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.

Easy Python 3.10+ Aug 9, 2026 Dictionaries & sets 14 views 0 copies

Python code

58 lines
Python 3.10+
import 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

stdout
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

  1. Use a `TypedDict` with explicit type annotations per key for stronger static checking
  2. 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

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Dictionaries & sets

Related tutorials and quizzes for this topic.