Skip to main content

Smart .env loader with configurable file location for Python projects.

Project description

dotenv-loader

Smart and flexible .env loader for Python applications.

📖 Overview

dotenv-loader provides a flexible yet straightforward way to load environment variables from .env files, tailored specifically for Python applications, including Django, Flask, Celery, FastCGI, WSGI, CLI tools, and more. It supports hierarchical configuration, making it extremely convenient to manage multiple environments (development, testing, production) without manually switching .env files or cluttering code with environment-specific logic.

🚀 Historical Context

Managing environment-specific settings is crucial in modern software development. Standard solutions like python-dotenv simplify loading variables from .env files but lack flexible mechanisms for dynamically switching configurations across multiple deployment environments or nested project structures.

dotenv-loader was created specifically to solve these practical challenges:

  • Easily switch environments without changing code or manually managing environment variables.
  • Support flexible directory structures (such as monorepos or Django sub-applications).
  • Enable clear separation of environment-specific configurations, improving clarity and reducing human error.

✨ Features

  • Hierarchical and prioritized .env file search: dotenv-loader follows a clear and intuitive priority order:

    1. Explicit path provided via DOTENV environment variable.
    2. Configuration directory (DOTCONFIG_ROOT) with customizable subdirectories per project and environment stage (DOTSTAGE).
    3. Automatic fallback to .env file located directly in the project root.
  • Dynamic project and stage selection: Quickly switch configurations by setting the DOTPROJECT and DOTSTAGE environment variables, allowing effortless toggling between multiple environments or projects.

  • Customizable file names: Use custom .env filenames to further separate and manage your configurations.

🔒 Security and Best Practices

Storing .env files separately in a dedicated configuration directory (DOTCONFIG_ROOT) outside your project source tree is a secure and recommended best practice. This approach significantly reduces the risk of accidentally leaking sensitive information (such as API keys, database credentials, etc.) during backups, version control operations, or file transfers. By keeping secrets separate from your codebase, dotenv-loader helps enforce a clear boundary between configuration and code, enhancing security and compliance.

⚙️ Installation

pip install dotenv-loader

🛠 Usage

Basic Usage

By default, dotenv-loader automatically identifies the .env file from the current project's root directory:

import dotenv_loader

dotenv_loader.load_env()

Advanced Usage

import dotenv_loader

# Load environment with custom default settings 
# Each parameter is optional and first four can be overridden by environment variables:
dotenv_loader.load_env(
    project='mega-project',          # - explicitly set project name
    stage='production',              # - explicitly set stage name
    dotenv='./dir/.env.test'         # - explicitly set .env file 
    config_root='~/custom-configs',  # - custom config directory
    steps_to_project_root=1,         # - how many directories up to look for project root
    default_env_file='env',          # - change the default '.env' name to you name
    override=True                    # - whether to overwrite existing environment variables 
                                     #   already defined in os.environ. Use False to preserve 
                                     #   values already present (e.g. from OS or CI/CD), or 
                                     #   True to always prefer .env contents.
)

Environment Variables

You can configure dotenv-loader behavior directly from environment variables:

  • DOTENV: Specify exact path to the .env file:
DOTENV=/path/to/custom.env python manage.py
  • DOTPROJECT: Quickly switch project environments:
DOTPROJECT=test python manage.py  # loads ~/.config/python-projects/test/.env
  • DOTSTAGE: Switch configuration stages within a project (prod, staging, test):
DOTSTAGE=staging python manage.py  # loads ~/.config/python-projects/myproject/.env.staging
  • DOTCONFIG_ROOT: Change the root directory for configuration files:
DOTCONFIG_ROOT=~/myconfigs python manage.py

Typical Directory Structure

~/.config/python-projects/
└── myproject/
    ├── .env          # Default configuration (typically a symlink from .env.prod)
    ├── .env.prod     # Production configuration. Explicit usage: DOTSTAGE=prod python manage.py
    ├── .env.staging  # Staging configuration. Explicit usage: DOTSTAGE=staging python manage.py
    └── .env.test     # Testing configuration. Explicit usage: DOTSTAGE=test python manage.py

myproject/
└── manage.py  # By default, loads ~/.config/python-projects/myproject/.env

🧽 .env Resolution Rules and Precedence

dotenv-loader uses a deterministic and secure resolution strategy when selecting the appropriate .env file to load. The logic ensures maximum flexibility while maintaining clarity and safety.

Resolution Rules

  1. Environment Variables Take Precedence
    The following environment variables have higher priority than the corresponding load_env() parameters:

    • DOTENV overrides dotenv
    • DOTPROJECT overrides project
    • DOTSTAGE overrides stage
    • DOTCONFIG_ROOT overrides config_root
  2. Relative Paths Are Context-Aware

    • Paths defined in environment variables (e.g., DOTENV, DOTCONFIG_ROOT) are resolved relative to the OS working directory (PWD, as seen with pwd in a terminal).
    • Paths provided as function arguments (dotenv, config_root) are resolved relative to the script that directly invoked load_env(), adjusted by steps_to_project_root.
      For example, if manage.py is located at ~/projects/proj1/app/manage.py and called with load_env(steps_to_project_root=2), then the project_root is assumed to be ~/projects/proj1, and relative paths are resolved from that base.
  3. Project and Stage Names Must Be Basenames
    Both DOTPROJECT / project and DOTSTAGE / stage must not contain slashes (/). They are always interpreted as directory/file basenames and resolved with Path(name).name.

  4. Highest Priority: Explicit .env Path
    If either DOTENV or dotenv is defined, it is used directly. All other resolution rules are skipped.

  5. Project Name Determination
    The project name is resolved in the following order:

    • From DOTPROJECT or project (if defined)
    • Otherwise, it falls back to the name of the final directory in the project_root path
  6. .env Filename Construction
    The target filename is built using the format:
    "[default_env_file][[.]STAGE]",
    where default_env_file is .env by default, and STAGE is the value of DOTSTAGE or stage.

  7. Primary Search Location
    If no explicit .env is provided, dotenv-loader first checks the following path:
    [DOTCONFIG_ROOT | config_root] / [DOTPROJECT | project] / [default_env_file][.stage]

  8. Fallback Location
    If the file is not found in the config directory, it will search inside the computed project root:
    [project_root] / [default_env_file][.stage]

  9. Error Handling
    If no .env file is found in any of the candidate locations, a FileNotFoundError is raised, detailing all paths that were attempted.

🎯 Use Cases

dotenv-loader is especially useful when:

  • Deploying applications to multiple environments (development, testing, staging, production).
  • Managing complex directory structures (monorepos or multi-app Django projects).
  • Simplifying CI/CD workflows by dynamically selecting environment configurations.

📜 License

MIT License

🤝 Contributing

We welcome contributions from the community! Please see CONTRIBUTING.md for details on how to get started.

🤖 Acknowledgments

This project was created in collaboration with ChatGPT (OpenAI), utilizing the GPT-4o, GPT-4.5, and GPT-3 models.

📅 Changelog

For detailed release notes, see CHANGELOG.md.


By clearly managing your environment variables and enabling dynamic configuration switching, dotenv-loader helps you streamline your deployment and development workflows, reduce errors, and maintain cleaner, more maintainable code.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dotenv_loader-1.0.1.tar.gz (10.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dotenv_loader-1.0.1-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file dotenv_loader-1.0.1.tar.gz.

File metadata

  • Download URL: dotenv_loader-1.0.1.tar.gz
  • Upload date:
  • Size: 10.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for dotenv_loader-1.0.1.tar.gz
Algorithm Hash digest
SHA256 f32f6e3754d620a18a078ce22f701dffe5ff95de8883ece6c338cd158817ac00
MD5 0262b8f812897bcc8afa225ba91db57d
BLAKE2b-256 8cff69ff7fdfa5c69e4fe924e322a43fcac1547007f8b27b0dd2a69e51f55d04

See more details on using hashes here.

File details

Details for the file dotenv_loader-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: dotenv_loader-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for dotenv_loader-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9b198f2afa8213f6d87a0bd930db73269a01ef562ed5bb5951fcad8a1ff7e1b4
MD5 6e93d6d22d9c592e40c731682f541462
BLAKE2b-256 4016138304609c3b18e508e7d16fe535f1a0f0c523adda356dd4ad50bdde4f25

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page