Python SDK

Load secrets directly into a Python application at startup.

Python SDK

Load secrets directly into your Python application at startup. One-liner setup or fine-grained control with the fluent builder.

Install

uv add envilder
# or
pip install envilder

Quick start: one-liner

Load secrets from a map file and inject them into the environment:

from envilder import Envilder

Envilder.load('envilder.json')

Environment-based loading

Recommended for multi-environment apps. Map each environment to its own secrets file:

from envilder import Envilder
import os

env = os.getenv('APP_ENV', 'development')

Envilder.load(env, {
    'production': 'prod-secrets.json',
    'development': 'dev-secrets.json',
    'test': None,
})

Resolve without injecting

Get secrets as a dictionary without modifying the environment:

secrets = Envilder.resolve_file('envilder.json')

Fluent builder with overrides

Override provider settings programmatically using the fluent API:

from envilder import Envilder, SecretProviderType

secrets = (
    Envilder.from_map_file('envilder.json')
    .with_provider(SecretProviderType.AZURE)
    .with_vault_url('https://my-vault.vault.azure.net')
    .resolve()
)

Secret validation

Opt-in validation ensures all resolved secrets have non-empty values:

from envilder import Envilder, validate_secrets

secrets = Envilder.resolve_file('envilder.json')
validate_secrets(secrets)  # raises SecretValidationError if any value is empty

Map file contract validation

Check, without loading anything and without using or printing any value, that the map file is valid and that every declared secret exists with the current credentials: the same check as envilder validate. Expected validation failures are returned in the result instead of thrown; a missing map file still throws. Each key reports exists, missing, access_denied, authentication_failed or provider_error:

See the envilder validate reference for the statuses and the permissions the check needs →

from envilder import Envilder, SecretExistenceStatus

result = Envilder.from_map_file('envilder.json').validate_contract()
if not result.is_valid:
    for error in result.map_file_errors:
        print(f'{error.key}: {error.message}')
    for key in result.keys:
        if key.status != SecretExistenceStatus.EXISTS:
            print(f'{key.variable} ({key.path}): {key.status.value}')

To fail the load instead, enable contract validation on the builder. The check runs once before resolving and the error names the failing keys, never their values. It is off by default, so a normal load makes no extra provider call. Unlike secret validation, which checks resolved values, it checks the map file and the keys before resolving:

Envilder.from_map_file('envilder.json').with_contract_validation().inject()
# raises ContractValidationError
💡
Runnable examples. A pytest project with Testcontainers resolves a map file against AWS SSM and Azure Key Vault (emulated with LocalStack and Lowkey Vault) and passes the values to containers, with no .env file: python-testcontainers

Full documentation →