コンテンツにスキップ

Settings Management

Pydantic Settingsは、環境変数やシークレットファイルから設定や構成クラスをロードするためのオプションのPydantic機能を提供します。

Warning

このドキュメントは、https://raw.githubusercontent.com/pydantic/pydantic-settings/main/docs/index.md にリンクされたドキュメントのコピーを翻訳しています。

Installation

インストールは次のように簡単です。

pip install pydantic-settings

Usage

BaseSettingsから継承するモデルを作成した場合、モデルイニシャライザは、キーワード引数として渡されていないフィールドの値を、環境から読み取って決定しようとします(一致する環境変数が設定されていない場合でも、デフォルト値が使用されます)。

これにより、次のことが容易になります。

  • 明確に定義され、型をヒントにしたアプリケーション構成クラスの作成
  • 環境変数から構成への変更を自動的な読み取り
  • 必要に応じて、イニシャライザの特定の設定を手動での上書き(ユニットテストなど)

次に例を示します。

from typing import Any, Callable, Set

from pydantic import (
    AliasChoices,
    AmqpDsn,
    BaseModel,
    Field,
    ImportString,
    PostgresDsn,
    RedisDsn,
)

from pydantic_settings import BaseSettings, SettingsConfigDict


class SubModel(BaseModel):
    foo: str = 'bar'
    apple: int = 1


class Settings(BaseSettings):
    auth_key: str = Field(validation_alias='my_auth_key')  # (1)!

    api_key: str = Field(alias='my_api_key')  # (2)!

    redis_dsn: RedisDsn = Field(
        'redis://user:pass@localhost:6379/1',
        validation_alias=AliasChoices('service_redis_dsn', 'redis_url'),  # (3)!
    )
    pg_dsn: PostgresDsn = 'postgres://user:pass@localhost:5432/foobar'
    amqp_dsn: AmqpDsn = 'amqp://user:pass@localhost:5672/'

    special_function: ImportString[Callable[[Any], Any]] = 'math.cos'  # (4)!

    # to override domains:
    # export my_prefix_domains='["foo.com", "bar.com"]'
    domains: Set[str] = set()

    # to override more_settings:
    # export my_prefix_more_settings='{"foo": "x", "apple": 1}'
    more_settings: SubModel = SubModel()

    model_config = SettingsConfigDict(env_prefix='my_prefix_')  # (5)!


print(Settings().model_dump())
"""
{
    'auth_key': 'xxx',
    'api_key': 'xxx',
    'redis_dsn': Url('redis://user:pass@localhost:6379/1'),
    'pg_dsn': MultiHostUrl('postgres://user:pass@localhost:5432/foobar'),
    'amqp_dsn': Url('amqp://user:pass@localhost:5672/'),
    'special_function': math.cos,
    'domains': set(),
    'more_settings': {'foo': 'bar', 'apple': 1},
}
"""
  1. 環境変数名はvalidation_aliasを使用してオーバーライドされます。この場合、環境変数my_auth_keyauth_keyの代わりに読み込まれます。詳細については、Fielddocumentationを参照してください。
  1. 環境変数名はaliasを使用してオーバーライドされます。この場合、環境変数my_api_keyが検証とシリアライゼーションの両方にapi_keyの代わりに使用されます。詳細については、Fielddocumentationを参照してください。
  1. AliasChoicesクラスでは、1つのフィールドに対して複数の環境変数名を持つことができます。最初に見つかった環境変数が使用されます。詳細については、AliasChoicesを確認してください。
  1. ImportStringクラスを使用すると、文字列からオブジェクトをインポートできます。この場合、環境変数special_functionが読み込まれ、関数math.cosがインポートされます。
  1. env_prefix構成設定では、すべての環境変数に接頭辞を設定できます。詳細については、環境変数名のドキュメントを参照してください。

Validation of default values

pydanicのBaseModelとは異なり、BaseSettingsフィールドのデフォルト値はデフォルトで検証されます。 この動作を無効にするには、model_configまたはField(validate_default=False)のフィールドレベルでvalidate_default=Falseを設定します。

from pydantic import Field

from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(validate_default=False)

    # default won't be validated
    foo: int = 'test'


print(Settings())
#> foo='test'


class Settings1(BaseSettings):
    # default won't be validated
    foo: int = Field('test', validate_default=False)


print(Settings1())
#> foo='test'

詳細については、Validation of default valuesを参照してください。

Environment variable names

デフォルトでは、環境変数名はフィールド名と同じです。

すべての環境変数のプレフィックスを変更するには、env_prefixconfig設定を設定するか、インスタンス化時に_env_prefixキーワード引数を使用します。

from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_prefix='my_prefix_')

    auth_key: str = 'xxx'  # will be read from `my_prefix_auth_key`

Note

デフォルトのenv_prefix''(空文字列)です。

1つのフィールドの環境変数名を変更する場合は、エイリアスを使用できます。

これには2つの方法があります。

  • Field(alias=...)を使用する(上記のapi_keyを参照)
  • Field(validation_alias=...)を使用します(上記のauth_keyを参照)

エイリアスの詳細については、Fieldaliases documentationを参照してください。

env_prefixはエイリアスを持つフィールドには適用されません。これは、環境変数名がフィールドエイリアスと同じであることを意味します:

from pydantic import Field

from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_prefix='my_prefix_')

    foo: str = Field('xxx', alias='FooAlias')  # (1)!
  1. env_prefix will be ignored and the value will be read from FooAlias environment variable.

Case-sensitivity

デフォルトでは、環境変数名の大文字と小文字は区別されません。

環境変数名の大文字と小文字を区別する場合は、case_sensitive構成設定を設定します。

from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(case_sensitive=True)

    redis_host: str = 'localhost'

case_sensitiveTrueの場合、環境変数名はフィールド名と一致する必要があります(オプションで接頭辞が必要)。したがって、この例ではredis_hostexport redis_hostを介してのみ変更できます。 環境変数にすべて大文字の名前を付ける場合は、attributeにもすべて大文字の名前を付ける必要があります。 Field(validation_alias=...)を使用して、環境変数に任意の名前を付けることができます。

大文字と小文字の区別は、インスタンス化時に_case_sensitiveキーワード引数を使用して設定することもできます。

ネストされたモデルの場合、case_sensitive設定はすべてのネストされたモデルに適用されます。

import os

from pydantic import BaseModel, ValidationError

from pydantic_settings import BaseSettings


class RedisSettings(BaseModel):
    host: str
    port: int


class Settings(BaseSettings, case_sensitive=True):
    redis: RedisSettings


os.environ['redis'] = '{"host": "localhost", "port": 6379}'
print(Settings().model_dump())
#> {'redis': {'host': 'localhost', 'port': 6379}}
os.environ['redis'] = '{"HOST": "localhost", "port": 6379}'  # (1)!
try:
    Settings()
except ValidationError as e:
    print(e)
    """
    1 validation error for Settings
    redis.host
      Field required [type=missing, input_value={'HOST': 'localhost', 'port': 6379}, input_type=dict]
        For further information visit https://errors.pydantic.dev/2/v/missing
    """
  1. 環境変数名がHOST(すべて大文字)であるため、hostフィールドが見つからないことに注意してください。

Note

Windowsでは、Pythonのosモジュールは常に環境変数を大文字小文字を区別しないものとして扱うので、case_sensitive設定には何の効果もありません。設定は常に大文字小文字を無視して更新されます。

Parsing environment variable values

デフォルトでは、環境変数は値が空の場合も含めて逐語的にパースされます。env_ignore_empty設定をTrueに設定することで、空の環境変数を無視することを選択できます。 これは、環境からの空の値ではなく、フィールドのデフォルト値を使用する場合に便利です。

ほとんどの単純なフィールド型(intfloatstrなど)では、環境変数の値はイニシャライザに(文字列として)直接渡された場合と同じようにパースされます。

listsetdict、サブモデルなどの複雑な型は、環境変数の値をJSONでエンコードされた文字列として扱うことによって、環境から生成されます。

ネストされた複合変数を設定するもう1つの方法は、env_nested_delimiter構成設定でモデルを構成し、ネストされたモジュールフィールドを指す名前の環境変数を使用することです。 これは単に、変数をネストされたモデルやディクテーションに展開するだけです。 ですから、変数FOO__BAR__BAZ=123を定義すると、FOO={'BAR':{'BAZ':123}}に変換されます。 同じ構造を持つ複数の変数がある場合、それらはマージされます。

Note

サブモデルはpydantic.BaseModelから継承する必要があります。そうしないと、pydantic-settingsがサブモデルを初期化し、サブモデルフィールドの値を個別に収集し、予期しない結果になる可能性があります。

たとえば、次の環境変数があるとします。

# your environment
export V0=0
export SUB_MODEL='{"v1": "json-1", "v2": "json-2"}'
export SUB_MODEL__V2=nested-2
export SUB_MODEL__V3=3
export SUB_MODEL__DEEP__V4=v4

次の設定モデルにロードすることができます。

from pydantic import BaseModel

from pydantic_settings import BaseSettings, SettingsConfigDict


class DeepSubModel(BaseModel):  # (1)!
    v4: str


class SubModel(BaseModel):  # (2)!
    v1: str
    v2: bytes
    v3: int
    deep: DeepSubModel


class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_nested_delimiter='__')

    v0: str
    sub_model: SubModel


print(Settings().model_dump())
"""
{
    'v0': '0',
    'sub_model': {'v1': 'json-1', 'v2': b'nested-2', 'v3': 3, 'deep': {'v4': 'v4'}},
}
"""
  1. サブモデルはpydantic.BaseModelから継承する必要があります。
  1. サブモデルはpydantic.BaseModelから継承する必要があります。

env_nested_delimiterは、上記のようにmodel_configを介して、またはインスタンス化時に_env_nested_delimiterキーワード引数を介して設定できます。

ネストされた環境変数は、トップレベルの環境変数JSONよりも優先されます(例えば、上の例ではSUB_MODEL__V2SUB_MODELより優先されます)。

また、独自のソースクラスを指定して複合型を生成することもできます。

import json
import os
from typing import Any, List, Tuple, Type

from pydantic.fields import FieldInfo

from pydantic_settings import (
    BaseSettings,
    EnvSettingsSource,
    PydanticBaseSettingsSource,
)


class MyCustomSource(EnvSettingsSource):
    def prepare_field_value(
        self, field_name: str, field: FieldInfo, value: Any, value_is_complex: bool
    ) -> Any:
        if field_name == 'numbers':
            return [int(x) for x in value.split(',')]
        return json.loads(value)


class Settings(BaseSettings):
    numbers: List[int]

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: Type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> Tuple[PydanticBaseSettingsSource, ...]:
        return (MyCustomSource(settings_cls),)


os.environ['numbers'] = '1,2,3'
print(Settings().model_dump())
#> {'numbers': [1, 2, 3]}

Dotenv (.env) support

.envファイル(通常は.env)は、プラットフォームに依存しない方法で環境変数を簡単に使用できるようにする一般的なパターンです。

.envファイルは、すべての環境変数と同じ一般原則に従い、次のようになります。

.env
# ignore comment
ENVIRONMENT="production"
REDIS_ADDRESS=localhost:6379
MEANING_OF_LIFE=42
MY_VAR='Hello world'

.envファイルに変数を入れると、pydanticは以下の2つの方法でロードをサポートします。

  1. BaseSettingsクラスのmodel_configenv_file(およびOSのデフォルトエンコーディングが不要な場合はenv_file_encoding)を設定します。
    from pydantic_settings import BaseSettings, SettingsConfigDict
    
    
    class Settings(BaseSettings):
        model_config = SettingsConfigDict(env_file='.env', env_file_encoding='utf-8')
    
  1. _env_fileキーワード引数(および必要に応じて_env_file_encoding)を使用してBaseSettings派生クラスをインスタンス化します。
    from pydantic_settings import BaseSettings, SettingsConfigDict
    
    
    class Settings(BaseSettings):
        model_config = SettingsConfigDict(env_file='.env', env_file_encoding='utf-8')
    
    
    settings = Settings(_env_file='prod.env', _env_file_encoding='utf-8')
    

どちらの場合も、渡される引き数の値は任意の有効なパスまたはファイル名(絶対パスまたは現在の作業ディレクトリからの相対パス)にすることができます。そこから、pydanticは変数をロードして検証することで、すべてを処理します。

Note

env_fileにファイル名が指定されている場合、Pydanticは現在の作業ディレクトリのみをチェックし、.envファイルの親ディレクトリはチェックしません。

.envファイルを使用している場合でも、pydanticは環境変数とdotenvファイルを読み込みます。環境変数は常にdotenvファイルからロードされた値よりも優先されます

インスタンス化(方法2)で_env_fileキーワード引数を介してファイルパスを渡すと、model_configクラスに設定された値(もしあれば)が上書きされます。上記のスニペットが一緒に使用された場合、prod.envがロードされ、.envは無視されます。

複数のdotenvファイルをロードする必要がある場合は、複数のファイルパスをタプルまたはリストとして渡すことができます。ファイルは順番にロードされ、各ファイルが前のファイルを上書きします。

from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(
        # `.env.prod` takes priority over `.env`
        env_file=('.env', '.env.prod')
    )

settings=Settings(_env_file=None)のように、キーワード引数overrideを使用して、インスタンス化キーワード引数としてNoneを渡すことで、(model_configクラスにファイルが設定されていても)ファイルをまったくロードしないようにPydanticに指示することもできます。

python-dotenvはファイルをパースするために使用されるので、exportのようなbashのようなセマンティクスを使用することができます。(お使いのOSや環境によっては)dotenvファイルをsourceでも使用できる場合があります。詳細については、python-dotenv's documentationを参照してください。

Pydanticの設定では、dotenvファイルの場合にextraconfigを考慮します。これは、model_configextra=forbid(default)を設定し、dotenvファイルに設定モデルで定義されていないフィールドのエントリが含まれている場合、設定の構築でValidationErrorが発生することを意味します。

pydantic 1.x BaseSettingsとの互換性のために、extra=ignoreを使用してください。

from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_file='.env', extra='ignore')

Note

Pydantic設定は、モデルのenv_prefixに関係なく、dotenvファイルからすべての値をロードしてモデルに渡します。 したがって、dotenvファイルに追加の値を指定すると、それらがenv_prefixで始まるかどうかにかかわらず、ValidationErrorが発生します。

Command Line Support

Pydantic設定は統合されたCLIサポートを提供し、Pydanticモデルを使用してCLIアプリケーションを簡単にすばやく定義できるようにします。Pydantic設定CLIの主なユースケースは次の2つです。

  1. CLIを使用してPydanticモデルのフィールドを上書きする場合。
  2. Pydanticモデルを使用してCLIを定義する場合。

デフォルトでは、エクスペリエンスはユースケース#1に合わせて調整され、parsing environment variablesで確立された基礎の上に構築されます。ユースケースが主に#2に該当する場合は、enforcing required arguments at the CLIを有効にする必要があります。

The Basics

最初に、parsing environment variablesで示した例を、Pydantic設定CLIを使用してもう一度見てみましょう。

import sys

from pydantic import BaseModel

from pydantic_settings import BaseSettings, SettingsConfigDict


class DeepSubModel(BaseModel):
    v4: str


class SubModel(BaseModel):
    v1: str
    v2: bytes
    v3: int
    deep: DeepSubModel


class Settings(BaseSettings):
    model_config = SettingsConfigDict(cli_parse_args=True)

    v0: str
    sub_model: SubModel


sys.argv = [
    'example.py',
    '--v0=0',
    '--sub_model={"v1": "json-1", "v2": "json-2"}',
    '--sub_model.v2=nested-2',
    '--sub_model.v3=3',
    '--sub_model.deep.v4=v4',
]

print(Settings().model_dump())
"""
{
    'v0': '0',
    'sub_model': {'v1': 'json-1', 'v2': b'nested-2', 'v3': 3, 'deep': {'v4': 'v4'}},
}
"""

CLIでのパースを有効にするには、単にcli_parse_argsフラグを有効な値に設定します。このフラグはargparseで定義されているのと同様の意味を保持します。あるいは、インスタンス化時にパースする引数を直接指定することもできます。

from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    this_foo: str


print(Settings(_cli_parse_args=['--this_foo', 'is such a foo']).model_dump())
#> {'this_foo': 'is such a foo'}

Note that a CLI settings source is the topmost source by default unless its priority value is customised: CLIの設定ソースは、priority value is customisedでない限り、デフォルトでthe topmost sourceであることに注意してください。

import os
import sys
from typing import Tuple, Type

from pydantic_settings import (
    BaseSettings,
    CliSettingsSource,
    PydanticBaseSettingsSource,
)


class Settings(BaseSettings):
    my_foo: str

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: Type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> Tuple[PydanticBaseSettingsSource, ...]:
        return env_settings, CliSettingsSource(settings_cls, cli_parse_args=True)


os.environ['MY_FOO'] = 'from environment'

sys.argv = ['example.py', '--my_foo=from cli']

print(Settings().model_dump())
#> {'my_foo': 'from environment'}

Lists

CLI argument parsing of lists supports intermixing of any of the below three styles: リストのCLI引数のパースでは、次の3つのスタイルの混在がサポートされています。

  • JSON style --field='[1,2]'
  • Argparse style --field 1 --field 2
  • Lazy style --field=1,2
import sys
from typing import List

from pydantic_settings import BaseSettings


class Settings(BaseSettings, cli_parse_args=True):
    my_list: List[int]


sys.argv = ['example.py', '--my_list', '[1,2]']
print(Settings().model_dump())
#> {'my_list': [1, 2]}

sys.argv = ['example.py', '--my_list', '1', '--my_list', '2']
print(Settings().model_dump())
#> {'my_list': [1, 2]}

sys.argv = ['example.py', '--my_list', '1,2']
print(Settings().model_dump())
#> {'my_list': [1, 2]}

Dictionaries

CLI argument parsing of dictionaries supports intermixing of any of the below two styles: ディクショナリのCLI引数のパースでは、次の2つのスタイルの混在がサポートされています。

  • JSON style --field='{"k1": 1, "k2": 2}'
  • Environment variable style --field k1=1 --field k2=2

これらは、次のようにリスト形式と組み合わせて使用することもできます。

  • --field k1=1,k2=2 --field k3=3 --field '{"k4": 4}' etc.
import sys
from typing import Dict

from pydantic_settings import BaseSettings


class Settings(BaseSettings, cli_parse_args=True):
    my_dict: Dict[str, int]


sys.argv = ['example.py', '--my_dict', '{"k1":1,"k2":2}']
print(Settings().model_dump())
#> {'my_dict': {'k1': 1, 'k2': 2}}

sys.argv = ['example.py', '--my_dict', 'k1=1', '--my_dict', 'k2=2']
print(Settings().model_dump())
#> {'my_dict': {'k1': 1, 'k2': 2}}

Literals and Enums

CLI argument parsing of literals and enums are converted into CLI choices. リテラルおよび列挙型のCLI引数のパースは、CLIでの選択項目に変換されます。

import sys
from enum import IntEnum
from typing import Literal

from pydantic_settings import BaseSettings


class Fruit(IntEnum):
    pear = 0
    kiwi = 1
    lime = 2


class Settings(BaseSettings, cli_parse_args=True):
    fruit: Fruit
    pet: Literal['dog', 'cat', 'bird']


sys.argv = ['example.py', '--fruit', 'lime', '--pet', 'cat']
print(Settings().model_dump())
#> {'fruit': <Fruit.lime: 2>, 'pet': 'cat'}

Aliases

Pydanticフィールドエイリアスは、CLI引数エイリアスとして追加されます。長さ1のエイリアスは、短いオプションに変換されます。

import sys

from pydantic import AliasChoices, AliasPath, Field

from pydantic_settings import BaseSettings


class User(BaseSettings, cli_parse_args=True):
    first_name: str = Field(
        validation_alias=AliasChoices('f', 'fname', AliasPath('name', 0))
    )
    last_name: str = Field(
        validation_alias=AliasChoices('l', 'lname', AliasPath('name', 1))
    )


sys.argv = ['example.py', '--fname', 'John', '--lname', 'Doe']
print(User().model_dump())
#> {'first_name': 'John', 'last_name': 'Doe'}

sys.argv = ['example.py', '-f', 'John', '-l', 'Doe']
print(User().model_dump())
#> {'first_name': 'John', 'last_name': 'Doe'}

sys.argv = ['example.py', '--name', 'John,Doe']
print(User().model_dump())
#> {'first_name': 'John', 'last_name': 'Doe'}

sys.argv = ['example.py', '--name', 'John', '--lname', 'Doe']
print(User().model_dump())
#> {'first_name': 'John', 'last_name': 'Doe'}

Subcommands and Positional Arguments

サブコマンドと位置引数は、CliSubCommandおよびCliPositionalArgアノテーションを使用して表現されます。 これらの注釈は必須フィールド(つまり、デフォルト値のないフィールド)にのみ適用できます。 さらに、サブコマンドはpydanicBaseModelまたはpydanic.dataclassesdataclassから派生した有効な型でなければなりません。

Note

CLI設定サブコマンドは、モデルごとに1つのサブパーサーに制限されています。つまり、モデルのすべてのサブコマンドは1つのサブパーサーにグループ化されます。各サブパーサーが独自のサブコマンドセットを持つ複数のサブパーサーは許可されません。サブパーサーの詳細については、argparse subcommandsを参照してください。

Note

CliSubCommandCliPositionalArgは常に大文字と小文字が区別され、エイリアスをサポートしていません。

import sys

from pydantic import BaseModel, Field
from pydantic.dataclasses import dataclass

from pydantic_settings import (
    BaseSettings,
    CliPositionalArg,
    CliSubCommand,
)


@dataclass
class FooPlugin:
    """git-plugins-foo - Extra deep foo plugin command"""

    x_feature: bool = Field(default=False, description='Enable "X" feature')


@dataclass
class BarPlugin:
    """git-plugins-bar - Extra deep bar plugin command"""

    y_feature: bool = Field(default=False, description='Enable "Y" feature')


@dataclass
class Plugins:
    """git-plugins - Fake plugins for GIT"""

    foo: CliSubCommand[FooPlugin] = Field(description='Foo is fake plugin')

    bar: CliSubCommand[BarPlugin] = Field(description='Bar is fake plugin')


class Clone(BaseModel):
    """git-clone - Clone a repository into a new directory"""

    repository: CliPositionalArg[str] = Field(description='The repo ...')

    directory: CliPositionalArg[str] = Field(description='The dir ...')

    local: bool = Field(default=False, description='When the repo ...')


class Git(BaseSettings, cli_parse_args=True, cli_prog_name='git'):
    """git - The stupid content tracker"""

    clone: CliSubCommand[Clone] = Field(description='Clone a repo ...')

    plugins: CliSubCommand[Plugins] = Field(description='Fake GIT plugins')


try:
    sys.argv = ['example.py', '--help']
    Git()
except SystemExit as e:
    print(e)
    #> 0
"""
usage: git [-h] {clone,plugins} ...

git - The stupid content tracker

options:
  -h, --help       show this help message and exit

subcommands:
  {clone,plugins}
    clone          Clone a repo ...
    plugins        Fake GIT plugins
"""


try:
    sys.argv = ['example.py', 'clone', '--help']
    Git()
except SystemExit as e:
    print(e)
    #> 0
"""
usage: git clone [-h] [--local bool] [--shared bool] REPOSITORY DIRECTORY

git-clone - Clone a repository into a new directory

positional arguments:
  REPOSITORY    The repo ...
  DIRECTORY     The dir ...

options:
  -h, --help    show this help message and exit
  --local bool  When the repo ... (default: False)
"""


try:
    sys.argv = ['example.py', 'plugins', 'bar', '--help']
    Git()
except SystemExit as e:
    print(e)
    #> 0
"""
usage: git plugins bar [-h] [--my_feature bool]

git-plugins-bar - Extra deep bar plugin command

options:
  -h, --help        show this help message and exit
  --y_feature bool  Enable "Y" feature (default: False)
"""

Customizing the CLI Experience

次のフラグを使用して、必要に応じてCLIエクスペリエンスをカスタマイズできます。

Change the Displayed Program Name

cli_prog_nameを設定して、ヘルプテキストの使用方法に表示されるデフォルトのプログラム名を変更します。デフォルトでは、argparseと同様に、現在実行中のプログラムの名前をsys.argv[0]から取得します。

import sys

from pydantic_settings import BaseSettings


class Settings(BaseSettings, cli_parse_args=True, cli_prog_name='appdantic'):
    pass


try:
    sys.argv = ['example.py', '--help']
    Settings()
except SystemExit as e:
    print(e)
    #> 0
"""
usage: appdantic [-h]

options:
  -h, --help  show this help message and exit
"""

Change Whether CLI Should Exit on Error

cli_exit_on_errorを使用して、CLI内部パーサーがエラー時に終了するか、SettingsError例外を発生させるかを変更します。デフォルトでは、CLI内部パーサーはエラー時に終了します。

import sys

from pydantic_settings import BaseSettings, SettingsError


class Settings(BaseSettings, cli_parse_args=True, cli_exit_on_error=False): ...


try:
    sys.argv = ['example.py', '--bad-arg']
    Settings()
except SettingsError as e:
    print(e)
    #> error parsing CLI: unrecognized arguments: --bad-arg

Enforce Required Arguments at CLI

Pydantic設定は、モデルをインスタンス化するときにさまざまなソースから値を取得するように設計されている。 つまり、必須フィールドは、単一のソース(CLIなど)からは厳密に必須ではありません。 代わりに重要なのは、ソースの1つが必要な値を提供することだけです。

しかし、Pydanticモデルを使用してCLIを定義するユースケース#2では、必須フィールドをCLIで厳密に必須にする必要があります。この動作を有効にするには、cli_enforce_requiredを使用します。

import os
import sys

from pydantic import Field

from pydantic_settings import BaseSettings, SettingsError


class Settings(
    BaseSettings,
    cli_parse_args=True,
    cli_enforce_required=True,
    cli_exit_on_error=False,
):
    my_required_field: str = Field(description='a top level required field')


os.environ['MY_REQUIRED_FIELD'] = 'hello from environment'

try:
    sys.argv = ['example.py']
    Settings()
except SettingsError as e:
    print(e)
    #> error parsing CLI: the following arguments are required: --my_required_field

Change the None Type Parse String

解析されるCLI文字列値("null"、"void"、"None"など)をNoneに変更するには、cli_parse_none_strを設定します。デフォルトでは、設定されている場合はenv_parse_none_str値が使用されます。設定されていない場合は、cli_avoid_jsonFalseの場合はデフォルトで"null"になり、cli_avoid_jsonTrueの場合はデフォルトで"None"になります。

import sys
from typing import Optional

from pydantic import Field

from pydantic_settings import BaseSettings


class Settings(BaseSettings, cli_parse_args=True, cli_parse_none_str='void'):
    v1: Optional[int] = Field(description='the top level v0 option')


sys.argv = ['example.py', '--v1', 'void']
print(Settings().model_dump())
#> {'v1': None}

Hide None Type Values

cli_hide_none_typeを有効にして、CLIヘルプテキストからNone値を非表示にします。

import sys
from typing import Optional

from pydantic import Field

from pydantic_settings import BaseSettings


class Settings(BaseSettings, cli_parse_args=True, cli_hide_none_type=True):
    v0: Optional[str] = Field(description='the top level v0 option')


try:
    sys.argv = ['example.py', '--help']
    Settings()
except SystemExit as e:
    print(e)
    #> 0
"""
usage: example.py [-h] [--v0 str]

options:
  -h, --help  show this help message and exit
  --v0 str    the top level v0 option (required)
"""

Avoid Adding JSON CLI Options

cli_avoid_jsonを有効にして、CLIでJSON文字列になる複雑なフィールドを追加しないようにします。

import sys

from pydantic import BaseModel, Field

from pydantic_settings import BaseSettings


class SubModel(BaseModel):
    v1: int = Field(description='the sub model v1 option')


class Settings(BaseSettings, cli_parse_args=True, cli_avoid_json=True):
    sub_model: SubModel = Field(
        description='The help summary for SubModel related options'
    )


try:
    sys.argv = ['example.py', '--help']
    Settings()
except SystemExit as e:
    print(e)
    #> 0
"""
usage: example.py [-h] [--sub_model.v1 int]

options:
  -h, --help          show this help message and exit

sub_model options:
  The help summary for SubModel related options

  --sub_model.v1 int  the sub model v1 option (required)
"""

Use Class Docstring for Group Help Text

デフォルトでは、ネストされたモデルのグループヘルプテキストを設定すると、フィールドの説明から取得されます。 代わりに、クラスdocstringからプルするようにCLI設定を構成することもできます。

Note

フィールドがネストされたモデルの結合である場合、cli_use_class_docs_for_groupsTrueに設定されていても、グループのヘルプテキストは常にフィールドの説明から取得されます。

import sys

from pydantic import BaseModel, Field

from pydantic_settings import BaseSettings


class SubModel(BaseModel):
    """The help text from the class docstring."""

    v1: int = Field(description='the sub model v1 option')


class Settings(BaseSettings, cli_parse_args=True, cli_use_class_docs_for_groups=True):
    """My application help text."""

    sub_model: SubModel = Field(description='The help text from the field description')


try:
    sys.argv = ['example.py', '--help']
    Settings()
except SystemExit as e:
    print(e)
    #> 0
"""
usage: example.py [-h] [--sub_model JSON] [--sub_model.v1 int]

My application help text.

options:
  -h, --help          show this help message and exit

sub_model options:
  The help text from the class docstring.

  --sub_model JSON    set sub_model from JSON string
  --sub_model.v1 int  the sub model v1 option (required)
"""

Integrating with Existing Parsers

CLI設定ソースは、デフォルトのCLI設定ソースをroot_parserオブジェクトを指定するユーザ定義の設定ソースで上書きすることで、既存のパーサと統合できます。

import sys
from argparse import ArgumentParser

from pydantic_settings import BaseSettings, CliSettingsSource

parser = ArgumentParser()
parser.add_argument('--food', choices=['pear', 'kiwi', 'lime'])


class Settings(BaseSettings):
    name: str = 'Bob'


# Set existing `parser` as the `root_parser` object for the user defined settings source
cli_settings = CliSettingsSource(Settings, root_parser=parser)

# Parse and load CLI settings from the command line into the settings source.
sys.argv = ['example.py', '--food', 'kiwi', '--name', 'waldo']
print(Settings(_cli_settings_source=cli_settings(args=True)).model_dump())
#> {'name': 'waldo'}

# Load CLI settings from pre-parsed arguments. i.e., the parsing occurs elsewhere and we
# just need to load the pre-parsed args into the settings source.
parsed_args = parser.parse_args(['--food', 'kiwi', '--name', 'ralph'])
print(Settings(_cli_settings_source=cli_settings(parsed_args=parsed_args)).model_dump())
#> {'name': 'ralph'}

CliSettingsSourceは、パーサメソッドを使用してsettings_clsフィールドをコマンドライン引数として追加することにより、root_parserオブジェクトと接続します。 CliSettingsSource内部パーサー表現はargparseライブラリに基づいているので、対応するargparseと同じ属性をサポートするパーサーメソッドが必要です。 カスタマイズできる使用可能なパーサーメソッドと、対応するargparse(デフォルト)を次に示します。

  • parse_args_method - (argparse.ArgumentParser.parse_args)
  • add_argument_method - (argparse.ArgumentParser.add_argument)
  • add_argument_group_method - (argparse.ArgumentParser.add_argument_group)
  • add_parser_method - (argparse._SubParsersAction.add_parser)
  • add_subparsers_method - (argparse.ArgumentParser.add_subparsers)
  • formatter_class - (argparse.HelpFormatter)

非argparseパーサの場合、サポートされていなければパーサメソッドをNoneに設定することができます。CLI設定では、パーサメソッドが必要であるがNoneに設定されている場合にのみ、ルートパーサに接続するときにエラーが発生します。

Secrets

ファイルに秘密の値を設定することは、アプリケーションに機密性の高い設定を提供するための一般的なパターンです。

シークレット・ファイルは、1つの値のみを含み、ファイル名がキーとして使用されることを除いて、dotenvファイルと同じプリンシパルに従います。シークレット・ファイルは次のようになります。

/var/run/database_password
super_secret_database_password

シークレットファイルを取得すると、pydanticは次の2つの方法でそのファイルのロードをサポートします。

  1. BaseSettingsクラスのmodel_configsecrets_dirを、シークレットファイルが保存されているディレクトリに設定します。
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(secrets_dir='/var/run')

    database_password: str
  1. _secrets_dirキーワード引数を使用してBaseSettings派生クラスのインスタンス化:
    settings = Settings(_secrets_dir='/var/run')
    

どちらの場合も、渡される引数の値は、任意の有効なディレクトリ(絶対ディレクトリまたは現在の作業ディレクトリに対する相対ディレクトリ)にすることができます。存在しないディレクトリは警告を生成するだけであることに注意してください。 そこから、pydanticは変数をロードして検証することで、すべてを処理します。

secretsディレクトリを使用する場合でも、pydanticはdotenvファイルまたは環境から環境変数を読み込みます。dotenvファイルと環境変数は、secretsディレクトリからロードされた値よりも常に優先されます

インスタンス化(メソッド2)で_secrets_dirキーワード引数を介してファイルパスを渡すと、model_configクラスに設定された値(もしあれば)が上書きされます。

Use Case: Docker Secrets

Docker Secretsは、Dockerコンテナで実行されているアプリケーションに機密性の高い設定を提供するために使用できる。 これらのシークレットをpydanticアプリケーションで使用するプロセスは簡単です。Dockerでのシークレットの作成、管理、使用に関する詳細は、公式のDocker documentationを参照してください。

まず、secretsディレクトリを指定するSettingsConfigDictSettingsクラスを定義します。

from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(secrets_dir='/run/secrets')

    my_secret_data: str

Note

デフォルトでは、Dockerは/run/secretsをターゲットマウントポイントとして使用します。別の場所を使用したい場合は、それに応じてConfig.secrets_dirを変更してください。

次に、Docker CLIを使用してシークレットを作成します。

printf "This is a secret" | docker secret create my_secret_data -

最後に、Dockerコンテナ内でアプリケーションを実行し、新しく作成したシークレットを指定します。

docker service create --name pydantic-with-secrets --secret my_secret_data pydantic-app:latest

Azure Key Vault

次の2つのパラメータを設定する必要があります。

  • url:例えばhttps://my-resource.vault.azure.net/です。
  • credential:DefaultAzureCredentialを使用する場合は、ローカルでaz loginを実行してIDクレデンシャルを取得できます。シークレットにアクセスできるように、IDにロールが割り当てられている必要があります(推奨されるのはKey Vault Secrets Userです)。

フィールド名には、キー・ヴォールト・シークレット名と同じ命名規則を使用する必要があります。たとえば、シークレットの名前がSqlServerPasswordの場合、フィールド名は同じである必要があります。別名も使用できます。

Key Vaultでは、ネストされたモデルは--セパレータでサポートされます。たとえば、SqlServer--Passwordのようになります。

Key Vault配列(例えばMySecret--0MySecret--1)はサポートされていません。

import os
from typing import Tuple, Type

from azure.identity import DefaultAzureCredential
from pydantic import BaseModel

from pydantic_settings import (
    AzureKeyVaultSettingsSource,
    BaseSettings,
    PydanticBaseSettingsSource,
)


class SubModel(BaseModel):
    a: str


class AzureKeyVaultSettings(BaseSettings):
    foo: str
    bar: int
    sub: SubModel

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: Type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> Tuple[PydanticBaseSettingsSource, ...]:
        az_key_vault_settings = AzureKeyVaultSettingsSource(
            settings_cls,
            os.environ['AZURE_KEY_VAULT_URL'],
            DefaultAzureCredential(),
        )
        return (
            init_settings,
            env_settings,
            dotenv_settings,
            file_secret_settings,
            az_key_vault_settings,
        )

Other settings source

その他の設定ソースは、一般的な設定ファイルに使用できます。

  • json_fileおよびjson_file_encoding引数を使用したJsonConfigSettingsSource
  • (オプション)pyproject_toml_depthおよび(オプション)pyproject_toml_table_header引数を使用したPyprojectTomlConfigSettingsSource
  • toml_file引数を使用したTomlConfigSettingsSource
  • yaml_fileおよびyaml_file_encoding引数を使用したYamlConfigSettingsSource

パスのリストを指定して、複数のファイルを指定することもできます。

toml_file = ['config.default.toml', 'config.custom.toml']

これらを使用するには、ここで説明したのと同じメカニズムを使用できます。

from typing import Tuple, Type

from pydantic import BaseModel

from pydantic_settings import (
    BaseSettings,
    PydanticBaseSettingsSource,
    SettingsConfigDict,
    TomlConfigSettingsSource,
)


class Nested(BaseModel):
    nested_field: str


class Settings(BaseSettings):
    foobar: str
    nested: Nested
    model_config = SettingsConfigDict(toml_file='config.toml')

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: Type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> Tuple[PydanticBaseSettingsSource, ...]:
        return (TomlConfigSettingsSource(settings_cls),)

これにより、ワーキングディレクトリにある次の"config.toml"ファイルを読み込むことができます。

foobar = "Hello"
[nested]
nested_field = "world!"

pyproject.toml

"pyproject.toml"は、Pythonプロジェクトで構成値を提供するための標準化されたファイルです。PEP 518では、任意のツール構成を提供するために使用できる[tool]テーブルが定義されています。 [tool]テーブルを使用することをお勧めしますが、PyprojectTomlConfigSettingsSourceは"pyproject.toml"ファイル内の任意の場所から変数をロードするために使用できます。

これはSettingsConfigDict(pyproject_toml_table_header=tuple[str, .])を提供することで制御されます。ここで、値はヘッダー部分のタプルです。 デフォルトではpyproject_toml_table_header=('tool','pydantic-settings')で、[tool.pydantic-settings]テーブルから変数をロードします。

from typing import Tuple, Type

from pydantic_settings import (
    BaseSettings,
    PydanticBaseSettingsSource,
    PyprojectTomlConfigSettingsSource,
    SettingsConfigDict,
)


class Settings(BaseSettings):
    """Example loading values from the table used by default."""

    field: str

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: Type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> Tuple[PydanticBaseSettingsSource, ...]:
        return (PyprojectTomlConfigSettingsSource(settings_cls),)


class SomeTableSettings(Settings):
    """Example loading values from a user defined table."""

    model_config = SettingsConfigDict(
        pyproject_toml_table_header=('tool', 'some-table')
    )


class RootSettings(Settings):
    """Example loading values from the root of a pyproject.toml file."""

    model_config = SettingsConfigDict(extra='ignore', pyproject_toml_table_header=())

これは、作業ディレクトリにある以下の"pyproject.toml"ファイルを読み込むことができ、結果はSettings(field='default-table')SomeTableSettings(field='some-table')RootSettings(field='root')になります。

field = "root"

[tool.pydantic-settings]
field = "default-table"

[tool.some-table]
field = "some-table"

デフォルトでは、PyprojectTomlConfigSettingsSourceは現在の作業ディレクトリ内の"pyproject.toml"のみを検索します。 ただし、この動作を変更するには2つのオプションがあります。

  • SettingsConfigDict(pyproject_toml_depth=<int>)を提供して、"pyproject.toml"が現在の作業ディレクトリに見つからない場合に、ディレクトリツリー内のディレクトリ数upをチェックすることができます。デフォルトでは、親ディレクトリはチェックされません。
  • ソースがインスタンス化されるときに、明示的なファイルパスをソースに提供することができます(例:PyprojectTomlConfigSettingsSource(settings_cls, Path('~/.config').resolve()/'pyproject.toml'))。ファイルパスがこのように提供される場合、絶対パスとして扱われます(他の場所はチェックされません)。
from pathlib import Path
from typing import Tuple, Type

from pydantic_settings import (
    BaseSettings,
    PydanticBaseSettingsSource,
    PyprojectTomlConfigSettingsSource,
    SettingsConfigDict,
)


class DiscoverSettings(BaseSettings):
    """Example of discovering a pyproject.toml in parent directories in not in `Path.cwd()`."""

    model_config = SettingsConfigDict(pyproject_toml_depth=2)

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: Type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> Tuple[PydanticBaseSettingsSource, ...]:
        return (PyprojectTomlConfigSettingsSource(settings_cls),)


class ExplicitFilePathSettings(BaseSettings):
    """Example of explicitly providing the path to the file to load."""

    field: str

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: Type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> Tuple[PydanticBaseSettingsSource, ...]:
        return (
            PyprojectTomlConfigSettingsSource(
                settings_cls, Path('~/.config').resolve() / 'pyproject.toml'
            ),
        )

Field value priority

同じ"設定"フィールドに複数の方法で値が指定されている場合、選択された値は次のように決定されます(優先順位の高い順に)。

  1. cli_parse_argsが有効な場合、CLIに渡される引数
  2. Settingsクラスのイニシャライザに渡される引数
  3. 環境変数。例えば、上で説明したmy_prefix_special_function
  4. dotenv(.env)ファイルからロードされた変数
  5. secretsディレクトリからロードされた変数
  6. Settingsモデルのデフォルトのフィールド値

Customise settings sources

デフォルトの優先順位があなたのニーズに合わない場合は、Settingssettings_customise_sourcesメソッドをオーバーライドすることで変更できます。

settings_customise_sourcesは引数として4つのcallableを取り、任意の数のcallableをタプルとして返します。 次に、これらの呼び出し可能オブジェクトが呼び出されて、settingsクラスのフィールドへの入力が作成されます。

各呼び出し可能オブジェクトは、設定クラスのインスタンスを唯一の引数として取り、dictを返します。

Changing Priority

返される呼び出し可能オブジェクトの順序によって、入力の優先順位が決まります。最初の項目が最も高い優先順位になります。

from typing import Tuple, Type

from pydantic import PostgresDsn

from pydantic_settings import BaseSettings, PydanticBaseSettingsSource


class Settings(BaseSettings):
    database_dsn: PostgresDsn

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: Type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> Tuple[PydanticBaseSettingsSource, ...]:
        return env_settings, init_settings, file_secret_settings


print(Settings(database_dsn='postgres://postgres@localhost:5432/kwargs_db'))
#> database_dsn=MultiHostUrl('postgres://postgres@localhost:5432/kwargs_db')

env_settingsinit_settingsを反転することで、環境変数が__init__kwargsよりも優先されるようになりました。

Adding sources

すでに説明したように、pydanticには複数の設定ソースが組み込まれています。ただし、独自のカスタムソースを追加する必要がある場合もあります。settings_customise_sourcesを使用すると、これを非常に簡単に行うことができます。

import json
from pathlib import Path
from typing import Any, Dict, Tuple, Type

from pydantic.fields import FieldInfo

from pydantic_settings import (
    BaseSettings,
    PydanticBaseSettingsSource,
    SettingsConfigDict,
)


class JsonConfigSettingsSource(PydanticBaseSettingsSource):
    """
    A simple settings source class that loads variables from a JSON file
    at the project's root.

    Here we happen to choose to use the `env_file_encoding` from Config
    when reading `config.json`
    """

    def get_field_value(
        self, field: FieldInfo, field_name: str
    ) -> Tuple[Any, str, bool]:
        encoding = self.config.get('env_file_encoding')
        file_content_json = json.loads(
            Path('tests/example_test_config.json').read_text(encoding)
        )
        field_value = file_content_json.get(field_name)
        return field_value, field_name, False

    def prepare_field_value(
        self, field_name: str, field: FieldInfo, value: Any, value_is_complex: bool
    ) -> Any:
        return value

    def __call__(self) -> Dict[str, Any]:
        d: Dict[str, Any] = {}

        for field_name, field in self.settings_cls.model_fields.items():
            field_value, field_key, value_is_complex = self.get_field_value(
                field, field_name
            )
            field_value = self.prepare_field_value(
                field_name, field, field_value, value_is_complex
            )
            if field_value is not None:
                d[field_key] = field_value

        return d


class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_file_encoding='utf-8')

    foobar: str

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: Type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> Tuple[PydanticBaseSettingsSource, ...]:
        return (
            init_settings,
            JsonConfigSettingsSource(settings_cls),
            env_settings,
            file_secret_settings,
        )


print(Settings())
#> foobar='test'

Accessing the result of previous sources

設定の各ソースは、前の設定の出力にアクセスできます。

from typing import Any, Dict, Tuple

from pydantic.fields import FieldInfo

from pydantic_settings import PydanticBaseSettingsSource


class MyCustomSource(PydanticBaseSettingsSource):
    def get_field_value(
        self, field: FieldInfo, field_name: str
    ) -> Tuple[Any, str, bool]: ...

    def __call__(self) -> Dict[str, Any]:
        # Retrieve the aggregated settings from previous sources
        current_state = self.current_state
        current_state.get('some_setting')

        # Retrieve settings from all sources individually
        # self.settings_sources_data["SettingsSourceName"]: Dict[str, Any]
        settings_sources_data = self.settings_sources_data
        settings_sources_data['SomeSettingsSource'].get('some_setting')

        # Your code here...

Removing sources

また、ソースを無効にすることもできます。

from typing import Tuple, Type

from pydantic import ValidationError

from pydantic_settings import BaseSettings, PydanticBaseSettingsSource


class Settings(BaseSettings):
    my_api_key: str

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: Type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> Tuple[PydanticBaseSettingsSource, ...]:
        # here we choose to ignore arguments from init_settings
        return env_settings, file_secret_settings


try:
    Settings(my_api_key='this is ignored')
except ValidationError as exc_info:
    print(exc_info)
    """
    1 validation error for Settings
    my_api_key
      Field required [type=missing, input_value={}, input_type=dict]
        For further information visit https://errors.pydantic.dev/2/v/missing
    """

In-place reloading

既存の設定をインプレイスで再ロードしたい場合は、__init__メソッドを使って行うことができます。

import os

from pydantic import Field

from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    foo: str = Field('foo')


mutable_settings = Settings()

print(mutable_settings.foo)
#> foo

os.environ['foo'] = 'bar'
print(mutable_settings.foo)
#> foo

mutable_settings.__init__()
print(mutable_settings.foo)
#> bar

os.environ.pop('foo')
mutable_settings.__init__()
print(mutable_settings.foo)
#> foo