How to Load envrc Files in Python

Parse and apply direnv-style envrc files to the current environment, with proper handling of variables, comments, and quotes.

Easy Python 3.6+ Aug 9, 2026 Modern tooling 15 views 0 copies

Python code

43 lines
Python 3.6+
import os
import tempfile
from pathlib import Path
from unittest.mock import patch


def load_envrc(envrc_path):
    """Parse an envrc-style file and apply it to the current environment."""
    env_changes = {}
    with open(envrc_path, "r") as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith("#") and "=" in line:
                key, value = line.split("=", 1)
                env_changes[key.strip()] = value.strip().strip('"\'')
    return env_changes


def apply_env(env_changes):
    """Apply parsed env changes to os.environ."""
    for key, value in env_changes.items():
        os.environ[key] = value


def main():
    with tempfile.NamedTemporaryFile(mode="w", suffix=".envrc", delete=False) as tmp:
        tmp.write('export PROJECT_NAME="demo-app"\nexport DEBUG=true\n')
        envrc_path = tmp.name

    try:
        changes = load_envrc(envrc_path)
        apply_env(changes)
        assert os.environ["PROJECT_NAME"] == "demo-app"
        assert os.environ["DEBUG"] == "true"
        print("Environment loaded successfully:")
        print(f"PROJECT_NAME={os.environ['PROJECT_NAME']}")
        print(f"DEBUG={os.environ['DEBUG']}")
    finally:
        Path(envrc_path).unlink()


if __name__ == "__main__":
    main()

Output

stdout
Environment loaded successfully:
PROJECT_NAME=demo-app
DEBUG=true

How it works

The load_envrc function reads each line from the envrc file, strips whitespace, and skips comments and empty lines. For lines containing =, it splits on the first = and safely strips quotes from values (both single and double). The apply_env function then writes the parsed key-value pairs into os.environ.

A temporary file is created with tempfile.NamedTemporaryFile to simulate an envrc file, then removed in a finally block so cleanup happens even if something fails. This pattern mimics how tools like direnv process environment configuration files.

Note that this only handles simple export KEY=value lines — it does not expand shell variables or execute bash commands, which means it's a lightweight alternative to full direnv compatibility.

Common mistakes

  • Forgetting to strip quotes from values, leaving literal quotes in environment variables
  • Not handling lines without `=` that would crash with a ValueError
  • Skipping the `finally` cleanup block, leaving temp files behind
  • Assuming only `export` statements matter, but the parser includes all `key=value` lines

Variations

  1. Use python-dotenv's `load_dotenv` function for .env file support
  2. Extend to handle `export KEY=value` specifically vs bare `KEY=value`

Real-world use cases

  • Applying local development secrets in a CI pipeline without hardcoding credentials.
  • Switching environment-specific configuration when deploying microservices to different clusters.
  • Parsing developer-defined env files before running tests to ensure consistent setup across machines.

Sponsored

Run this sample

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

Open editor

More from Modern tooling

Related tutorials and quizzes for this topic.