API Reference¶
Core¶
- Responsibility:
Provide the staticconfig decorator to transform user-defined configuration classes into fully functional static configuration classes with validation and persistence capabilities.
- Contracts:
The decorator expects classes to define required attributes from StaticConfigInterface.
Data fields with duplicate names will raise TypeError during decoration.
All decorated classes will inherit from StaticConfigBase.
- staticconfiguration.config_base.decorator.staticconfig(cls)¶
Decorate a settings class to enable static configuration functionality.
- Responsibility:
Validate the class structure, verify required attributes and Data fields, and inject StaticConfigBase inheritance to enable configuration persistence and access.
- Contracts:
- Preconditions:
clsmust define all required attributes from StaticConfigInterface.All Data fields in
clsmust have unique names.
- Postconditions:
Returns a class that inherits from StaticConfigBase.
The returned class has validated Data fields stored in
__data_fields__.The class is ready to use get/set methods for configuration access.
- Parameters:
cls (type) – The class to decorate as a static configuration class.
- Returns:
The decorated class with StaticConfigBase functionality.
- Return type:
type
- Raises:
TypeError – If required attributes are missing or Data field names are duplicated.
Example
>>> @staticconfig >>> class AppConfig: >>> __config_path__ = "~/.config/myapp" >>> __config_file__ = "app.json" >>> __version__ = "1.0.0" >>> __development__ = False >>> timeout = Data(name="timeout", data_type=int, default=30)
- Responsibility:
Provide base utilities to manage static configurations defined via Data descriptors and persisted using a JSON backend.
- Contracts:
Classes that inherit from StaticConfigBase must declare configuration attributes as Data instances and define __config_path__, __config_file__, and __version__.
No function modifies resources outside the path provided by __config_path__ and __config_file__.
- class staticconfiguration.config_base.static_config_base.StaticConfigBase¶
Base class for static configurations with JSON persistence.
- Responsibility:
Provide reusable get and set methods to access and modify configuration values declared as Data in subclasses, delegating persistence to the JSON backend.
- Contracts:
- Invariants:
Subclasses define __config_path__, __config_file__, and __version__ as class attributes.
- Preconditions:
Configuration fields are declared as Data instances in the derived class.
- Postconditions:
get returns the stored value or the default defined in the corresponding Data.
set validates the type and persists the new value using JSONBackend.
- classmethod get(data_field, concurrency_unsafe=False)¶
Retrieve the configuration value associated with
data_field.- Responsibility:
Locate the Data descriptor corresponding to the provided field, ensure the configuration file exists, and invoke the backend to obtain the stored value.
- Contracts:
- Preconditions:
data_fieldmust be a Data descriptor attribute in the subclass.
- Postconditions:
Returns the currently persisted value or the default value defined in the Data if it does not yet exist in the file.
- Parameters:
data_field (Data) – Data descriptor attribute to retrieve.
concurrency_unsafe (bool) – If True, operations will be unsafe for concurrent access. Default is False. Data integrity may be compromised if multiple processes write concurrently. Use with caution.
- Returns:
Field value decoded according to Data rules.
- Return type:
Any
- Raises:
TypeError – If
data_fieldis not a Data descriptor.KeyError – If
data_fieldis not defined in the class.
Example
>>> MyConfig.get(MyConfig.timeout) 30
- classmethod set(data_field, new_value, concurrency_unsafe=False)¶
Assign and persist a new value for the specified field.
- Responsibility:
Validate the type of
new_valueaccording todata.data_type, ensure the configuration file exists, and delegate writing to the JSON backend.
- Contracts:
- Preconditions:
data_fieldcorresponds to a Data defined in the class.new_valueis an instance compatible withdata.data_type.
- Postconditions:
The new value is persisted in the configuration file and
last_modifiedis updated.
- Parameters:
data_field (Data) – Data descriptor attribute to modify.
new_value (object) – New value that must be compatible with the type declared in the corresponding Data.
concurrency_unsafe (bool) – If True, operations will be unsafe for concurrent access. Default is False. Data integrity may be compromised if multiple processes write concurrently. Writting is more likely to corrupt the file if multiple processes write concurrently. Use with caution.
- Returns:
Persists the new value to disk.
- Return type:
None
- Raises:
TypeError – If
data_fieldis not a Data descriptor ornew_valueis not of the expected type.KeyError – If
data_fieldis not defined in the class.
Example
>>> MyConfig.set(MyConfig.timeout, 60)
- Responsibility:
Define the interface that all static configuration classes must implement by declaring required class attributes.
- Contracts:
Classes implementing this interface must define __config_file__, __version__, __development__, and __config_path__ as class attributes.
This interface serves as a contract enforced by the staticconfig decorator.
- class staticconfiguration.config_base.static_config_interface.StaticConfigInterface¶
Interface defining required attributes for static configuration classes.
- Responsibility:
Declare the required class attributes that all static configuration classes must define to enable proper configuration management.
- Contracts:
- Invariants:
Implementing classes must define all four annotated attributes.
__config_file__ specifies the configuration file name.
__version__ specifies the configuration schema version.
__development__ indicates development mode status.
__config_path__ specifies the directory path for configuration storage.
Entities¶
- Responsibility:
Define the Data class that serves as a descriptor for configuration fields, encapsulating metadata such as name, type, default value, and optional encoder/decoder functions.
- Contracts:
Data instances are immutable after creation and serve as declarative specifications for configuration fields.
Encoder and decoder functions, if provided, must be compatible with the data_type specified.
- class staticconfiguration.entities.data.Data(name, data_type, default, encoder=None, decoder=None)¶
Container for configuration field metadata.
- Responsibility:
Encapsulate all metadata required to define a configuration field, including its name, type, default value, and optional serialization functions.
- Contracts:
- Invariants:
Once created, Data instances should be treated as immutable specifications.
- Preconditions:
namemust be a non-empty string.data_typemust be a valid Python type.defaultshould be compatible withdata_type.If provided,
encodermust accept instances ofdata_type.If provided,
decodermust return instances ofdata_type.
- Postconditions:
All provided attributes are stored and accessible as instance attributes.
- Parameters:
name (str)
data_type (type)
default (object)
encoder (function | None)
decoder (function | None)
Backend¶
- Responsibility:
Provide a simple JSON file-based backend to store and retrieve structured configuration values. Group the necessary operations to ensure safe state, read, and write the configuration file.
- Contracts:
The backend assumes the filesystem is available and the process has read/write permissions on the target path.
Methods expect to receive valid pathlib.Path objects and Data objects defined in staticconfiguration.entities.
- class staticconfiguration.json_backend.json_backend.JSONBackend¶
Backend for JSON persistence of static configurations.
Responsibility: - Handle initial creation of the JSON configuration file, as well as reading and writing individual values. Contracts: Invariants: - No method modifies paths other than those provided by its arguments. Preconditions: - ``config_path`` must be a pathlib.Path pointing to the file or the location where it will be created. - ``data_fields`` is a valid list of Data describing fields and possible associated encoder/decoder. Postconditions: - After ``ensure_safe_state``, a JSON file exists with keys ``version``, ``created``, ``last_modified``, and ``data`` and is structurally operable when preconditions are met.- static read_value(data, config_path, version, data_fields, development, concurrency_unsafe=False)¶
Read and decode the value of a configuration key from JSON.
- Responsibility:
Retrieve the stored value for the provided Data from the JSON file and return it in its domain representation (applying
Data.decoderif available or performing conversion viadata.data_type). Always under lock to ensure exclusive access.
- Contracts:
- Preconditions:
datais a valid Data instance with a definednameattribute.
- Postconditions:
Returns
NoneifdataisNone.If
data.decoderis present, the output is the result ofdata.decoder(raw_value).
- Parameters:
data (Data) – Descriptor of the field whose key is to be read.
config_path (Path) – Path to the JSON configuration file.
version (str) – Configuration schema version to store.
data_fields (list[Data]) – List of Data descriptors for fields to initialize with their default values.
development (bool) – If True, forces migration even if versions match.
concurrency_unsafe (bool) – If True, operations will be unsafe for concurrent access. Default is False. Data integrity may be compromised. Use with caution.
- Returns:
- Decoded value corresponding to the
datafield, or
Noneif the stored value is JSON null.
- Decoded value corresponding to the
- Return type:
object | None
- Raises:
KeyError – If the key described by
data.namedoes not exist in the JSON file.
- static write_value(data, new_value, config_path, version, data_fields, development, concurrency_unsafe=False)¶
Write or update the value of a field in the JSON configuration file.
- Responsibility:
Persist
new_valuefor the key described bydata, updating thelast_modifiedtimestamp and applyingData.encoderif present. Always under lock to ensure exclusive access.
- Contracts:
- Preconditions:
datais a valid Data instance andnew_valueis a value that can be serialized directly or viaData.encoder.data_fieldsis a valid list of Data from the configuration schema.
- Postconditions:
The JSON file will contain the updated value in
payload['data'][data.name](possibly encoded).payload['last_modified']will reflect the write time in ISO 8601 UTC format without microseconds.
- Parameters:
data (Data) – Descriptor of the field to update.
new_value (Any) – New value to store for the field.
config_path (Path) – Path to the JSON configuration file.
version (str) – Configuration schema version to store.
data_fields (list[Data]) – List of Data descriptors for fields to initialize with their default values.
development (bool) – If True, forces migration even if versions match.
concurrency_unsafe (bool) – If True, operations will be unsafe for concurrent access. Default is False. Data integrity may be compromised. Use with caution.
- Returns:
Does not return a value; persists the new state to disk.
- Return type:
None
- Raises:
KeyError – If the key described by
data.namedoes not exist in the JSON file.
Configuration payload migration and normalization utilities.
- Responsibility:
Provide deterministic migration of configuration payloads between schema versions.
Normalize payload structure by reconstructing the data dictionary from a field schema.
Ensure timestamp consistency and validation for creation and modification tracking.
Handle type coercion and default value application during field resolution.
- Contracts:
All methods in this module are stateless and do not mutate global state.
Output timestamps are always normalized to ISO 8601 format with UTC timezone (Z suffix).
Field values are resolved according to their declared data types and encoders.
Invalid or missing timestamps are normalized to the current UTC time.
- class staticconfiguration.json_backend.config_payload_migrator.ConfigPayloadMigrator¶
Migrate and normalize configuration payloads according to schema definitions.
- Responsibility:
Provide static methods for deterministic payload migration.
Reconstruct payload data from field schemas to ensure consistency.
Validate and normalize timestamps for tracking creation and modifications.
Apply type coercion and encoding rules to field values.
- Contracts:
- Invariants:
All methods are static and operate without instance state.
Migrations are deterministic given the same input payload and schema.
- Preconditions:
Input payloads may be partial, malformed, or from older schema versions.
Data fields must be valid Data instances with type and default information.
- Postconditions:
Output payloads conform to the current schema structure.
All required fields are present with appropriate values or defaults.
Timestamps are valid ISO 8601 strings with UTC timezone.
- static migrate_payload(payload, version, data_fields)¶
Migrate a configuration payload to a new schema version with normalized structure.
- Responsibility:
Reconstruct the data dictionary deterministically from the field schema.
Fields not present in the schema are dropped during reconstruction.
Apply type coercion and encoding to each field value.
Preserve the original creation timestamp if valid, otherwise use current time.
Update the last modified timestamp to the current time.
Handle missing fields by applying their default values.
- Contracts:
- Preconditions:
payload is a dictionary that may contain “data”, “created”, and other keys.
version is a non-empty string representing the target schema version.
data_fields is a list of Data instances defining the complete schema.
- Postconditions:
Returns a dictionary with keys: “version”, “created”, “last_modified”, “data”.
The “data” dictionary contains all fields from data_fields with resolved values.
Timestamps are valid ISO 8601 strings with UTC timezone.
- Parameters:
payload (dict) – The input configuration payload to migrate.
version (str) – The target schema version string.
data_fields (list[Data]) – List of Data field descriptors defining the schema.
- Returns:
- A normalized payload dictionary with keys: “version”, “created”,
”last_modified”, and “data”. The “data” key contains all fields with resolved values according to their schema definitions.
- Return type:
dict
Example
>>> fields = [Data(name="count", data_type=int, default=0)] >>> payload = {"data": {"count": "5"}, "created": "2024-01-01T00:00:00Z"} >>> result = ConfigPayloadMigrator.migrate_payload(payload, "1.0", fields) >>> result["version"] '1.0' >>> result["data"]["count"] 5
Exceptions¶
- exception staticconfiguration.exceptions.configuration_reset_warning.ConfigurationResetWarning(message='Configuration file was corrupted, configuration restored to defaults.')¶
Exception raised when there is an error resetting the configuration.