Skip to main content

envgate

CI codecov PyPI version Python License: MIT

A minimal Python library to validate environment variables at startup. Zero dependencies.

Why?

Instead of your app crashing at runtime because DATABASE_URL is missing, envgate validates everything at startup and tells you exactly what's wrong.

Installation

pip install envgate

Quick Start

from envgate import get_env, validate

# Get a single variable with type coercion
port = get_env("PORT", type="int", default=8000)
debug = get_env("DEBUG", type="bool", default=False)

# Explicitly mark a variable as required
api_key = get_env("API_KEY", required=True)

# Parse comma-separated lists (or use a custom separator)
hosts = get_env("ALLOWED_HOSTS", type="list")            # ["a", "b", "c"]
ports = get_env("PORTS", type="list[int]", sep=":")      # [8000, 8001]

# Or validate multiple variables at once
config = validate({
    "DATABASE_URL": {"type": "str"},
    "REDIS_URL": {"type": "str"},
    "PORT": {"type": "int", "default": 8000},
    "DEBUG": {"type": "bool", "default": False},
})

If DATABASE_URL and REDIS_URL are missing and PORT is invalid, you get all errors at once:

envgate.exceptions.ValidationError: Environment validation failed:
    - Environment variable 'DATABASE_URL' is not set.
    - Environment variable 'REDIS_URL' is not set.
    - Environment variable 'PORT' has invalid value 'abc' (expected int).

Custom validators

Type coercion checks that PORT is an integer. A validator checks that the value also makes sense — e.g. that the port is in a usable range, or that a log level is one of a fixed set:

def in_port_range(p):
    if not (1024 <= p <= 65535):
        raise ValueError("must be in [1024, 65535]")

def is_known_level(level):
    if level not in {"debug", "info", "warning", "error"}:
        raise ValueError("must be one of debug|info|warning|error")

config = validate({
    "PORT": {"type": "int", "validator": in_port_range},
    "LOG_LEVEL": {"type": "str", "default": "info", "validator": is_known_level},
})

A validator signals failure by raising any exception — its message is captured and joined into the same collective ValidationError as missing and invalid-type errors:

envgate.exceptions.ValidationError: Environment validation failed:
    - Environment variable 'PORT' has invalid value '80': must be in [1024, 65535]
    - Environment variable 'LOG_LEVEL' has invalid value 'verbose': must be one of debug|info|warning|error

Loading a .env file

For local development, load variables from a .env file before validating. load_env() copies the file's entries into os.environ, so validate() picks them up with no extra wiring:

from envgate import load_env, validate

load_env()  # reads ./.env into os.environ (defaults to ".env")

config = validate({
    "DATABASE_URL": {"type": "str"},
    "PORT": {"type": "int", "default": 8000},
})

Given a .env like:

# database
DATABASE_URL=postgres://localhost/app
PORT=5432
export DEBUG="true"
  • Real environment variables win by default. A key already set in the environment (CI, containers, systemd) is not overwritten by the file. Pass load_env(override=True) to flip this and let the file's values replace what's already there — handy for test fixtures.
  • A missing file is a silent no-op — handy in production, where you rely on real environment variables and ship no .env. A file that exists but has a broken line raises EnvFileError.
  • load_env() returns a dict of everything it parsed from the file, so you can log or inspect it without touching global state.

Parsing is stdlib-only and deliberately simple: blank lines and full-line # comments are skipped, a leading export is tolerated, surrounding quotes are stripped, and there's no shell-style interpolation.

Supported Types

Type Example values
str Any string (default)
int "42", "-7", "0"
float "3.14", "42", "-2.5"
bool "true", "1", "yes", "on" / "false", "0", "no", "off"
list, list[str], list[int], list[float], list[bool] Comma-separated values — e.g. "a,b,c" → ["a", "b", "c"]. Pass sep=":" (or any character) to override the separator.

Contributing

Contributions are welcome! Check out the CONTRIBUTING.md for guidelines.

License

MIT

Release files for envgate 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for envgate 1.0.0
File Size Uploaded
envgate-1.0.0.tar.gz 11.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for envgate 1.0.0
File Interpreter ABI Platform
envgate-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 24.9 kB

Release files / envgate-1.0.0.tar.gz

Download URL envgate-1.0.0.tar.gz
Size 11.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6d6abd3e5bb089b479c428ff3e9902b650b05da28cdf9176d10ac84d05465f2b
BLAKE2b-256 checksum
How to use checksums
47b14b30527c6497fbd47b34d2b795cd7b8b986253dd2228afbec30a6a33a03d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / envgate-1.0.0-py3-none-any.whl

Download URL envgate-1.0.0-py3-none-any.whl
Size 13.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
524ba39ab75d469af8067e7919c392ad93749243458207af451db052991dccf1
BLAKE2b-256 checksum
How to use checksums
d598a0c1141c7545465020def3c3e481ae3c403f8d99951b80708cb225d63a1e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page