Parse Env Vars into Typed Dict in Python
Convert a list of environment variable names into a dictionary with automatically detected types (bool, int, float, or string), defaulting missing vars to None.
Python code
58 linesimport os
from typing import Any, Dict
def parse_env_vars(env_names: list[str], env: Dict[str, str] | None = None) -> Dict[str, Any]:
"""Parse a list of environment variable names into a typed dict.
Each variable is parsed as:
- bool: "true"/"false" (case-insensitive)
- int: if it can be converted to an integer
- float: if it can be converted to a float
- str: fallback, original string value
Missing variables default to None.
"""
env = env or os.environ
result: Dict[str, Any] = {}
for name in env_names:
raw_value = env.get(name)
if raw_value is None:
result[name] = None
continue
# Normalize the value for parsing
value = raw_value.strip()
lower = value.lower()
if lower in ("true", "false"):
result[name] = lower == "true"
else:
try:
# Convert to int first (handles "10", "-5", "0x10")
result[name] = int(value, 0)
except ValueError:
try:
# Then try float ("3.14", "-0.5", "1e4")
result[name] = float(value)
except ValueError:
# Fall back to string
result[name] = value
return result
if __name__ == "__main__":
# Example usage with a mock environment
mock_env = {
"DEBUG": "true",
"PORT": "8080",
"TIMEOUT": "2.5",
"APP_NAME": "my-service",
"MISSING_VAR": None,
}
names = ["DEBUG", "PORT", "TIMEOUT", "APP_NAME", "MISSING_VAR"]
parsed = parse_env_vars(names, mock_env)
for key, value in parsed.items():
print(f"{key}: {value!r} ({type(value).__name__})")
Output
DEBUG: True (bool)
PORT: 8080 (int)
TIMEOUT: 2.5 (float)
APP_NAME: 'my-service' (str)
MISSING_VAR: None (NoneType)
How it works
The function iterates over each requested env var name and pulls its raw string value from the environment dict. Type detection happens in a cascade: booleans first ('true'/'false'), then integers using int(value, 0) which handles hex like '0x10', then floats, and finally falls back to the stripped string. Using env.get() returns None for missing keys, which becomes the default value in the result. The env or os.environ pattern lets you inject a mock dict for testing while defaulting to the real process environment.
Common mistakes
- Forgetting that `int(value, 0)` also parses hexadecimal — '0x10' becomes 16, which may surprise you
- Not stripping whitespace around values, causing ' true' to be treated as a string instead of a boolean
- Assuming all env vars exist — always handle missing keys with `.get()` or a try/except
- Using `int(value)` without base 0, which rejects valid hex strings like '0x1F'
Variations
- Use a `TypedDict` with explicit type annotations per key for stronger static checking
- Add support for JSON parsing with `json.loads` to handle arrays and objects in env vars
Real-world use cases
- Loading service configuration from environment variables in a 12-factor app before startup.
- Parsing feature flags passed from CI/CD pipelines into typed values for test automation.
- Converting environment variables in a Docker container into typed settings for a data pipeline.
Sponsored
More from Dictionaries & sets
- Build a Case-Insensitive Dict with a Wrapper Class in Python medium
- Build a defaultdict histogram of categories in Python easy
- Build adjacency dict graph from edges in Python easy
- Build an OrderedDict insertion order demo in Python 3 easy
- Check Invertible Mapping for Duplicate Values in Python easy
- Compare Two Dictionaries in Python easy
Keep learning
Related tutorials and quizzes for this topic.