Python

Django

Load Envless variables in Django settings.py with envless-env, read them typed, and hand client variables to templates with the envless context processor.

Django reads its configuration once, when it imports your settings module, so that is where the load belongs. Import envless_env.register at the top of settings.py and read every value through env.

python
import envless_env.register  # noqa: F401
from envless_env.server import env, optional

SECRET_KEY = str(env.DJANGO_SECRET_KEY)
DEBUG = env.DEBUG is True
ALLOWED_HOSTS = str(env.ALLOWED_HOSTS).split(',')

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'HOST': env.DATABASE_HOST,
        'NAME': env.DATABASE_NAME,
        'USER': env.DATABASE_USER,
        'PASSWORD': env.DATABASE_PASSWORD,
    }
}

SENTRY_DSN = optional.SENTRY_DSN

Give DEBUG the type boolean in Envless. Typed string, it reads 'false', and bool('false') is True, so env.DEBUG is True keeps debug off unless Envless says otherwise.

manage.py, wsgi.py, asgi.py, Celery workers and the test runner all import settings.py first, so every entry point loads before anything else runs. The loaded values are also in os.environ, so a helper such as dj-database-url that reads DATABASE_URL from the environment works unchanged.

The development server's autoreloader imports settings in two processes. The second one reads the ciphertext cache the first one wrote, so with ENVLESS_KEY it makes no request at all.

Client variables in templates

Add the context processor and every variable marked client in Envless is available to your templates as envless. Server variables are not in it, so a template can never print one.

python
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.request',
                'envless_env.django.context_processor',
            ],
        },
    }
]
html
<script>
    window.API_URL = '{{ envless.PUBLIC_API_URL|escapejs }}';
</script>

Tests

Django's test runner imports settings like any other entry point, so tests load from Envless too. Point a CI job at a test environment with its own machine key, or run the suite under envless run --env test -- python manage.py test, which needs no key in the process at all. A value your code reads through env while handling a request can be layered for one test with override(). A value copied into a setting at import is a Django setting by then, so change it with Django's own override_settings.