What’s a pythonic way to implement a typed overridable config.py?

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 setting MYAPP_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)

  • 1

    use singleton if you want to have single class instance

    – 

Leave a Comment