Configuration

Provides a simple woy to add settings to your application.

Management of loading of settings from different file types and merging into a simple easy to use settings object.

Usage:

>>> from pyapp.conf import settings
>>> # Configure default settings
>>> settings.configure('my_app.default_settings')

>>> settings.MY_CONFIG_VALUE
'foo'

Note

All settings must be UPPER_CASE. If a setting is not upper case it will not be imported into the settings object.

The settings object also has helper methods to simplify your testing:

>>> from pyapp.conf import settings
>>> with settings.modify() as patch:
...     patch.MY_CONFIG_VALUE = 'bar'
...     settings.MY_CONFIG_VALUE
'bar'
>>> settings.MY_CONFIG_VALUE
'foo'

In addition to changing values new values can be added or existing values removed using the del keyword. Once the context has been exited all changes are reverted.

Testing CLI Commands

When testing the CLI settings loading can be a problem if your test case loads different settings or requires changes to be applied to settings files for test cases to execute correctly.

To reset settings to allow the CLI to rebuild the settings object use the reset_settings:

>>> from pyapp.conf import settings
>>> with settings.modify() as patch:
...     patch.reset_settings()
...     assert not settings.is_configured
>>> assert settings.is_configured

Just like with any usage of settings.modify() the origional settings are restored once the with block is exited.

Settings

class pyapp.conf.Settings(base_settings_=None)[source]

Settings container

configure(default_settings: str | Sequence[str], runtime_settings: str = None, additional_loaders: Sequence[Loader] = None, env_settings_key: str = 'PYAPP_SETTINGS')[source]

Configure the settings object

Parameters:
  • default_settings – Your applications and extensions default settings.

  • runtime_settings – Settings defined for the current runtime (eg from the command line)

  • additional_loaders – Additional loaders to execute

  • env_settings_key – Environment variable key used to override the runtime_settings.

property is_configured: bool

Settings have been configured (or some initial settings have been loaded).

load(loader: Loader, apply_method=None)[source]

Load settings from a loader instance. A loader is an iterator that yields key/value pairs.

See pyapp.conf.loaders.ModuleLoader as an example.

modify() ModifySettingsContext[source]

Apply changes to settings file using a context manager that will roll back the changes on exit of a with block. Designed to simplify test cases.

This should be used with a context manager:

>>> settings = Settings()
>>> with settings.modify() as patch:
>>>     # Change a setting
>>>     patch.FOO = 'foo'
>>>     # Remove a setting
>>>     del patch.BAR
Return type:

ModifySettingsContext

Loaders

Conf Loaders

Loaders are used to load settings from an external source, eg a Python module (using ModuleLoader).

A loader provides key/value pairs to the settings container to merge into the application settings.

ModuleLoader

class pyapp.conf.loaders.ModuleLoader(module: str)[source]

Load configuration from an importable module.

Loader will load all upper case attributes from the imported module.

Usage:

>>> loader = ModuleLoader("name.of.module")
>>> settings = dict(loader)

ObjectLoader

class pyapp.conf.loaders.ObjectLoader(obj: object)[source]

Load configuration variables from any object. This can be used to mirror settings from Django settings.

Loader will only read UPPERCASE attributes from the object.

Usage:

>>> from django.conf import settings as django_settings
>>> from pyapp.conf import settings as pyapp_settings
>>> loader = ObjectLoader(django_settings)
>>> pyapp_settings.load(loader)

New in version 4.2.

File Loader

Loads settings from a file

FileLoader

class pyapp.conf.loaders.file_loader.FileLoader(path: str | Path, content_type: str, *, encoding: str = 'UTF8')[source]

Load settings from a file.

Usage:

>>> loader = FileLoader('/path/to/settings.json')
>>> settings = dict(loader)

HTTP Loader

Loads settings from an HTTP endpoint (HTTPS is recommended)

HttpLoader

class pyapp.conf.loaders.http_loader.HttpLoader(url: URL)[source]

Load settings from a file.

Usage:

>>> loader = HttpLoader(URL("https://hostname/path/to/settings.json"))
>>> settings = dict(loader)

Default settings

Base settings used to initialise settings object.

pyapp.conf.base_settings.CHECK_LOCATIONS: List[str] = []

Locations to import to ensure checks are registered.

pyapp.conf.base_settings.DEBUG: bool = False

Enable debug mode

pyapp.conf.base_settings.FEATURE_FLAGS: Dict[str, bool] = {}

Feature flags definition, this is a simple configuration of:

FEATURE_FLAGS = {
    "flag-name": True,  # State of True, False
}
pyapp.conf.base_settings.FEATURE_FLAG_PREFIX: str = 'PYAPP_FLAG_'

Prefix applied to flag names for environment variables

pyapp.conf.base_settings.LOGGING: Dict[str, Any] = {}

Logging configuration.

The following configuration is applied by default:

LOGGING = {
    "formatters": {
        "default": {
            "format": "%(asctime)s | %(levelname)s | %(name)s | %(message)s",
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "default",
            "stream": "ext://sys.stderr",
        },
    },
    "root": {
        # "level" : "INFO",  # Set from command line arg parser.
        "handlers": ["console"],
    }
}
pyapp.conf.base_settings.LOG_HANDLERS = {}

Simple method for configuring log handlers that is merged into the default logging configuration. This allows for custom handlers to be configured without needing to duplicate the entire logging configuration.

By default all handlers defined in this dict are added to the root handler, if this is not desired set the non_root argument to True.

See the Logging Handlers in the Python documentation for a complete list of builtin handlers.

Example:

LOG_HANDLERS = {
    "file": {
        "class": "logging.handlers.RotatingFileHandler",
        "stream": "/path/to/my/file.log",
        "maxBytes": 5_242_880,  # 5MiB
    },
    "special_file": {
        "class": "logging.FileHandler",
        "non_root": True,  # Don't assign to root logger
        "stream": "/path/to/my/special.log",
    }
}
pyapp.conf.base_settings.LOG_LOGGERS = {}

Simple method for configuring loggers that is merged into the default logging configuration. This allows for custom loggers to be configured without needing to duplicate the entire logging configuration.

Example:

LOG_LOGGERS = {
    "my_package.my_module": {
        "level": "INFO",
        "handlers": ["console"]
    }
}