YAML Configuration
Lexigram merges user-defined YAML files, environment variables, and code defaults into a single typed configuration object. This page covers the mechanics; for a task-oriented walkthrough see Configuration.
1. The Configuration File
Section titled “1. The Configuration File”The primary file is application.yaml in the project root. Core settings are top-level; each extension reads its own named section:
app_name: "order-service"debug: falseenv: "production"
db: # lexigram-sql (config_key: "db") backend: url: "${DATABASE_URL:sqlite+aiosqlite:///./dev.db}" pool: min_size: 2 max_size: 10
cache: # lexigram-cache (config_key: "cache") backends: - name: redis type: redis default: true redis_url: "${REDIS_URL}"Loading config
Section titled “Loading config”from lexigram import LexigramConfig
config = LexigramConfig.from_yaml() # auto-discovers application.yamlconfig = LexigramConfig.from_yaml("config/application.yaml")2. Environment Interpolation
Section titled “2. Environment Interpolation”Lexigram resolves ${VAR} placeholders inside YAML values at load time:
${PORT}— resolves to thePORTenv var; fails fast if unset.${PORT:8080}— resolves toPORT, or8080if unset.
db: backend: url: "${DATABASE_URL:sqlite+aiosqlite:///./dev.db}"3. Environment-Variable Overrides
Section titled “3. Environment-Variable Overrides”Beyond interpolation, any key can be overridden by an environment variable using the LEX_ prefix and double underscores (__) for nesting. This is the highest-priority source:
db.backend.url → LEX_SQL__BACKEND__URLweb.server.port → LEX_WEB__SERVER__PORTai_llm.providers[0].api_key → LEX_AI_LLM__PROVIDERS__0__API_KEYLEX_WEB__SERVER__PORT=9000 lexigram run4. Configuration Profiles
Section titled “4. Configuration Profiles”Override base settings per environment with profile files. Activate a profile with LEX_PROFILE:
LEX_PROFILE=production lexigram run- Base:
application.yaml - Overlay:
application.{profile}.yaml(e.g.application.production.yaml)
5. Precedence Rules
Section titled “5. Precedence Rules”When resolving a key, Lexigram applies sources in this order (highest priority wins):
LEX_environment variables —LEX_WEB__SERVER__PORT=9000overrides everything- Profile YAML — values from
application.{profile}.yaml - Base YAML — values from
application.yaml - Code defaults — defined in each config model
6. Typed Sections and get_section()
Section titled “6. Typed Sections and get_section()”LexigramConfig exposes typed top-level fields and resolves extension sections on demand:
config = LexigramConfig.from_yaml()
# Typed top-levelconfig.app_name # "order-service"config.debug # Falseconfig.environment # Environment.PRODUCTION
# Extension sections — pass the config model to get a typed object backdb_config = config.get_section("db", DatabaseConfig)
# Dotted pathsrag_config = config.get_section("ai_rag", RAGConfig)
# Existence checkconfig.has_section("web") # TrueProviders rarely call get_section() themselves — declaring config_key and config_model makes the framework inject the typed section automatically. See Configuration → auto-injection.
7. Profile Examples
Section titled “7. Profile Examples”debug: truelogging: level: DEBUG format: textdb: backend: url: "sqlite+aiosqlite:///./dev.db"debug: falselogging: level: WARNING format: jsoncache: backends: - name: redis type: redis default: true redis_url: "${REDIS_URL}"Next Steps
Section titled “Next Steps”- Configuration — the practical guide
- Application Lifecycle — when config is loaded during boot