From 3fc4e4e373f6f9d80cbc38fd2e2ed97fc6b6acfe Mon Sep 17 00:00:00 2001 From: Anthony Miyaguchi Date: Mon, 4 Apr 2022 17:16:54 -0700 Subject: [PATCH] Add docs for env_parse usage --- docs/examples/settings_with_custom_parsing.py | 17 +++++++++++++++ .../settings_with_custom_parsing_validator.py | 17 +++++++++++++++ docs/usage/settings.md | 21 ++++++++++++++++--- 3 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 docs/examples/settings_with_custom_parsing.py create mode 100644 docs/examples/settings_with_custom_parsing_validator.py diff --git a/docs/examples/settings_with_custom_parsing.py b/docs/examples/settings_with_custom_parsing.py new file mode 100644 index 00000000000..231b5801607 --- /dev/null +++ b/docs/examples/settings_with_custom_parsing.py @@ -0,0 +1,17 @@ +# output-json +import os +from typing import List + +from pydantic import BaseSettings, Field + + +def parse_list(s: str) -> List[int]: + return [int(x.strip()) for x in s.split(",")] + + +class Settings(BaseSettings): + numbers: List[int] = Field(env_parse=parse_list) + + +os.environ["numbers"] = "1,2,3" +print(Settings().dict()) diff --git a/docs/examples/settings_with_custom_parsing_validator.py b/docs/examples/settings_with_custom_parsing_validator.py new file mode 100644 index 00000000000..2c9d9406384 --- /dev/null +++ b/docs/examples/settings_with_custom_parsing_validator.py @@ -0,0 +1,17 @@ +# output-json +import os +from typing import List + +from pydantic import BaseSettings, Field, validator + + +class Settings(BaseSettings): + numbers: List[int] = Field(env_parse=str) + + @validator("numbers", pre=True) + def validate_numbers(cls, s): + return [int(x.strip()) for x in s.split(",")] + + +os.environ["numbers"] = "1,2,3" +print(Settings().dict()) diff --git a/docs/usage/settings.md b/docs/usage/settings.md index 6bb752a1ea3..1c053e63f4f 100644 --- a/docs/usage/settings.md +++ b/docs/usage/settings.md @@ -90,7 +90,7 @@ You could load a settings module thus: {!.tmp_examples/settings_nested_env.py!} ``` -`env_nested_delimiter` can be configured via the `Config` class as shown above, or via the +`env_nested_delimiter` can be configured via the `Config` class as shown above, or via the `_env_nested_delimiter` keyword argument on instantiation. JSON is only parsed in top-level fields, if you need to parse JSON in sub-models, you will need to implement @@ -99,6 +99,21 @@ validators on those models. Nested environment variables take precedence over the top-level environment variable JSON (e.g. in the example above, `SUB_MODEL__V2` trumps `SUB_MODEL`). +You may also populate a complex type by providing your own parsing function to +`env_parse` in the field extras. + +```py +{!.tmp_examples/settings_with_custom_parsing.py!} +``` + +You might choose to pass the environment string value through to pydantic and +transform in a validator instead. + +```py +{!.tmp_examples/settings_with_custom_parsing_validator.py!} +``` + + ## Dotenv (.env) support !!! note @@ -162,7 +177,7 @@ see [python-dotenv's documentation](https://saurabh-kumar.com/python-dotenv/#usa Placing secret values in files is a common pattern to provide sensitive configuration to an application. -A secret file follows the same principal as a dotenv file except it only contains a single value and the file name +A secret file follows the same principal as a dotenv file except it only contains a single value and the file name is used as the key. A secret file will look like the following: `/var/run/database_password`: @@ -215,7 +230,7 @@ class Settings(BaseSettings): secrets_dir = '/run/secrets' ``` !!! note - By default Docker uses `/run/secrets` as the target mount point. If you want to use a different location, change + By default Docker uses `/run/secrets` as the target mount point. If you want to use a different location, change `Config.secrets_dir` accordingly. Then, create your secret via the Docker CLI