Core Config Protocols¶
Structum Configuration Subsystem.
This module exposes the Public API for configuration management. It adheres to the Stable Facade Principle (DP-1): application code imports from here (structum.config) and is decoupled from the underlying provider (JSON, Dynaconf, Database, etc.).
All code should interact with configuration via the aliases provided here.
Example
from structum.config import get_config
cfg = get_config() cfg.set(“app.mode”, “production”)
- structum.config.ConfigInterface¶
alias of
ConfigProviderInterface
- structum.config.get_config() ConfigProviderInterface¶
Returns the global configuration provider (Lazy Loading & Dynamic).
Architectural Role: Singleton Accessor.
If no provider handles been registered, it automatically instantiates the Fallback JSON Provider (Principle of Operational Continuity). This ensures the application works out-of-the-box without setup.
- structum.config.set_config_provider(provider: ConfigProviderInterface | type[ConfigProviderInterface]) None[source]¶
Registers a custom configuration provider.
Architectural Role: Dependency Injection Root.
This function is typically called by a plugin (e.g., structum-dynaconf) during the bootstrap phase. The registered provider globally replaces the default one, seamlessly upgrading the application capabilities.
- Parameters:¶
- provider: ConfigProviderInterface | type[ConfigProviderInterface]¶
Instance or Class of a provider conforming to ConfigInterface.
- class structum.config.JSONConfigProvider[source]¶
Bases:
objectProvider di configurazione basato su file JSON.
Caratteristiche: - Persistenza automatica su filesystem - Supporto a chiavi annidate tramite dot notation - Nessuna dipendenza esterna
- __init__()[source]¶
Initialize the JSON configuration provider.
Creates the configuration directory if needed and loads existing configuration from the JSON file.
Interfaces¶
Structum Configuration Interface.
This module defines the Formal Contract (Protocol) that all configuration providers must respect. The Structum core depends exclusively on this interface (Dependency Inversion), not on concrete implementations.
Architectural Role: - Decoupling: Application code knows ConfigProviderInterface, not Dynaconf. - Extensibility: Plugins (Dynaconf, Vault, Etcd) register themselves at bootstrap.
- class structum.config.interface.ConfigProviderInterface(*args, **kwargs)[source]¶
Bases:
ProtocolProtocol defining the interface for configuration providers.
This interface uses
typing.Protocolto enable duck typing: explicit inheritance is not required. Any object implementing these methods with compatible signatures is considered a valid provider.This approach maximizes flexibility and reduces coupling between core and plugins.
- Implementations:
DynaconfConfigProviderJSONConfigProvider(fallback)
Example
Using a configuration provider:
from structum.config import get_config_provider config = get_config_provider() # Get value with fallback db_host = config.get("database.host", default="localhost") # Set value config.set[Any]("database.port", 5432) # Check existence if config.has("database.password"): password = config.get("database.password") # Persist changes config.save()Note
All providers should be thread-safe and support hierarchical key access using dot-notation (e.g., “database.pool.size”).
See also
get_config_provider(): Retrieve the global configuration providerset_config_provider(): Register a custom provider-
get(key: str, default: Any =
None) Any[source]¶ Retrieve a configuration value by key.
Supports dot-notation for nested configuration values (e.g., “database.pool.size” accesses nested dictionaries).
- Parameters:¶
- Returns:¶
The configuration value, or default if key not found.
- Return type:¶
Any
- Raises:¶
KeyError – If key not found and default not provided (implementation-specific behavior).
Example
Retrieving nested configuration:
# Config: {"database": {"host": "localhost", "port": 5432}} host = config.get("database.host") # "localhost" port = config.get("database.port") # 5432 # With fallback timeout = config.get("database.timeout", 30) # 30See also
set[Any](): Set a configuration valuehas(): Check if a key exists
- set(key: str, value: Any) None[source]¶
Set a configuration value.
Persistence behavior depends on the concrete provider implementation. Changes may be in-memory only until
save()is called.- Parameters:¶
Example
Setting configuration values:
# Simple value config.set[Any]("app.debug", True) # Nested structure (creates intermediate dicts) config.set[Any]("database.pool.size", 10) # Complex value config.set[Any]("servers", ["srv1", "srv2", "srv3"])Warning
Changes are not persisted to storage until
save()is called (for file-based providers). In-memory providers lose changes on restart.
- has(key: str) bool[source]¶
Check if a configuration key exists.
Example
Checking key existence:
if config.has("database.password"): password = config.get("database.password") else: raise ValueError("Database password not configured")Note
A key can exist with a None value. Use
get()to distinguish between missing keys and None values.
- save() None[source]¶
Persist configuration changes to underlying storage.
For file-based providers, writes changes to disk. For remote providers, may trigger a commit or synchronization. For in-memory providers, this may be a no-op.
- Raises:¶
IOError – If unable to write to storage (file permissions, disk full).
RuntimeError – If provider doesn’t support persistence.
Example
Saving configuration:
config.set[Any]("app.version", "2.0.0") config.set[Any]("app.build", 123) config.save() # Persist both changesWarning
Unsaved changes will be lost on process termination. Call save() periodically for critical configuration updates.
See also
reload(): Discard changes and reload from storage
- reload() None[source]¶
Reload configuration from persistent storage.
Discards all unsaved in-memory changes and reloads the configuration from the underlying storage source.
Example
Reloading configuration:
config.set[Any]("temp.value", 123) # In-memory change config.reload() # Discards temp.value # Now config reflects disk state assert not config.has("temp.value")Warning
All unsaved changes will be permanently lost. Consider calling
save()before reload if needed.See also
save(): Persist changes before reloading
- structum.config.interface.get_config_provider() ConfigProviderInterface[source]¶
Returns the global configuration provider (Lazy Loading & Dynamic).
Architectural Role: Singleton Accessor.
If no provider handles been registered, it automatically instantiates the Fallback JSON Provider (Principle of Operational Continuity). This ensures the application works out-of-the-box without setup.
- structum.config.interface.set_config_provider(provider: ConfigProviderInterface | type[ConfigProviderInterface]) None[source]¶
Registers a custom configuration provider.
Architectural Role: Dependency Injection Root.
This function is typically called by a plugin (e.g., structum-dynaconf) during the bootstrap phase. The registered provider globally replaces the default one, seamlessly upgrading the application capabilities.
- Parameters:¶
- provider: ConfigProviderInterface | type[ConfigProviderInterface]¶
Instance or Class of a provider conforming to ConfigInterface.
Manager¶
Provider di configurazione JSON per Structum.
Questa implementazione rappresenta il fallback minimale basato esclusivamente sulla standard library Python. È pensata per garantire un funzionamento immediato del framework in assenza di plugin avanzati.
Per casi d’uso complessi (multi-source, validazione, override per ambiente) si raccomanda l’uso di provider esterni come Dynaconf.
- class structum.config.manager.JSONConfigProvider[source]¶
Bases:
objectProvider di configurazione basato su file JSON.
Caratteristiche: - Persistenza automatica su filesystem - Supporto a chiavi annidate tramite dot notation - Nessuna dipendenza esterna
- __init__()[source]¶
Initialize the JSON configuration provider.
Creates the configuration directory if needed and loads existing configuration from the JSON file.
-
get(key: str, default: Any =
None) Any[source]¶ Restituisce il valore associato a una chiave (dot notation supportata).