Config¶
The config
module provides a flexible, extensible configuration system for Python applications, inspired by and compatible with Starlette's Config. It supports environment variables, .env
files, type casting, and advanced features like environment-specific overrides and adapter-based extensibility.
Why?¶
Managing configuration in Python projects often involves juggling environment variables, .env
files, and type conversions. The config
module streamlines this process, offering a unified API for loading, casting, and managing configuration values, while remaining compatible with Starlette's conventions.
from escudeiro.config import Config
config = Config(".env")
DEBUG = config("DEBUG", cast=bool, default=False)
DATABASE_URL = config("DATABASE_URL")
Features¶
- Starlette-compatible API for easy migration and interoperability
- Environment variable and
.env
file support - Type casting with robust error handling
- Environment-specific configuration via
EnvConfig
andDotFile
- Extensible adapters for dataclasses, attrs, Pydantic, and more
- Manual and automatic value overrides
- Thread-safe lazy loading
Usage¶
Basic Configuration¶
from escudeiro.config import Config
config = Config(".env")
SECRET_KEY = config("SECRET_KEY")
TIMEOUT = config("TIMEOUT", cast=int, default=30)
Environment-Specific Configuration¶
from escudeiro.config import EnvConfig, Env, DotFile
config = EnvConfig(DotFile(".env.production", Env.PROD))
API_URL = config("API_URL")
Using Adapters¶
Adapters allow you to load configuration into dataclasses, attrs, or Pydantic models.
from escudeiro.config.adapter import AdapterConfigFactory
from dataclases import dataclass
from escudeiro.data import data
@data
class PoolConfig:
size: int
timeout: int
max_retries: int
@dataclass # Also supports escudeiro.data.data, attrs.define and pydantic.BaseModel
class DBConfig:
host: str
port: int
user: str
password: str
pool: PoolConfig
factory = AdapterConfigFactory()
db_config = factory.load(DBConfig, __prefix__="db")
# will search for environment variables like DB_HOST, DB_PORT, etc.
# for pool it will search for DB_POOL__SIZE, DB_POOL__TIMEOUT, etc.
# the types defined in DBConfig will be automatically casted using the declared types
# or using boolean_cast for boolean values.
Type Casting Helpers¶
The escudeiro.config.core.utils
module provides a set of robust helpers for type casting and validation, which are used internally by the config system and can be leveraged in your own code for advanced scenarios.
Key Helpers¶
maybe_result
: A decorator that wraps a function to provide.strict()
(raises if result isNone
),.optional()
(suppresses exceptions), and normal call behavior. Used for safe and strict type conversions.instance_is_casted
: Returns a decorator that checks if a value is already of the expected type; if not, applies a fallback conversion.boolean_cast
: Converts strings like"true"
,"1"
,"false"
,"0"
to booleans, with strict error handling viamaybe_result
.valid_path
: Casts a string to aPath
and checks if it exists, raising if not.joined_cast
: Chains multiple casting operations together, allowing for complex type transformations.with_rule
: Wraps a cast function to enforce a rule (predicate), raisingInvalidEnv
if the rule fails.literal_cast
: Casts a string to a value from aLiteral
type annotation, raising if the value is not allowed.multicast
: Tries multiple casting functions in order, raising if all fail.none_is_missing
: Ensures that a cast never returnsNone
, raisingMissingName
if it does.null_cast
: Casts strings like"null"
,"none"
, or""
to PythonNone
.
These helpers are used by the config system to provide safe, extensible, and customizable type casting for environment variables and .env
values. You can use them directly for custom validation or casting logic in your own configuration workflows.
Examples¶
Here are some practical examples of using the helpers from escudeiro.config.core.utils
:
from escudeiro.config.core.utils import boolean_cast, valid_path, literal_cast, maybe_result
# Boolean casting
DEBUG = boolean_cast("true") # True
ENABLED = boolean_cast("0") # False
# Path validation
config_path = valid_path("/etc/myapp/config.yaml") # Raises if file does not exist
# Literal casting
from typing import Literal
env = literal_cast("prod", Literal["dev", "prod", "test"]) # "prod"
# Using maybe_result for strict/optional casting
strict_bool = maybe_result(boolean_cast).strict()
optional_bool = maybe_result(boolean_cast).optional()
strict_bool("yes") # Raises if not a valid boolean
optional_bool("maybe") # Returns None instead of raising
# Chaining casts with joined_cast
from escudeiro.config.core.utils import joined_cast
cast_to_int_then_str = joined_cast(int).cast(str)
result = cast_to_int_then_str("42") # "42" as a string after int conversion
# Using with_rule to enforce a custom rule
from escudeiro.config.core.utils import with_rule
positive_int = joined_cast(int).cast(with_rule(lambda x: x > 0))
value = positive_int("10") # 10
These examples demonstrate how you can compose and use the helpers for robust configuration parsing and validation.
API Reference¶
Config
¶
class Config:
def __init__(self, env_file: str | Path | None = None, mapping: Mapping[str, str] = DEFAULT_MAPPING)
def __call__(self, name: str, cast: Callable = default_cast, default: Any = MISSING) -> Any
def get(self, name: str, cast: Callable = default_cast, default: Any = MISSING) -> Any
- Description: Loads configuration from environment variables and
.env
files. - Parameters:
env_file
: Path to a dotenv file.mapping
: Optional mapping to override environment variables.
EnvConfig
¶
class EnvConfig(Config):
def __init__(self, env: Env, env_file: str | Path | None = None, ...)
def get(self, name: str, cast: Callable = default_cast, default: Any = MISSING) -> Any
@property
def dotfile(self) -> DotFile | None
- Description: Extends
Config
to support environment-specific overrides.
DotFile
¶
class DotFile:
filename: str | Path
env: Env
cascade: bool = False
- Description: Represents a configuration file for a specific environment.
Adapters¶
AdapterConfigFactory
: Base for creating config adapters.CachedFactory
: Caches adapter instances for efficiency.
Utilities¶
default_cast
: Default type casting function.MISSING
: Sentinel for missing values.EnvMapping
: Mapping for environment variables.
Notes¶
- The API is compatible with Starlette's
Config
, so you can migrate with minimal changes. - Use
EnvConfig
andDotFile
for advanced, multi-environment setups. - Adapters make it easy to bind configuration to structured types.