django-environ
Configure Django apps with twelve-factor environment variables and URL-based settings.
Repository Health
Technical Analysis
django-environ brings twelve-factor configuration to Django projects by letting you define settings as environment variables instead of hardcoded Python. It reads variables from the OS environment or a .env file, casts them to the right Python type (bool, int, float, list, tuple, dict, JSON), and exposes convenience accessors like env.db(), env.cache(), env.email(), env.search(), and env.channels() that parse a single connection URL into the nested dict Django’s DATABASES, CACHES, EMAIL_* and CHANNEL_LAYERS settings expect.
Beyond simple variable reading, the library supports Docker-style _FILE secret injection through FileAwareEnv, a Path helper for building filesystem paths relative to the project root, and URL parsers for a wide range of database engines (Postgres, MySQL, SQLite, Oracle, Redshift, and more), cache backends (Redis, Memcached, filesystem), email backends, and search engines (Elasticsearch, Solr, Whoosh, Xapian).
What You Get
- Typed environment variable accessors — env.str(), env.bool(), env.int(), env.float(), env.list(), env.tuple(), env.dict(), and env.json() cast raw environment strings to native Python types with optional defaults.
- URL-based settings parsers — db_url(), cache_url(), email_url(), search_url(), and channels_url() turn a single connection string into the nested dict Django expects for DATABASES, CACHES, EMAIL_* and CHANNEL_LAYERS.
- .env file loading via Env.read_env(), including comment parsing, quoted-value handling, and an optional overwrite of existing OS environment values.
- FileAwareEnv and FileAwareMapping for Docker/Kubernetes-style secrets, reading a value from a file path referenced by a <VAR>_FILE environment variable.
- A Path helper class for building filesystem paths relative to BASE_DIR with operator overloading (path / ‘subdir’).
Common Use Cases
- Configuring DATABASES and CACHES from a single DATABASE_URL / REDIS_URL environment variable across Heroku, Docker, and Kubernetes deployments.
- Keeping secrets like SECRET_KEY and API tokens out of source control by loading them from a .env file in local development and real environment variables in production.
- Injecting secrets from Docker/Kubernetes secret files using the _FILE convention instead of plaintext environment variables.
- Casting comma-separated or JSON-formatted environment variables into Python lists, tuples, and dicts for settings like ALLOWED_HOSTS or CORS_ORIGIN_WHITELIST.
Under The Hood
Architecture The library is a flat, single-module design centered on environ/environ.py: a large Env class holds ecosystem-wide scheme dictionaries (DB_SCHEMES, CACHE_SCHEMES, EMAIL_SCHEMES, SEARCH_SCHEMES, CHANNELS_SCHEMES) that map URL prefixes to Django backend import paths, with every typed accessor (str, bool, int, float, json, list, tuple, dict, url) funneling through a shared get_value()/parse_value() pipeline so casting logic lives in one place. URL-to-settings conversion is handled by classmethods (db_url_config, cache_url_config, email_url_config, search_url_config, channels_url_config) that parse a connection string against the scheme tables and assemble the nested dict Django expects, delegating platform-specific quirks (such as choosing the Redis cache driver by Django version) to compat.py. Docker/Kubernetes secret support is layered in separately via fileaware_mapping.py’s FileAwareMapping, a MutableMapping wrapping os.environ that FileAwareEnv swaps in, and a standalone Path class at the bottom of the same file provides operator-overloaded filesystem path construction — three loosely coupled concerns living in one large module rather than separate packages, so a change to the core casting pipeline ripples through every accessor and every *_url_config classmethod that depends on it.
Tech Stack A pure-Python package targeting Python 3.10–3.14 with a single runtime dependency, django>=2.2, and compatibility maintained through Django 6.0 via compat.py’s version-gated driver selection (built-in redis cache backend on Django 4+, django_redis if installed, else the legacy redis_cache package). Build tooling is setuptools with setuptools.build_meta and a classic setup.py, and a tox.ini matrix runs unit tests, coverage, lint, mypy type-checking, and Sphinx documentation builds across every supported Python/Django combination plus PyPy. Docs are built with Sphinx and the furo theme and published via Read the Docs.
Code Quality An extensive test suite spans test_env.py, test_db.py, test_cache.py, test_email.py, test_channels.py, test_search.py, test_schema.py, test_path.py, test_fileaware.py, and test_utils.py, using pytest with heavy parametrized tables — for example dozens of .env-parsing edge cases combining comment styles, quoting, and escape sequences — plus custom fixtures and assertion helpers rather than ad hoc checks. Error handling is explicit: missing required variables and malformed casts raise Django’s ImproperlyConfigured instead of failing silently, and a DefaultValueWarning surfaces silent-default usage when enabled. Public method signatures carry type hints checked by mypy, and dedicated GitHub Actions workflows cover linting/formatting, CodeQL static analysis, and a CI matrix across Python and Django versions plus PyPy that runs on every push, pull request, and a daily cron.
API Design The public API optimizes for one-liner settings: env.db() replaces a multi-key DATABASES dict with a single URL string, and the same pattern repeats across cache(), email(), search(), and channels(), so adopting the library changes only a handful of settings.py lines. Declaring a scheme up front (Env(VAR=(type, default))) lets a project front-load its variable contract instead of scattering os.environ.get() calls with inline defaults, and the docs site walks through nearly every accessor with copy-pasteable examples. Method naming is consistent across typed accessors, and boilerplate is minimal to get started, though the underlying module packs typed-accessor, URL-parsing, and path-utility responsibilities into one very large class — more a maintainer-facing cost than an end-user one.
Used by 4 apps in this directory
Flagsmith
Developer Tools · Devops · Ab Testing Experimentation
Open-source feature flagging, remote config, and A/B/multivariate testing platform for web, mobile, and server-side apps — self-host or use the hosted SaaS.
Horilla
Human Resources · ERP
Open-source HRMS covering recruitment, attendance, payroll, and biometrics in one self-hosted Django application.
Label Studio
AI Development · Data Engineering
Label Studio is an open-source, multi-type data labeling platform that lets teams annotate images, text, audio, video, and time series data with a configurable XML-based UI and export annotations in formats ready for any ML framework.
SWIRL
Search · Databases · Data Engineering
Federated AI search and RAG across 100+ enterprise sources—no data extraction, no vector database required.