I’ve never been satisfied with the way I implement global configuration settings in my apps. Basically, I want a config.py file that defines default variables which will be used by several modules. It should also:
- Use type hints
- Only use the standard library
- Be possible to override values with environment variables (e.g. the
ca_bundle
config var should be overridable by settingMYAPP_CA_BUNDLE
) - If possible, allow overriding from the command line, though this isn’t a must-have
It feels like this should be simple enough so I don’t really want to require a third-party library for this. However, my attempts all result in multiple config instances, one for each module. Perhaps this is fine but it just seems wrong? And perhaps using a dataclass is overkill? I feel like there’s a simple way to do this that I’m missing. Here’s one such attempt:
# config.py
import os
from dataclasses import asdict, dataclass
@dataclass()
class Config:
ca_bundle : str = "/etc/ssl/certs/ca-bundle.crt"
def __post_init__(self):
for k in asdict(self):
env_var = f"MYAPP_{k.upper()}"
if env_var in os.environ and isinstance(k, str):
setattr(self, k, os.environ[env_var])
# my_module.py
from config import Config
if __name__ == "__main__":
config = Config()
print(config.ca_bundle)
use singleton if you want to have single class instance