Typed configuration and runtime values
Files in config/ describe how each installation works: connections, drivers, limits, cookies, mail and other services. They are the place to read variables using Env or env(); during execution, components consume resolved values through an injected IApplication and app.config(...).
The Environment guide covers .env, typed values and bootstrap JSON persistence. This page documents configuration composition, native entities and validators you can reuse in your own configuration files.
How configuration is built
Section titled “How configuration is built”flowchart TD
A["Native entities: defaults"] --> D["Merge by section"]
B["Bootstrap withConfig options"] --> D
C["Frozen dataclasses discovered in config"] --> D
D --> E["Frozen bootstrap snapshot"]
E --> F["Settings available through app.config"]Without a valid compiled cache, the application:
- Builds independent dictionaries containing defaults for all 16 native sections.
- Incorporates dictionaries stored through
withConfig...()inbootstrap/app.py. - Discovers and instantiates frozen dataclasses from
config/; their values are applied last. - Freezes the bootstrap snapshot and prepares the configuration used by the application.
Merging uses dict.update() per section, rather than a universal recursive merge. Supply complete configuration when replacing a nested dictionary. A dataclass in config/app.py can also replace a value previously supplied through withConfigApp(...).
Each call to the same withConfig...() replaces that section’s dictionary stored by the preceding call. Group related options in a single call. When a compiled bootstrap is recovered, these setters do not rebuild it: see Configuration cache and Bootstrap options.
What entities validate and what setters do
Section titled “What entities validate and what setters do”Constructing a native entity runs its validation and normalization. Depending on the field, this can check ranges, strict types, enums and nested option structures. For example:
from orionis.foundation.config.hashing import Bcrypt
settings = Bcrypt(rounds=12)assert settings.rounds == 12
try: Bcrypt(rounds=32)except ValueError: print("The rounds setting is outside the supported range.")The withConfig...(**options) setters store dictionaries for merging; they do not automatically construct the equivalent entity or revalidate every option. A constructor rejecting a value does not mean the corresponding setter rejects it at that point. Consumers may perform additional checks during initialization, but the entire merge is not universally revalidated through Configuration.
Discovered dataclasses are actually instantiated: when they inherit a native entity and preserve its __post_init__(), its checks run. An exception during that construction propagates from configuration loading as RuntimeError, retaining its cause. A custom dataclass’s type annotations alone do not convert or validate every field.
frozen=True prevents attribute reassignment, but does not automatically make every internal dictionary or list immutable. Bootstrap freezing belongs to the application process and transforms supported containers such as dictionaries, lists, and tuples; it does not freeze every arbitrary object.
All 16 native sections
Section titled “All 16 native sections”Every section is optional when constructing Configuration: each has a default entity factory. Component-specific options, variables, drivers and restrictions are documented in their respective guides.
| Section | Main entity | Option reference |
|---|---|---|
app | App | Identity, environment and key. |
auth | Auth | Authentication and guards. |
cache | Cache | Cache stores and configuration. |
database | Database | Database connections. |
filesystems | Filesystems | Storage disks and configuration. |
hashing | Hashing | Hashing and drivers. |
http | HTTP | Middleware and HTTP policies, payloads and WebSocket. |
logging | Logging | Logging channels and rotation. |
mail | Mail | Mailers and email content. |
mcp | McpConfig | MCP transport and configuration. |
queue | Queue | Queue connections, workers and persistence. |
realtime | RealtimeConfig | Message and invocation limits. |
scheduler | Scheduler | Scheduling and persistence. |
session | Session | Lifetime, storage and cookies. |
testing | Testing | Test execution and configuration. |
view | View | View engine and extensions. |
Configuration: collect entities or dictionaries
Section titled “Configuration: collect entities or dictionaries”orionis.foundation.config.startup.Configuration is a frozen dataclass with keyword-only arguments. For each section in the table, it accepts the corresponding entity or a dict. It does not accept None as a replacement section; omitting the argument constructs its default.
Given a dictionary, it constructs Entity(**options) and runs that entity’s validation. Given an instance of the expected type, it retains it; a different type produces TypeError. Unknown dictionary fields fail during entity construction. Some entities normalize their substructures into entities while others retain validated dictionaries: do not assume every component has the same internal representation.
from orionis.foundation.config.app import App, Environmentsfrom orionis.foundation.config.startup import Configuration
# Fixed key exclusively for this isolated validation example.settings = Configuration( app=App(name="Reports", env=Environments.TESTING, key=b"k" * 32), hashing={"bcrypt": {"rounds": 12}}, view={"cache_size": 0, "autoescape": False},)
assert settings.app.name == "Reports"assert settings.hashing.bcrypt.rounds == 12assert settings.view.autoescape is Falseassert settings.toDict()["app"]["env"] == "testing"toDict() is inherited from BaseEntity and provides the data representation. Constructing Configuration does not automatically configure or start Application: there is no implicit step binding it to bootstrap/app.py. The application uses its own defaults, setters and dataclass-loading flow described above.
Do not replace an existing project’s key with this example’s fixed test key. Entity defaults may read the environment and App may generate and persist a missing key; configuration construction should not be assumed to have no side effects under all conditions.
Application options: App
Section titled “Application options: App”Import App, Cipher and Environments from orionis.foundation.config.app. The following are fallback defaults; environment values read by the entity may override them.
| Field | Type and default | Purpose and validation |
|---|---|---|
name | str, "Orionis Application" | Non-empty application name. |
env | str | Environments, "development" | development, testing or production; normalized to the enum value. |
debug | bool, True | Enables debugging detail; a string cannot substitute for a boolean. |
timezone | str, "UTC" | Timezone recognized by ZoneInfo. |
locale | str, "en" | Non-empty primary locale. |
fallback_locale | str, "en" | Non-empty fallback locale. |
language_path | str, "resources/lang/" | Non-empty translation path; see Localization. |
cipher | str | Cipher, "AES-256-CBC" | Normalized algorithm used to validate key length; see Encryption. |
key | str | bytes | None, None | Normalized to bytes. Accepts base64: representation; requires the cipher’s exact key length. Generates and persists a key when missing. |
maintenance | bool, False | Maintenance setting; effective state also considers the application’s maintenance marker. |
Environments contains DEVELOPMENT, TESTING and PRODUCTION. Cipher contains the available algorithms; the linked encryption guide explains their keys and uses. Normalization accepts a member, its name or its textual value according to normalize_enum().
Create a custom section
Section titled “Create a custom section”For example, create config/payments.py:
from dataclasses import dataclassfrom orionis.foundation.config.validation import validate_integer, validate_string
@dataclass(frozen=True, kw_only=True)class Payments: currency: str = "USD" receipt_limit: int = 100
def __post_init__(self) -> None: validate_string(self.currency, "currency") validate_integer(self.receipt_limit, "receipt_limit", minimum=1)The section comes from the module: after application creation, read it with app.config("payments.currency"). Keep one concrete configuration dataclass per section to avoid depending on merge ordering between classes writing the same keys. Avoid network I/O in construction: it is imported and instantiated during startup.
For .env values, use the reading and default_factory pattern in Environment. For reading or changing runtime values, see the Application API; process-local changes do not rewrite configuration files or guarantee reconfiguration of existing managers.
Reusable configuration validators
Section titled “Reusable configuration validators”These ten functions are in orionis.foundation.config.validation. They validate configuration options and do not replace payload schemas. The validate_* functions return None for accepted values without converting them; normalize_enum() and copy_string_list() return a result.
Integers, strings and booleans
Section titled “Integers, strings and booleans”validate_integer(value: object, name: str, *, minimum: int = 0, maximum: int | None = None) -> Nonevalidate_string(value: object, name: str, *, allow_empty: bool = False) -> Nonevalidate_boolean(value: object, name: str) -> Nonevalidate_integer() requires int and rejects bool; bounds are inclusive. validate_string() requires str and rejects empty or whitespace-only text unless allow_empty=True. validate_boolean() requires a real boolean without converting 1 or "true". Wrong types produce TypeError; an out-of-range value or disallowed empty string produces ValueError.
from orionis.foundation.config.validation import ( validate_boolean, validate_integer, validate_string,)
validate_integer(25, "page_size", minimum=1, maximum=100)validate_string("reports", "name")validate_string("", "optional_label", allow_empty=True)validate_boolean(False, "enabled")Enums and string lists
Section titled “Enums and string lists”normalize_enum(value: object, enum_type: type[Enum], name: str) -> objectcopy_string_list(value: object, name: str) -> list[str]normalize_enum() accepts an enum member or a string containing a member’s name or value, ignoring case and surrounding whitespace. It returns .value. An unsuitable type produces TypeError and an unknown string produces ValueError.
copy_string_list() requires a list rather than a tuple, validates that all items are non-empty strings and returns an independent copy. It preserves content and order without trimming or transforming strings.
from orionis.foundation.config.app import Environmentsfrom orionis.foundation.config.validation import copy_string_list, normalize_enum
assert normalize_enum(" PRODUCTION ", Environments, "env") == "production"original = ["api", "reports"]copied = copy_string_list(original, "channels")assert copied == original and copied is not originalCookie names and identifiers
Section titled “Cookie names and identifiers”validate_cookie_name(value: object, name: str) -> Nonevalidate_name(value: object, name: str, *, table: bool = False) -> NoneThe first checks the name using the HTTP cookie serializer. The second accepts identifiers of 1 to 128 characters starting with an alphanumeric character and continuing with ASCII letters, digits, _, . or -. With table=True, it applies ASCII [A-Za-z_]\w* for an unqualified table name. It neither quotes SQL nor validates query data.
from orionis.foundation.config.validation import validate_cookie_name, validate_name
validate_cookie_name("orionis_session", "cookie")validate_name("reports-primary", "connection")validate_name("job_results", "table", table=True)Both reject non-string types with TypeError and invalid names with ValueError.
Durations, queue drivers and HTTP origins
Section titled “Durations, queue drivers and HTTP origins”validate_seconds(value: object, name: str, *, positive: bool = False) -> Nonevalidate_driver(value: object, expected: Drivers) -> Nonevalidate_http_origin(origin: str) -> Nonevalidate_seconds() accepts finite int and float values, rejects bool and negative numbers, and rejects zero with positive=True. validate_driver() checks a string driver against the exact expected queue Drivers member; it is not a universal validator for every enum named Drivers.
validate_http_origin() accepts an explicit HTTP or HTTPS origin with a host and a valid port when supplied. It rejects wildcards, whitespace, non-ASCII characters, credentials, paths, queries and fragments. It does not change the representation; https://app.example.test/ has a path and is not equivalent to the origin without / for this validator.
from orionis.foundation.config.queue.enums import Driversfrom orionis.foundation.config.validation import ( validate_driver, validate_http_origin, validate_seconds,)
validate_seconds(0.5, "timeout", positive=True)validate_driver("redis", Drivers.REDIS)validate_http_origin("https://app.example.test:8443")Invalid types produce TypeError; durations, drivers or origins outside the accepted rules produce ValueError.
Logging-specific validators
Section titled “Logging-specific validators”orionis.foundation.config.logging.validators exports two callable objects:
IsValidPath(value: str, *, suffix: bool = False) -> NoneIsValidLevel(value: Level | int | str) -> NoneIsValidLevel.normalize(value: Level | int | str) -> intIsValidPath requires a non-empty string ending in .log; suffix=True also requires the literal {suffix} placeholder. It checks format, not file existence or permissions. IsValidLevel accepts Level, an allowed integer or a textual level name; normalize() returns the canonical integer and IsValidLevel(...) only validates. Levels are DEBUG=10, INFO=20, WARNING=30, ERROR=40 and CRITICAL=50.
from orionis.foundation.config.logging.validators import IsValidLevel, IsValidPath
IsValidPath("storage/logs/application.log")IsValidPath("storage/logs/application-{suffix}.log", suffix=True)IsValidLevel("warning")assert IsValidLevel.normalize(" INFO ") == 20Wrong types produce TypeError and unsupported formats or levels produce ValueError. See Logging to choose channels, paths and rotation.
Secret-generation helper
Section titled “Secret-generation helper”SecretKey.random(length: int = 32) -> strorionis.foundation.config.session.helpers.secret_key.SecretKey.random() delegates to secure random-byte generation and returns hexadecimal text: the default produces 32 bytes and a 64-character string. length counts bytes, not output characters. The helper does not store the key or change configuration.
from orionis.foundation.config.session.helpers.secret_key import SecretKey
generated_key = SecretKey.random()assert len(generated_key) == 64Use it when preparing a secret your component will retain in secure deployment configuration. Do not use it as a factory that changes a persistent secret on every startup or worker. Although located in config/session/helpers, the current session service does not use it automatically or expose a secret_key field connecting it: you do not need to add that setting to config/session.py. The helper adds no validation of length; invalid arguments propagate the underlying generator’s errors.
Configuration-family reference
Section titled “Configuration-family reference”The section table links to each component’s operational configuration. Auxiliary types in those families are listed below to locate their reference; Database, mail, storage and authentication options remain in their respective guides without duplication here.
| Family and reference | Defined classes and enums |
|---|---|
| app | App, Cipher, Environments |
| auth | Auth, Identity, PasswordReset, RememberAuth, SessionAuth, Tokens, Guards |
| cache | Cache, Database, File, Memcached, Memory, Redis, Stores, Drivers |
| database | Connections, Database, MySQL, Oracle, PGSQL, Redshift, SQLite, SQLServer, ConnectionName, MySQLCharset, MySQLCollation, MySQLEngine, OracleEncoding, OracleNencoding, PGSQLCharset, PGSQLCollation, PGSQLSSLMode, RedshiftSSLMode, SQLiteForeignKey, SQLiteJournalMode, SQLiteSynchronous, SQLServerCharset |
| filesystems | S3, Azure, Disks, Filesystems, GCS, Local, Public, DiskName |
| hashing | Argon2, Bcrypt, Hashing, Drivers |
| http | HTTPBodyLimits, Cors, HTTPCsrf, HTTP, HTTPProxies, HTTPRateLimit, Redis, HTTPSecurity, HTTPWebSocket |
| logging | Channels, Chunked, Daily, Hourly, Logging, Monthly, Stack, Weekly, Level |
File, FromAddress, Mail, Mailers, Smtp, MailDriver | |
| mcp | McpConfig |
| queue | Connections, Database, Failed, Queue, Redis, Sync, Worker, Drivers |
| realtime | RealtimeConfig |
| scheduler | Database, Memory, Redis, Scheduler, Stores, Drivers |
| session | Session, SessionDriver, SameSitePolicy, SecretKey |
| testing | Testing, VerbosityMode |
| view | View |
Continue with the Application API, Bootstrap options and Service providers.