Manage application settings with ease using runenv
, a lightweight tool inspired by The Twelve-Factor App methodology for configuration through environment variables.
runenv
provides:
- A CLI for language-agnostic
.env
profile execution - A Python API for programmatic
.env
loading
“Store config in the environment” — 12factor.net/config
Section | Status |
---|---|
CI/CD | |
PyPI | |
Python | |
Style | |
License | |
Docs | CHANGELOG.md |
- 🚀 CLI-First: Use
.env
files across any language or platform. - 🐍 Python-native API: Load and transform environment settings inside Python.
- ⚙️ Multiple Profiles: Switch easily between
.env.dev
,.env.prod
, etc. - ⚙️ Multiple Formats: Use plain
.env
,.env.json
,.env.toml
, or.env.yaml
- ⚙️ Autodetect Env File: Looking for
.env
,.env.json
,.env.toml
, and.env.yaml
- 🧩 Framework-Friendly: Works well with Django, Flask, FastAPI, and more.
pip install runenv
pip install runenv[toml] # if you want to use .env.toml in python < 3.11
pip install runenv[yaml] # if you want to use .env.yaml
Run any command with a specified environment:
runenv run --env-file .env.dev -- python manage.py runserver
runenv run --env-file .env.prod -- uvicorn app:app --host 0.0.0.0
runenv list [--env-file .env] # view parsed variables
runenv lint [--env-file .env] # check common errors in env file
Note: The
load_env
will not parse env_file if therunenv
CLI was used, unless youforce=True
it.
from runenv import load_env
load_env() # loads .env
load_env(
env_file=".env.dev", # file to load - will be autodetected if not passed
prefix='APP_', # load only APP_.* variables from file
strip_prefix=True, # strip ^ prefix when loading variables
force=True, # load env_file even if the `runvenv` CLI was used
search_parent=1, # look for env_file in current dir and its 1 parent dirs
require_env_file=False # raise error if env file is missing, otherwise just ignore
)
from runenv import create_env
config = create_env() # parse .env content into dictionary
config = create_env(
env_file=".env.dev", # file to load - will be autodetected if not passed
prefix='APP_', # parse only APP_.* variables from file
strip_prefix=True, # strip ^ prefix when parsing variables
search_parent=1, # look for env_file in current dir and its 1 parent dirs
)
print(config)
Options include:
- Filtering by prefix
- Automatic prefix stripping
- Searching parent directories
Use separate .env
files per environment:
runenv .env.dev flask run
runenv .env.staging python main.py
runenv .env.production uvicorn app.main:app
Recommended structure:
.env.dev
.env.test
.env.staging
.env.production
Note: If you're using
runenv .env [./manage.py, ...]
CLI then you do not need change your code. Use these integrations only if you're using Python API.
# manage.py or wsgi.py
from runenv import load_env
load_env(".env")
from flask import Flask
from runenv import load_env
load_env(".env")
app = Flask(__name__)
from fastapi import FastAPI
from runenv import load_env
load_env(".env")
app = FastAPI()
# Basic
DEBUG=1
PORT=8000
# Nested variable
HOST=localhost
URL=http://${HOST}:${PORT}
# Quotes and comments
EMAIL="admin@example.com" # Inline comment
SECRET='s3cr3t'
- python-dotenv – Python-focused, lacks CLI tool
- envdir – Directory-based env manager
- dotenv-linter – Linter for
.env
files
With runenv
, you get portable, scalable, and explicit configuration management that aligns with modern deployment standards. Ideal for CLI usage, Python projects, and multi-environment pipelines.