Tip of the Day: User-based Settings Configuration for Python With Dynaconf
Configurations vary substantially across deployments, but code does (should) not change. An important approach to configuration management is to use config files.
dynaconf
is one of my favourite packages for achieving this in Python.
However, setting up user-based configurations (as opposed to app-based) can be a little tricky.
A typical example would be a CLI app that can be installed for multiple users or across different machines.
Problem
As per this GitHub issue, dynaconf
, by default, loads settings based on the “present working directory” (pwd
).
Thus, if you have a CLI app that’s installed (e.g., pip install mypackage
or pip install -e .
), the settings will be properly loaded only if the CLI commands are run in the directory with with dynaconf
settings files (e.g., settings.toml
).
This does not bode well if we want to store our settings in a user’s home directory (e.g., ~/.mypackage.toml
), similar to how .zshrc
, .bashrc
, and .profile
are stored.
Loading a User-config File
Given a typical Python package, e.g., mypackage
:
.
├── mypackage
│ ├── __init__.py
│ ├── foo.py
│ ├── bar.py
├── README.md
├── requirements.txt
└── setup.py
We can set up the __init__.py
file like so:
from pathlib import Path
from dynaconf import LazySettings # type: ignore
ENVVAR_PREFIX_FOR_DYNACONF = "MYPACKAGE"
ENV_SWITCHER_FOR_DYNACONF = f"{ENVVAR_PREFIX_FOR_DYNACONF}_ENV"
ENVVAR_FOR_DYNACONF = f"{ENVVAR_PREFIX_FOR_DYNACONF}_SETTINGS"
DYNACONF_SETTINGS_FILE = Path.home() / ".mypackage.toml"
settings = LazySettings(
ENV_SWITCHER_FOR_DYNACONF=ENV_SWITCHER_FOR_DYNACONF,
ENVVAR_FOR_DYNACONF=ENVVAR_FOR_DYNACONF,
ENVVAR_PREFIX_FOR_DYNACONF=ENVVAR_PREFIX_FOR_DYNACONF,
SETTINGS_FILE_FOR_DYNACONF=DYNACONF_SETTINGS_FILE,
)
Then, in foo.py
and bar.py
, we can load settings like so:
from mypackage import settings
# settings work like typical dynaconf settings, e.g.:
user = settings.USERNAME
email = settings.EMAIL
password = settings.PASSWORD
Using this example, the settings are actually loaded from ~/.mypackage.toml
, allowing the user to define their settings as they see fit.