Files
2025-11-29 18:49:58 +08:00

20 KiB

title, library_name, pypi_package, category, python_compatibility, last_updated, official_docs, official_repository, maintenance_status
title library_name pypi_package category python_compatibility last_updated official_docs official_repository maintenance_status
python-dotenv: Environment Variable Management for Python python-dotenv python-dotenv configuration 3.9+ 2025-11-02 https://github.com/theskumar/python-dotenv#readme https://github.com/theskumar/python-dotenv active

python-dotenv: Environment Variable Management for Python

Core Purpose

python-dotenv reads key-value pairs from a .env file and can set them as environment variables. It helps in the development of applications following the 12-factor app principles.

Problem Solved

The model must state that python-dotenv addresses development environment configuration challenges by enabling loading of environment variables from .env files, eliminating the need to manually set environment variables before running applications during local development.

Without python-dotenv, developers would need to:

  • Manually export environment variables in shell sessions before running applications
  • Hardcode configuration values in source code (security risk)
  • Write custom file-reading and environment-setting code (reinventing the wheel)
  • Maintain separate shell scripts for different environments

12-Factor App Methodology

The model must verify that python-dotenv implements the configuration principle from the 12-factor methodology: "Store config in the environment." This separation of configuration from code enables:

  • Different configurations per environment (development, staging, production)
  • No credentials in version control
  • Configuration changes without code deployment
  • Portable code across environments

Official Information

The model must cite the following verified sources:

Python Version Compatibility

The model must state the following compatibility information from setup.py:

Python Version Support Status Notes
3.9 Supported Minimum version
3.10 Supported Full support
3.11 Supported Full support
3.12 Supported Full support
3.13 Supported Latest version
3.14 Expected No breaking changes expected
PyPy Supported PyPy implementation supported

The model must verify that python-dotenv has no version-specific features and works identically across supported Python versions.

Installation

# Basic installation
pip install python-dotenv

# With CLI support
pip install "python-dotenv[cli]"

Usage Examples

Basic .env File Loading

The model must demonstrate the standard pattern from official documentation:

# app.py
from dotenv import load_dotenv
import os

# Load variables from .env file
load_dotenv()

# Access environment variables
database_url = os.getenv('DATABASE_URL')
api_key = os.getenv('API_KEY')
debug = os.getenv('DEBUG', 'False') == 'True'

Corresponding .env file:

# .env
DATABASE_URL=postgresql://localhost/mydb
API_KEY=secret_key_12345
DEBUG=True

Advanced Configuration Management

The model must show the dictionary-based pattern for merging multiple configuration sources:

from dotenv import dotenv_values
import os

config = {
    **dotenv_values(".env.shared"),  # load shared development variables
    **dotenv_values(".env.secret"),  # load sensitive variables
    **os.environ,                    # override with environment variables
}

# Access with priority: os.environ > .env.secret > .env.shared
database_url = config['DATABASE_URL']

Multi-Environment Loading

The model must demonstrate environment-specific configuration loading:

from dotenv import load_dotenv, find_dotenv
import os

# Determine environment
env = os.getenv('ENVIRONMENT', 'development')
dotenv_path = f'.env.{env}'

# Load environment-specific file
load_dotenv(dotenv_path=dotenv_path)

# .env.development, .env.staging, .env.production

Variable Expansion with Defaults

The model must show POSIX-style variable interpolation:

# .env with variable expansion
DOMAIN=example.org
EMAIL=admin@${DOMAIN}
API_URL=https://${DOMAIN}/api

# Default values for missing variables
DATABASE_HOST=${DB_HOST:-localhost}
DATABASE_PORT=${DB_PORT:-5432}
REDIS_URL=redis://${REDIS_HOST:-localhost}:${REDIS_PORT:-6379}

IPython/Jupyter Integration

The model must demonstrate the IPython extension usage:

# In Jupyter notebook
%load_ext dotenv
%dotenv

# Load specific file
%dotenv /path/to/.env.local

# Override existing variables
%dotenv -o

# Verbose output
%dotenv -v

CLI Usage

The model must show command-line interface examples:

# Set variables
dotenv set DATABASE_URL "postgresql://localhost/mydb"
dotenv set API_KEY "secret_key_123"

# Get specific value
dotenv get API_KEY

# List all variables
dotenv list

# List as JSON
dotenv list --format=json

# Run command with loaded environment
dotenv run -- python manage.py runserver
dotenv run -- pytest tests/

Integration Patterns

Django Integration

The model must demonstrate Django integration in manage.py and settings.py:

# manage.py
import os
import sys
from dotenv import load_dotenv

if __name__ == '__main__':
    # Load .env before Django imports settings
    load_dotenv()

    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
    from django.core.management import execute_from_command_line
    execute_from_command_line(sys.argv)
# settings.py
import os
from dotenv import load_dotenv

load_dotenv()

SECRET_KEY = os.getenv('SECRET_KEY')
DEBUG = os.getenv('DEBUG', 'False') == 'True'
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.getenv('DB_NAME'),
        'USER': os.getenv('DB_USER'),
        'PASSWORD': os.getenv('DB_PASSWORD'),
        'HOST': os.getenv('DB_HOST', 'localhost'),
        'PORT': os.getenv('DB_PORT', '5432'),
    }
}

Flask Integration

The model must show Flask application factory pattern:

# app.py or __init__.py
from flask import Flask
from dotenv import load_dotenv
import os

load_dotenv()

def create_app():
    app = Flask(__name__)

    app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
    app.config['DATABASE_URI'] = os.getenv('DATABASE_URL')
    app.config['DEBUG'] = os.getenv('FLASK_DEBUG', 'False') == 'True'

    return app

if __name__ == '__main__':
    app = create_app()
    app.run()

FastAPI Integration

The model must demonstrate Pydantic Settings integration:

# config.py
from pydantic_settings import BaseSettings
from dotenv import load_dotenv

load_dotenv()

class Settings(BaseSettings):
    database_url: str
    api_key: str
    debug: bool = False

    class Config:
        env_file = '.env'
        env_file_encoding = 'utf-8'

settings = Settings()
# main.py
from fastapi import FastAPI
from config import settings

app = FastAPI(debug=settings.debug)

@app.get("/")
def read_root():
    return {"database": settings.database_url}

Docker and Container Integration

The model must show Docker integration with environment variable precedence:

# Dockerfile
FROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

# .env file is included in image for defaults
# But container env vars take precedence
CMD ["python", "app.py"]
# app.py with override=False (default)
from dotenv import load_dotenv
import os

# Precedence: Docker env vars > .env file
load_dotenv(override=False)

# This respects container-injected variables
database_url = os.getenv('DATABASE_URL')
# docker-compose.yml
services:
  app:
    build: .
    environment:
      - DATABASE_URL=postgresql://db/production
      - DEBUG=False
    # Container env vars override .env file

Environment Variable Precedence

The model must explain the precedence rules:

With load_dotenv(override=False) (default):

  1. Existing environment variables (highest priority)
  2. Variables from .env file
  3. Default values in code

With load_dotenv(override=True):

  1. Variables from .env file (highest priority)
  2. Existing environment variables
  3. Default values in code

Real-World Examples

The model must cite verified GitHub repositories using python-dotenv:

  1. theskumar/python-dotenv (8,443 stars)

    • Source repository with comprehensive examples
    • @github:theskumar/python-dotenv
  2. daveebbelaar/langchain-experiments (1,104 stars)

    • LangChain AI applications with environment configuration
    • @github:daveebbelaar/langchain-experiments
  3. iam-veeramalla/python-for-devops (3,994 stars)

    • DevOps automation scripts using dotenv
    • @github:iam-veeramalla/python-for-devops
  4. AgentOps-AI/agentops (4,978 stars)

    • AI agent monitoring with environment configuration
    • @github:AgentOps-AI/agentops

Common pattern observed across repositories:

from dotenv import load_dotenv
import os

load_dotenv()
api_key = os.getenv('API_KEY')

When to Use python-dotenv

The model must create a decision matrix based on verified use cases:

Use python-dotenv when

  • Local Development: Managing configuration during development where setting environment variables manually is impractical
  • Multiple Developers: Team needs consistent local environment setup without sharing credentials in version control
  • Multiple Environments: Application runs in development, staging, production with different configurations
  • Third-Party Services: Application integrates with APIs requiring secret keys
  • Framework Integration: Using Django, Flask, FastAPI where .env files are standard practice
  • CI/CD Pipelines: Testing with different configurations in continuous integration
  • Jupyter Notebooks: Interactive development requiring API keys and configuration
  • Docker Development: Local development with Docker where .env provides defaults but containers can override
  • 12-Factor Applications: Following cloud-native application design principles

The model must verify these scenarios from real-world usage patterns in GitHub repositories.

When NOT to Use python-dotenv

The model must state limitations and alternative approaches:

Do NOT use python-dotenv when

  1. Production Secrets Management:

    • Problem: .env files are plaintext and not encrypted
    • Alternative: Use HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager
    • Reason: Production secrets require encryption, rotation, audit logging, and access control
  2. Native Environment Variables Sufficient:

    • Problem: Adds unnecessary dependency for simple cases
    • Alternative: Use os.environ directly
    • Reason: If environment already provides all variables, loading from file is redundant
  3. Compiled Applications:

    • Problem: .env files must be distributed with application
    • Alternative: Bake configuration into build or use external configuration service
    • Reason: Compiled/packaged applications should not rely on external files
  4. Read-Only Filesystems:

    • Problem: Cannot read .env file from disk
    • Alternative: Use environment variables directly
    • Reason: Some container runtimes and serverless platforms use read-only filesystems
  5. Complex Configuration Schemas:

    • Problem: .env files only support string key-value pairs
    • Alternative: Use YAML, TOML, JSON with schema validation
    • Reason: Complex nested configuration requires structured formats
  6. Dynamic Configuration:

    • Problem: .env files are loaded once at startup
    • Alternative: Use configuration management service (Consul, etcd)
    • Reason: Applications requiring runtime configuration updates need dynamic sources
  7. Distributed Systems Coordination:

    • Problem: Each service would need its own .env file
    • Alternative: Use centralized configuration service
    • Reason: Distributed systems need synchronized configuration updates

Decision Guidance Matrix

The model must provide deterministic decision criteria:

┌─────────────────────────────────┬──────────────────┬───────────────────┐
│ Scenario                        │ Use dotenv?      │ Alternative       │
├─────────────────────────────────┼──────────────────┼───────────────────┤
│ Local development               │ YES              │ N/A               │
│ Development with team           │ YES              │ N/A               │
│ CI/CD testing                   │ YES              │ N/A               │
│ Docker local development        │ YES              │ N/A               │
│ Jupyter notebooks               │ YES              │ N/A               │
│ Production deployments          │ NO               │ Secrets manager   │
│ Production secrets storage      │ NO               │ Vault/KMS         │
│ Simple scripts (no secrets)     │ NO               │ os.environ        │
│ Complex nested config           │ NO               │ YAML/TOML         │
│ Dynamic config updates          │ NO               │ Consul/etcd       │
│ Serverless functions            │ MAYBE            │ Cloud env vars    │
│ Distributed systems             │ NO               │ Config service    │
└─────────────────────────────────┴──────────────────┴───────────────────┘

File Format Reference

The model must document the supported .env syntax from official documentation:

# Basic key-value pairs
API_KEY=secret123
PORT=8080
DEBUG=true

# Quoted values
DATABASE_URL='postgresql://localhost/mydb'
APP_NAME="My Application"

# Multiline values (quoted)
CERTIFICATE="-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKL0UG+mRbzMMA0GCSqGSIb3DQEBCwUA
-----END CERTIFICATE-----"

# Comments
# This is a comment
LOG_LEVEL=INFO  # Inline comment

# Export directive (optional, no effect on parsing)
export PATH_EXTENSION=/usr/local/bin

# Variable expansion with POSIX syntax
DOMAIN=example.org
EMAIL=admin@${DOMAIN}
API_URL=https://${DOMAIN}/api

# Default values for missing variables
DATABASE_HOST=${DB_HOST:-localhost}
DATABASE_PORT=${DB_PORT:-5432}

# Escape sequences in double quotes
MESSAGE="Line 1\nLine 2\nLine 3"
TABS="Column1\tColumn2\tColumn3"
QUOTE="He said \"Hello\""

# Escape sequences in single quotes (only \\ and \')
PATH='C:\\Users\\Admin'
NAME='O\'Brien'

# Empty values
EMPTY_STRING=
EMPTY_VAR

# Spaces around = are ignored
REDIS_URL = redis://localhost:6379

Supported escape sequences:

  • Double quotes: \\, \', \", \a, \b, \f, \n, \r, \t, \v
  • Single quotes: \\, \'

API Reference Summary

The model must list core functions from verified documentation:

Function Purpose Returns Common Use
load_dotenv(dotenv_path=None, stream=None, verbose=False, override=False, interpolate=True, encoding=None) Load .env into os.environ bool (success) Application startup
dotenv_values(dotenv_path=None, stream=None, verbose=False, interpolate=True, encoding=None) Parse .env to dict dict Config merging
find_dotenv(filename='.env', raise_error_if_not_found=False, usecwd=False) Search for .env file str (path) Auto-discovery
get_key(dotenv_path, key_to_get, encoding=None) Get single value str or None Read specific key
set_key(dotenv_path, key_to_set, value_to_set, quote_mode='always', export=False, encoding=None) Write key-value tuple Programmatic updates
unset_key(dotenv_path, key_to_unset, encoding=None) Remove key tuple Cleanup

The model must cite verified alternatives from GitHub repository:

  • django-environ: Django-specific with type coercion (@github:joke2k/django-environ)
  • python-decouple: Strict separation with type casting (@github:HBNetwork/python-decouple)
  • environs: Marshmallow-based validation (@github:sloria/environs)
  • dynaconf: Multi-format with layered settings (@github:rochacbruno/dynaconf)
  • pydantic-settings: Type-safe with Pydantic models (recommended for FastAPI)

The model must state that python-dotenv is the most widely adopted for simple .env loading.

Best Practices

The model must recommend the following verified patterns:

  1. Never commit .env to version control

    # .gitignore
    .env
    .env.local
    .env.*.local
    
  2. Provide .env.example for documentation

    # .env.example
    DATABASE_URL=postgresql://localhost/mydb
    API_KEY=your_api_key_here
    DEBUG=False
    
  3. Load at application entry point

    # Load once at startup, not in modules
    if __name__ == '__main__':
        from dotenv import load_dotenv
        load_dotenv()
        main()
    
  4. Use override=False for production precedence

    # Let container/server env vars override .env
    load_dotenv(override=False)
    
  5. Validate required variables

    from dotenv import load_dotenv
    import os
    
    load_dotenv()
    
    required_vars = ['DATABASE_URL', 'API_KEY', 'SECRET_KEY']
    missing = [var for var in required_vars if not os.getenv(var)]
    
    if missing:
        raise ValueError(f"Missing required environment variables: {missing}")
    
  6. Use type conversion explicitly

    # python-dotenv returns strings only
    DEBUG = os.getenv('DEBUG', 'False').lower() in ('true', '1', 'yes')
    PORT = int(os.getenv('PORT', '8000'))
    TIMEOUT = float(os.getenv('TIMEOUT', '30.0'))
    

Common Pitfalls

The model must warn about verified issues:

  1. Strings only: All values are strings, must convert to int/bool/float manually
  2. Load timing: Must load before importing modules that use environment variables
  3. Override behavior: Default override=False means existing env vars take precedence
  4. Variable expansion: Disabled with interpolate=False, check if this is needed
  5. Production secrets: Never use .env files for production secret storage

Verification

The model must self-check the following criteria:

  • All sections present and complete
  • Code examples tested against python-dotenv 1.1.1 documentation
  • Sources cited with @ references
  • Decision matrix provides deterministic guidance
  • No claims about functionality without documentation verification
  • Python version compatibility verified from setup.py
  • Real-world examples from GitHub repositories with star counts
  • Integration patterns match framework documentation
  • Security warnings included for production usage

Summary

The model must state that python-dotenv is the standard Python library for loading environment variables from .env files during development. It implements 12-factor app configuration principles, supports Python 3.9-3.13, and integrates with Django, Flask, FastAPI, and other frameworks. The library is suitable for development and testing environments but should not be used for production secrets management. For production deployments, environment variables should be injected by container orchestration or cloud platforms, with secrets managed by dedicated secrets management services.