Environment Module
Core Feature
The Environment module is the heart of True Storage, providing powerful environment management with mode support, runtime configuration, and advanced stage management capabilities.
Overview
The Environment module offers a robust solution for managing configuration across different environments (development, testing, production) with features like:
Mode-Based Configuration: Switch between different environments seamlessly
Runtime Configuration: Change settings dynamically during execution
Stage Management: Define and manage custom stages beyond traditional environments
Decorator Support: Control function execution based on environment modes
State Management: Create and restore configuration snapshots
Type Safety: Validate configuration values with type checking
Key Components
Environment Class
- class true_storage.env.Environment(env_data='.env', validator=None, parent=None, interpolate=True, mode=<MODES.DEV: dev>, *extenal_envs)[source]
Bases:
objectAdvanced environment configuration and management system.
This class provides a comprehensive environment variable management system with features like mode-specific variables, secure storage, and variable validation.
- Variables:
_mode (MODES) – Current environment mode.
_instance (Environment) – Singleton instance of the environment.
_lock (threading.Lock) – Thread lock for singleton pattern.
_mode_vars (Dict[MODES, Set[str]]) – Mode-specific variable tracking.
_secure_mode_mappings (Dict[str, Set[MODES]]) – Secure storage of mode mappings.
- Parameters:
env_data (EnvPath, optional) – Source of environment data. Defaults to “.env”.
validator (EnvValidatorProtocol, optional) – Validator for environment variables.
parent (Environment, optional) – Parent environment for inheritance.
interpolate (bool, optional) – Enable variable interpolation. Defaults to True.
- static __new__(cls, *args, **kwargs)[source]
Implement thread-safe singleton pattern.
- __init__(env_data='.env', validator=None, parent=None, interpolate=True, mode=<MODES.DEV: dev>, *extenal_envs)[source]
- property envpath
- property externalenvs
- property mode_mappings: Dict[str, Set[MODES]]
Get a secure copy of the mode-to-variable mappings.
- Returns:
A mapping of variable names to their allowed modes.
- Return type:
Dict[str, Set[MODES]]
- property mode: MODES
Get current environment mode.
- property parent: Environment | None
Get parent environment.
- property snapshots: List[EnvSnapshot]
Get list of environment snapshots.
- mark(mode)[source]
Decorator for mode-specific function execution.
- Parameters:
mode (MODES) – Mode to execute the function in.
- Returns:
Decorated function that executes in specified mode.
- Return type:
Callable
Example
>>> env = Environment() >>> @env.mark(MODES.TEST) ... def test_function(): ... return env.get('TEST_CONFIG') # Only accessible in test mode
- with_mode(mode)[source]
Context manager for temporary mode switching.
- Parameters:
mode (MODES) – Mode to temporarily switch to.
- Yields:
Environment – Self with temporarily changed mode.
- Return type:
ModeContext
Example
>>> env = Environment() >>> with env.with_mode(MODES.PROD): ... secret = env.get('API_KEY') # Access production-only variable
- _is_mode_var(key, mode=None)[source]
Check if a variable belongs to a specific mode.
- Return type:
- mark_as_mode_var(key, mode)[source]
Mark a variable as belonging to a specific mode.
- Return type:
- _get_mode_key(key, mode=None)[source]
Generate a mode-specific key for an environment variable.
- static _get_base_key(key)[source]
Extract the base key from a mode-specific key.
- is_allowed_in_mode(key, mode)[source]
Check if a variable is allowed in a specific mode.
- static create_snapshot()[source]
Create a snapshot of the current environment state.
- Returns:
Snapshot containing current variable values.
- Return type:
EnvSnapshot
Example
>>> env = Environment() >>> snapshot = env.create_snapshot() >>> env.set({'DEBUG': 'false'}) >>> env.rollback(snapshot) # Restore previous state
- static rollback(snapshot)[source]
Rollback environment to a previous snapshot.
- Parameters:
snapshot (EnvSnapshot) – Snapshot to restore from.
- Return type:
Example
>>> env = Environment() >>> snapshot = env.create_snapshot() >>> env.set({'DEBUG': 'false'}) >>> env.rollback(snapshot) # Restore DEBUG to previous value
- get(key, default=None, mode=None)[source]
Retrieve an environment variable with mode support.
- Parameters:
key (str) – The variable name to retrieve.
mode (MODES) – To specify a mode or it will go for current mode.
default (Any, optional) – Default value if variable not found. Defaults to None.
- Returns:
The value of the environment variable.
- Return type:
- Raises:
ModeError – If the variable is not accessible in the current mode.
- set(items, system_env=False, modes=None)[source]
Set environment variables with mode-specific access control.
- Return type:
- _validate_and_set_value(key, value, system_env, modes)[source]
Validate and set a single environment variable.
- Return type:
- _set_value_in_environments(key, value, system_env, modes)[source]
Set the value in appropriate environments based on modes.
- Return type:
- delete(key, modes=None)[source]
Delete an environment variable from specified modes.
- Parameters:
key (str) – The variable name to delete.
modes (List[MODES], optional) – List of modes to delete from. If None, deletes from all modes.
- Return type:
Example
>>> env = Environment() >>> env.delete('DEBUG', modes=[MODES.PROD]) # Remove from production only >>> env.delete('API_KEY') # Remove from all modes
- static _normalize_modes(modes)[source]
Normalize the modes list to handle None case.
- Parameters:
modes (List[MODES], optional) – List of modes to normalize.
- Returns:
All available modes if input is None, otherwise the input list.
- Return type:
List[MODES]
- _delete_from_env(key, modes)[source]
Delete the variable from specified modes in the environment.
- _delete_common_variable(key)[source]
Delete a common (non-mode-specific) variable.
- _delete_mode_specific_variable(key, mode)[source]
Delete a mode-specific variable.
- _update_secure_mappings(key, modes)[source]
Update the secure mode mappings after variable deletion.
- format_debug(batch_size=10)[source]
Format environment data for debugging in batches.
- Return type:
- _format_batch(title, items, batch_size, start=0)[source]
Format a batch of items with a title.
- Return type:
- __getitem__(key)[source]
Get environment variable using dictionary-style access with mode support.
- Return type:
- __setitem__(key, value)[source]
Set environment variable using dictionary-style access with mode support.
- Return type:
- __delitem__(key)[source]
Delete environment variable using dictionary-style access with mode support.
- Return type:
- __contains__(key)[source]
Check if environment variable exists using ‘in’ operator with mode support.
- Return type:
- __iter__()[source]
Iterate over environment variables.
- filter(search_value, search_in='key', exclude_secrets=True, mode_specific=True)[source]
Filter environment variables with mode and secret support.
- filter_with_predicate(predicate, exclude_secrets=True, mode_specific=True)[source]
Filter environment variables with a predicate function.
- classmethod from_json(json_path, **kwargs)[source]
Create an Environment instance from a JSON file.
- Return type:
Environment
- classmethod from_dict(env_dict, **kwargs)[source]
Create an Environment instance from a dictionary.
- Return type:
Environment
- classmethod from_config(config_path, **kwargs)[source]
Create an Environment instance from a configuration file.
- Return type:
Environment
- validate_external_envs(extenal_envs)[source]
- write_env(env_path=None, flush=False)[source]
Write environment variables to a file, organized by mode.
This method writes the current environment variables to a file, organizing them by mode. It determines the output path, organizes the variables, formats them into sections, and then writes them to the specified file.
Notes
If env_path is None it will override the existing env file!
- Parameters:
- Return type:
- Returns:
None
- Raises:
Modes
- class true_storage.env.MODES(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]
-
Environment modes for configuration management.
This enum defines different operational modes for environment variable management, each with specific behaviors and access patterns.
- Variables:
- ALL = 'all'
- DEV = 'dev'
- TEST = 'test'
- STAGE = 'stage'
- PROD = 'prod'
- __init__(value)[source]
- classmethod _generate_next_value_(name, start, count, last_values)[source]
Generate the next value for enum members.
- property is_development: bool
Check if the current mode is a development mode.
- property is_production: bool
Check if the current mode is production mode.
- property is_all: bool
Check if the current mode is ALL mode.
- property prefix: str
Get the prefix for environment variables in this mode.
- property suffix: str
Get the suffix for environment variables in this mode.
- classmethod with_stages(**new_stages)[source]
Create a new MODES enum with additional custom stages.
- Parameters:
**new_stages (
str) – Keyword arguments of new stage names and their values- Return type:
- Returns:
A new MODES enum class with additional stages
- Raises:
ValueError – If a stage name conflicts with existing stages
- classmethod get_stage(name)[source]
Get a stage by name.
- Parameters:
name (
str) – Name of the stage to get- Return type:
MODES- Returns:
Either a MODES enum member or a CustomStage instance
- Raises:
ValueError – If stage doesn’t exist
Usage Examples
Basic Usage
# Initialize environment with mode
env = Environment(mode=MODES.DEV)
# Set environment variables
env.set("DATABASE_URL", "postgresql://localhost:5432/db", modes=[MODES.DEV])
env.set("DATABASE_URL", "postgresql://prod:5432/db", modes=[MODES.PROD])
# Get current environment variable
db_url = env.get("DATABASE_URL") # Returns dev URL in DEV mode
Mode Switching
# Using context manager
with env.with_mode(MODES.PROD):
prod_url = env.get("DATABASE_URL") # Gets production URL
# Using mode property
env.mode = MODES.TEST
test_config = env.get("TEST_CONFIG")
# Using decorators
@env.mark(MODES.PROD)
def production_task():
# Only runs in production mode
pass
Advanced Features
# Create configuration snapshot
snapshot = env.create_snapshot()
# Make temporary changes
env.set("TEMP_VAR", "temporary")
# Restore previous state
env.rollback(snapshot)
# Custom stages
env.with_stage(STAGING="staging", QA="qa")
@env.mark(MODES.STAGING)
def staging_task():
pass
Best Practices
Mode Management: - Always set a default mode during initialization - Use context managers for temporary mode switches - Avoid global mode changes in library code
Variable Handling: - Use type hints for better validation - Set defaults for optional variables - Group related variables by mode
State Management: - Create snapshots before major changes - Use rollback for testing and cleanup - Maintain separate configurations per mode
Security: - Never store sensitive data in code - Use separate files for different environments - Implement proper access controls
See Also
API Reference - Complete API documentation
Storage Module - Storage backend integration
Session Module - Session management
Database Module - Database configuration