A simple library for easy handling of .env
files and environment-variables configurations.
Implements a singleton class so that everywhere in your code you get exactly one shared configuration registry.
Requires: Python 3.9+ (we make use of
str.removeprefix
/removesuffix
from PEP 616 and modern typing features; Python 3.13 is recommended for full support ofSelf
,Final
,|
-unions, etc.)
The configuration data is loaded in this order of precedence:
- Explicit constructor arguments (positional
data: dict
or any**kwargs
) ENV_FILE
environment variable (if set, points to your.env
file)env_file=
constructor argument (pass a path when instantiating)- Default
.env
in the current working directory - Raw OS environment variables
Built-in support for:
- Case-insensitive access (
Config.DEBUG
,Config.debug
,Config["Debug"]
all work) - Automatic type casting via a
magic.config
file in your project root - Automatic MongoDB/MySQL URI generation from individual host/user/password vars
- Flask integration via
app.config.from_mapping(Config)
orapp.config.from_object(Config)
(with a__dir__
override)
pip install magic-config
pip install --upgrade magic-config
PyPI URL: https://pypi.org/project/magic-config/
DEBUG=1 python myapp.py
from magic_config import Config
if Config.DEBUG:
print("Debug mode is ON")
You can also do:
if Config.debug:
...
if Config["DeBuG"]:
...
You can pass your own values when you first import/instantiate:
from magic_config import MagicConfig, Config
from pathlib import Path
# Positional dict + kwargs
MagicConfig(
{"NUMBER": 456},
Boolean=True,
BASE_DIR=Path(__file__).resolve().parent
)
# Or only kwargs
MagicConfig(
BASE_DIR=Path(__file__).resolve().parent
)
# Afterwards you can read:
print(Config.BASE_DIR) # e.g. /www/sites/newhr.org/data/server
print(Config.NUMBER) # 456
print(Config.BOOLEAN) # True
Instead of relying on the default .env lookup, simply set ENV_FILE in your shell:
ENV_FILE=dev-1.env python app.py
The library will load variables from dev-1.env (instead of .env in CWD).
In your .env:
MONGO_HOST=127.0.0.1
MONGO_USER=user
MONGO_PWD=secret
MONGO_DB=test
MONGO_PORT=27017
from magic_config import Config
print(Config.MONGO_URI)
# => "mongodb://user:[email protected]:27017/test?authSource=admin&tls=false"
Likewise for MYSQL_HOST, MYSQL_USER, etc. — just call Config.MYSQL_URI.
Create magic.config in your project root:
DEBUG="bool"
MAX_USERS="int"
FEATURE_FLAGS="obj"
DEBUG=1 MAX_USERS=42 FEATURE_FLAGS='{"beta":true}' python server.py
from magic_config import Config
assert isinstance(Config.DEBUG, bool) # True
assert isinstance(Config.MAX_USERS, int) # 42
assert isinstance(Config.FEATURE_FLAGS, dict) # {"beta": True}
By default Flask’s app.config.from_object() only picks up actual attributes listed in dir(obj).
We provide a small __dir__
override in MagicConfig so you can do:
from flask import Flask
from magic_config import Config
app = Flask(__name__)
app.config.from_object(Config)
All your uppercase keys will be imported. Alternatively, you can treat Config as a plain mapping:
app.config.from_mapping(Config)
# or
app.config.update(Config)
Enjoy a cleaner, more powerful way to manage your application configuration!