Welcome to Concrete Settings

Concrete Settings is a Python library which facilitates configuration management in big and small programs.

The project was born out of necessity to manage a huge decade-old Django-based SaaS solution with more than two hundred different application settings scattered around settings.py. What does this setting do? What type is it? Why does it have such a weird format? Is this the final value, or it changes somewhere on the way? Sometimes developers spent hours seeking answers to these questions.

Concrete Settings tackles these problems altogether. It was designed to be developer and end-user friendly. The settings are defined via normal Python code with few tricks which significantly improve readability and maintainability.

Take a look at a small example of Settings class with one boolean setting DEBUG. A developer defines the settings in application code, while an end-user chooses to store the configuration in a YAML file:

# settings.py

from concrete_settings import Settings

class AppSettings(Settings):

    #: Turns debug mode on/off
    DEBUG: bool = False

app_settings = AppSettings()
# settings.yml

DEBUG: true

Accessing settings:

>>>  print(app_settings.DEBUG)

>>> print(AppSettings.DEBUG.__doc__)
Turns debug mode on/off

Settings are defined in classes. Python mechanism of inheritance and composition apply here, so settings can be mixed (multiple inheritance) and be nested (settings as class fields). Settings are type-annotated and are validated. Documentation matters! Each settings can be documented in Sphinx-style comments #: written above its definition. An instance of Settings can be updated i.e. read from any kind of source: YAML, JSON or Python files, environmental variables, Python dicts, and you can add more!

Finally, Concrete Settings comes with batteries like Django 3.0 support out of the box.

In a nutshell:

:Developer: as Dev
:Application User: as User
(.yaml) as (yaml_source)
(.json) as (json_source)
(.py) as (py_source)
(Environmental Variables) as (envvar)

note top of User
    **User** sets configuration
    in files, environmental variables
    and other **sources**.
end note

note top of Dev
    **Developer** defines configuration
    via Concrete Settings
end note

User ==> (yaml_source)
User ==> (json_source)
User ==> (envvar)
User ==> (py_source)
User ==> (...)

Dev ==> (Settings)

(yaml_source) .. (Sources)
(json_source) .. (Sources)
(envvar) .. (Sources)
(...) .. (Sources)

note "Verify definition structure" as note_verify
note "Update Settings from sources" as note_update
note "Validate values" as note_validate

note_update <== (Sources)

(Settings) .. note_verify
note_verify ..> note_update
note_update .. note_validate
note_validate ..> (Application)


This flow perfectly applies to

  • A web application backend. Think of Django or Flask application and all the settings required to start it up.

  • A rich feed-execute-output tools like Sphinx documentation.

Concrete Settings are here to improve configuration handling whether you are starting from scratch, or dealing with an old legacy Cthulhu. Are you ready to try it out? Then you are very welcome to Concrete Settings documentation!


Python Version

We recommend using the latest version of Python 3. Concrete Settings supports Python 3.6 and newer.

With pip:

pip install concrete-settings


These distributions will be installed automatically when installing Concrete Settings:

  • Typeguard provides runtime type checking and allows validating settings values types.

  • Sphinx allows documenting settings in developer-friendly way - in comments above settings definitions.

  • Typing Extensions provides typing hints backports to Python 3.6.

Optional dependencies

These distributions will not be installed automatically. Concrete Settings will detect and use them if you install them.

  • PyYAML allows reading settings from YAML sources.


The source is available at https://github.com/basicwolf/concrete-settings.

Contributions are warmly welcomed!


API Reference

If you are looking for information on a specific function, class or method, this part of the documentation is for you.

Indices and tables