Environment Resolver¶
The environment resolver lets you embed ${VAR_NAME} placeholders in
configuration strings and nested dictionaries. At load time, these references
are replaced with the corresponding environment variable values -- keeping
secrets like API keys and tokens out of source code.
Source: src/promptise/env_resolver.py
Quick example¶
import os
from promptise.env_resolver import resolve_env_var
os.environ["API_KEY"] = "secret123"
resolved = resolve_env_var("Bearer ${API_KEY}")
print(resolved) # "Bearer secret123"
# With a default value
resolved = resolve_env_var("${MISSING_VAR:-fallback}")
print(resolved) # "fallback"
Concepts¶
Placeholder syntax¶
Two placeholder forms are supported:
| Syntax | Behaviour |
|---|---|
${VAR_NAME} |
Required -- raises EnvVarNotFoundError if the variable is not set |
${VAR_NAME:-default_value} |
Optional -- uses default_value when the variable is not set |
The placeholder pattern matches variable names that follow Python/shell conventions: letters, digits, and underscores, starting with a letter or underscore.
import os
from promptise.env_resolver import resolve_env_var
os.environ["DB_HOST"] = "db.example.com"
# Required variable
resolve_env_var("postgres://${DB_HOST}:5432/app")
# -> "postgres://db.example.com:5432/app"
# Optional with default
resolve_env_var("${DB_PORT:-5432}")
# -> "5432" (if DB_PORT is not set)
# Multiple placeholders in one string
os.environ["DB_USER"] = "admin"
resolve_env_var("${DB_USER}@${DB_HOST}")
# -> "admin@db.example.com"
Resolving nested dictionaries¶
resolve_env_in_dict walks an entire nested dictionary and resolves
placeholders in all string values -- including strings inside lists and
sub-dictionaries.
import os
from promptise.env_resolver import resolve_env_in_dict
os.environ["TOKEN"] = "abc123"
os.environ["API_URL"] = "https://api.example.com"
config = {
"auth": "${TOKEN}",
"server": {
"url": "${API_URL}",
"port": 8080, # Non-strings are passed through unchanged
},
"tags": ["${TOKEN}", "static"],
}
resolved = resolve_env_in_dict(config)
# {
# "auth": "abc123",
# "server": {"url": "https://api.example.com", "port": 8080},
# "tags": ["abc123", "static"],
# }
Pre-validation¶
Before attempting to resolve all variables, you can check which ones are
missing using validate_all_env_vars_available. This is useful for
fail-fast startup validation.
from promptise.env_resolver import validate_all_env_vars_available
config = {
"api_key": "${OPENAI_API_KEY}",
"url": "${API_URL:-http://localhost:8080}",
}
missing = validate_all_env_vars_available(config)
if missing:
print(f"Missing env vars: {', '.join(missing)}")
# Only lists truly required variables -- those with defaults are excluded
The regex pattern¶
The raw pattern used for matching is exposed as ENV_VAR_PATTERN:
from promptise.env_resolver import ENV_VAR_PATTERN
# re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*?)(?::-(.*?))?\}")
This can be useful if you need to scan configuration files for placeholder references in custom tooling.
API summary¶
resolve_env_var¶
| Parameter | Type | Default | Description |
|---|---|---|---|
value |
str |
required | String potentially containing ${VAR} references |
context |
str \| None |
None |
Optional context for error messages (e.g. "servers.math.url") |
allow_missing |
bool |
False |
If True, leave unresolved vars as-is instead of raising |
| Returns | str |
String with all environment variables resolved | |
| Raises | EnvVarNotFoundError |
If a required variable is not found and allow_missing is False |
resolve_env_in_dict¶
| Parameter | Type | Default | Description |
|---|---|---|---|
data |
dict[str, Any] |
required | Dictionary potentially containing env var references |
context_prefix |
str |
"" |
Prefix for error context (e.g. "servers.math") |
| Returns | dict[str, Any] |
New dictionary with all env vars resolved | |
| Raises | EnvVarNotFoundError |
If any required variable is not found |
validate_all_env_vars_available¶
| Parameter | Type | Default | Description |
|---|---|---|---|
data |
dict[str, Any] |
required | Parsed configuration data (dict from YAML/JSON) |
| Returns | list[str] |
Sorted list of missing variable names (empty if all available) |
ENV_VAR_PATTERN¶
| Export | Type | Description |
|---|---|---|
ENV_VAR_PATTERN |
re.Pattern |
Compiled regex matching ${VAR} and ${VAR:-default} syntax |
Tips and gotchas¶
Tip
Use validate_all_env_vars_available at application startup to detect
missing environment variables early, before any agent or server starts up.
Warning
The allow_missing flag in resolve_env_var leaves unresolved placeholders
as literal ${VAR} strings. This is useful for multi-stage resolution but
can cause subtle bugs if you forget to resolve them later.
Tip
The context parameter (in resolve_env_var) and context_prefix
(in resolve_env_in_dict) produce clearer error messages. When a variable
is missing, the error will say something like:
Environment variable 'API_KEY' not found (referenced in: servers.math.url).
Warning
resolve_env_in_dict returns a new dictionary -- it does not mutate the
input. Non-string, non-dict, non-list values are passed through unchanged.
What's next¶
- Config & Server Specs -- use resolved values in server specifications
- Exceptions -- details on
EnvVarNotFoundError - SuperAgent files -- YAML-based configuration that uses env resolution