Advanced Usage¶
Yeah Dynamic is part of the name of this library so you can do lots of things :)
Customizing the settings object¶
Sometimes you want to override settings for your existing Package or Framework lets say you have a conf module exposing a config object and used to do:
from myprogram.conf import config
Now you want to use Dynaconf, open that conf.py
or conf/__init__.py
and do:
# coding: utf-8
from dynaconf import LazySettings
config = LazySettings(ENVVAR_PREFIX_FOR_DYNACONF="MYPROGRAM")
Now you can use export MYPROGRAM_FOO=bar
instead of DYNACONF_FOO=bar
Module impersonation¶
In some cases you may need to impersonate your legacy settings
module for example you already have a program that does.
from myprogram import settings
and now you want to use dynaconf without the need to change your whole codebase.
Go to your myprogram/settings.py
and apply the module impersonation.
import sys
from dynaconf import LazySettings
sys.modules[__name__] = LazySettings()
the last line of above code will make the module to replace itself with a dynaconf instance in the first time it is imported.
Switching working environments¶
You can switch between existing environments using:
from_env
: (recommended) Will create a new settings instance pointing to defined env.setenv
: Will set the existing instance to defined env.using_env
: Context manager that will have defined env only inside its scope.
from_env¶
New in 2.1.0
Return a new isolated settings object pointing to specified env.
Example of settings.toml::
[development]
message = 'This is in dev'
foo = 1
[other]
message = 'this is in other env'
bar = 2
Program::
>>> from dynaconf import settings
>>> print(settings.MESSAGE)
'This is in dev'
>>> print(settings.FOO)
1
>>> print(settings.BAR)
AttributeError: settings object has no attribute 'BAR'
Then you can use from_env
:
>>> print(settings.from_env('other').MESSAGE)
'This is in other env'
>>> print(settings.from_env('other').BAR)
2
>>> print(settings.from_env('other').FOO)
AttributeError: settings object has no attribute 'FOO'
The existing settings
object remains the same.
>>> print(settings.MESSAGE)
'This is in dev'
You can assign new settings objects to different envs
like:
development_settings = settings.from_env('development')
other_settings = settings.from_env('other')
And you can choose if the variables from different envs
will be chained and overridden in a sequence:
all_settings = settings.from_env('development', keep=True).from_env('other', keep=True)
>>> print(all_settings.MESSAGE)
'This is in other env'
>>> print(all_settings.FOO)
1
>>> print(all_settings.BAR)
2
The variables from [development] are loaded keeping pre-loaded values, then the variables from [other] are loaded keeping pre-loaded from [development] and overriding it.
It is also possible to pass additional configuration variables to from_env
method.
new_settings = settings.from_env('production', keep=True, SETTINGS_FILE_FOR_DYNACONF='another_file_path.yaml')
Then the new_settings
will inherit all the variables from existing env and also load the another_file_path.yaml
production env.
setenv¶
Will change in_place
the env
for the existing object.
from dynaconf import settings
settings.setenv('other')
# now values comes from [other] section of config
assert settings.MESSAGE == 'This is in other env'
settings.setenv()
# now working env are back to previous
using_env¶
Using context manager
from dynaconf import settings
with settings.using_env('other'):
# now values comes from [other] section of config
assert settings.MESSAGE == 'This is in other env'
# existing settings back to normal after the context manager scope
assert settings.MESSAGE == 'This is in dev'
Populating objects¶
New in 2.0.0
You can use dynaconf values to populate Python objects (intances).
example:
class Obj:
...
then you can do:
from dynaconf import settings # assume it has DEBUG=True and VALUE=42.1
obj = Obj()
settings.populate_obj(obj)
assert obj.DEBUG is True
assert obj.VALUE == 42.1
Also you can specify only some keys:
from dynaconf import settings # assume it has DEBUG=True and VALUE=42.1
obj = Obj()
settings.populate_obj(obj, keys=['DEBUG'])
assert obj.DEBUG is True # ok
assert obj.VALUE == 42.1 # AttributeError
Customizations¶
It is possible to customize how your project will load settings, example: You want your users to customize a settings file defined in export PROJECTNAME_SETTINGS=/path/to/settings.toml
and you want environment variables to be loaded from PROJECTNAME_VARNAME
ENVVAR_PREFIX_FOR_DYNACONF = "PROJECTNAME"
"""This defines which environment variable global prefix dynaconf will load
That means that `export PROJECTNAME_FOO=1` will be loaded to `duanconf.settings.FOO
On command line it is possible to check it with `dynaconf list -k foo`"""
ENV_SWITCHER_FOR_DYNACONF='PROJECTNAME_ENV'
"""By default it is DYNACONF_ENV, this is the envvar used to switch from development to production
but with this settings your users can do `export PROJECT_ENV=production` (new in 2.0.0)"""
ENVVAR_FOR_DYNACONF = "PROJECTNAME_SETTINGS"
"""This defines which path dynaconf will look to load config files
example: export PROJECTNAME_SETTINGS=/path/to/settings.toml and the format can be
.ini, .json, .yaml or .toml
e.g::
export PROJECTNAME_SETTINGS=settings.toml
[default]
FOO = 1
[development]
FOO = 2
[production]
FOO = 3
OR::
export PROJECTNAME_SETTINGS=settings.yaml
default:
foo: 1
development:
foo: 2
production:
foo: 3
It is also possible to pass a list of files::
export PROJECTNAME_SETTINGS=settings.toml,other_settings.yaml,another.json
The variables will be cascaded in the defined order (last wins the precedence)
The environment variables wins precedence over all!
"""
# load dynaconf
settings = LazySettings(
ENVVAR_PREFIX_FOR_DYNACONF=ENVVAR_PREFIX_FOR_DYNACONF,
ENVVAR_FOR_DYNACONF=ENVVAR_FOR_DYNACONF.
ENV_SWITCHER_FOR_DYNACONF=ENV_SWITCHER_FOR_DYNACONF
)
Then the working environment can now be switched using export PROJECTNAME_ENV=production
Exporting¶
You can generate a file with current configs by calling dynaconf list -o /path/to/file.ext
see more in cli
You can also do that programmatically with:
from dynaconf import loaders
from dynaconf import settings
from dynaconf.utils.boxing import DynaBox
# generates a dict with all the keys for `development` env
data = settings.as_dict(env='development')
# writes to a file, the format is inferred by extension
# can be .yaml, .toml, .ini, .json, .py
loaders.write('/path/to/file.yaml', DynaBox(data).to_dict(), merge=False, env='development')
Preloading files¶
New in 2.2.0
Useful for plugin based apps.
from dynaconf import LazySettings
settings = LazySettings(
PRELOAD_FOR_DYNACONF=["/path/*", "other/settings.toml"], # <-- Loaded first
SETTINGS_FILE_FOR_DYNACONF="/etc/foo/settings.py", # <-- Loaded second (the main file)
INCLUDES_FOR_DYNACONF=["other.module.settings", "other/settings.yaml"] # <-- Loaded at the end
)