Environment Variables¶
Dynaconf prioritizes environment variables over files as the best recommendation to keep your settings.
According to 12factorapp it is a good practice to keep your configurations based on environment.
In addition to that Dynaconf offers some approaches you may want to Optionally follow:
- Add a list of validators to
validators=[Validator()]
on your dynaconf settings instance and provide defaults and constraints. - Enable
load_dotenv
and provide a.env.example
or.env
file with the default variables. - Write your variables in a settings file in the format of your choice.
- Load your settings from vault or redis
Environment variables¶
You can override any setting key by exporting an environment variable prefixed by DYNACONF_
(or by the custom prefix)
Example¶
Info
When loading environment variables, dynaconf will parse the value using toml
language
so it will try to automatic convert to the proper data type.
export DYNACONF_NAME=Bruno # str: "Bruno"
export DYNACONF_NUM=42 # int: 42
export DYNACONF_AMOUNT=65.6 # float: 65.6
export DYNACONF_THING_ENABLED=false # bool: False
export DYNACONF_COLORS="['red', 'gren', 'blue']" # list: ['red', 'gren', 'blue']
export DYNACONF_PERSON="{name='Bruno', email='foo@bar.com'}" # dict: {"name": "Bruno", ...}
export DYNACONF_STRING_NUM="'76'" # str: "76"
export DYNACONF_PERSON__IS_ADMIN=true # bool: True (nested)
Warning
When exporting datastructures sych as dict
and list
you have to use one of:
export DYNACONF_TOML_DICT={key="value"}
export DYNACONF_TOML_LIST=["item"]
export DYNACONF_JSON_DICT='@json {"key": "value"}'
export DYNACONF_JSON_LIST='@json ["item"]'
dicts
and lists
from envvars.
with the above it is now possible to read the settings from your program.py
using.
from dynaconf import Dynaconf
settings = Dynaconf()
assert settings.NAME == "Bruno"
assert settings.num == 42
assert settings.amount == 65.6
assert settings['thing_enabled'] is False
assert 'red' in settings.get('colors')
assert settings.person.email == "foo@bar.com"
assert settings.person.is_admin is True
assert settings.STRING_NUM == "76"
Tip
Dynaconf has multiple valid ways to access settings keys so it is compatible with your
existing settings solution. You can access using .notation
, [item] indexing
, .get method
and also it allows .notation.nested
for data structures like dicts.
Also variable access is case insensitive for the first level key
Custom Prefix¶
You are allowed to customize the prefix for your env vars. Let's say your application is called "PEANUT"
export PEANUT_USER=admin
export PEANUT_PASSWD=1234
export PEANUT_DB={name='foo', port=2000}
export PEANUT_DB__SCHEME=main
Now to your settings instance you can customize the prefix:
from dynaconf import Dynaconf
settings = Dynaconf(envvar_prefix="PEANUT")
assert settings.USER == "admin"
assert settings.PASSWD == 1234
assert settings.db.name == "foo"
assert settings.db.port == 2000
assert settings.db.scheme == 'main'
If you don't want to use any prefix (load unprefixed variables) the correct way is to set it like so:
from dynaconf import Dynaconf
settings = Dynaconf(envvar_prefix=False)
Dot env¶
When you have multiple environment variables to set it is useful to automate the definition
and Dynaconf comes with Python-Dotenv
support.
You can put in the root of your application a file called .env
PREFIX_USER=admin
Then pass load_dotenv=True
to your settings.
from dynaconf import Dynaconf
settings = Dynaconf(load_dotenv=True)
assert settings.USER == "admin"
Type Casting and Lazy Values¶
In addition to toml
parser you can also force your variables to be converted
in to a desired data type.
export PREFIX_NONE='@none None' # None
export PREFIX_NONE='@int 16' # int: 16
export PREFIX_NONE='@bool off' # bool: False
export PREFIX_ARRAY='@json [42, "Oi", {"foo": "bar"}]' # Heterogeneus list
Lazy Values¶
Dynaconf support 2 types of lazy values format
and jinja
which allows
template substitutions.
export PREFIX_PATH='@format {env{"HOME"}/.config/{this.DB_NAME}'
export PREFIX_PATH='@jinja {{env.HOME}}/.config/{{this.DB_NAME}} | abspath'
Adding a Custom Casting Token¶
If you would like to add a custom casting token, you can do so by adding a converter. For example, if we would like to cast strings to a pathlib.Path object we can add in our python code:
# app.py
from pathlib import Path
from dynaconf.utils import parse_conf
parse_conf.converters["@path"] = (
lambda value: value.set_casting(Path)
if isinstance(value, parse_conf.Lazy)
else Path(value)
)
In the settings file we can now use teh @path casting token. Like with other casting tokens you can also combine them:
# settings.toml
my_path = "@path /home/foo/example.txt"
parent = "@path @format {env[HOME]}/parent"
child = "@path @format {this.parent}/child"
Environment variables filtering¶
All environment variables (naturally, accounting for prefix rules) will be used and pulled into the settings space.
You can change that behaviour by enabling the filtering of unknown environment variables:
from dynaconf import Dynaconf
settings = Dynaconf(ignore_unknown_envvars=True)
In that case, only previously defined variables (e.g. specified in
settings_file
/settings_files
, preload
or includes
) will be loaded
from the environment. This way your setting space can avoid pollution
or potentially loading of sensitive information.