Skip to main content

Validate environment variables at startup. Fail fast with clear errors.

Project description

envcheck

Validate environment variables at startup. Fail fast with clear errors.

Python 3.8+ License: MIT

envcheck makes your environment variables:

  • Explicit — declare what you need
  • Validated — crash early, not in production
  • Typed — get real Python types, not just strings
  • Self-documenting — your schema IS the documentation

Installation

pip install envcheck

Quick Start

from envcheck import env

# Define your environment contract
config = env({
    "DATABASE_URL": str,          # required string
    "DB_PORT": int,               # required, converted to int
    "DEBUG": bool,                # required, smart bool parsing
    "TIMEOUT": (float, 30.0),     # optional with default
    "LOG_LEVEL": (str, "INFO"),   # optional string with default
})

# Use with confidence
print(config.DATABASE_URL)  # Typed, validated, guaranteed
print(config.DB_PORT)       # Already an int
print(config.DEBUG)         # Already a bool

What Happens When Validation Fails?

Your app crashes immediately with a clear error:

❌ EnvCheck Validation Failed

Missing required variables:
  • DATABASE_URL
  • API_KEY

Type validation errors:
  • DB_PORT: expected int, cannot convert 'not_a_number' to int
  • DEBUG: expected bool, cannot convert 'maybe' to bool (expected: true/false, 1/0, yes/no, on/off)

Fix these issues and restart the application.

This is intentional. Fail fast, fail loud, fail obviously.

API Reference

env(schema) -> EnvConfig

Validate environment variables against a schema.

Schema Format:

Syntax Meaning
"VAR": str Required string
"VAR": int Required integer
"VAR": float Required float
"VAR": bool Required boolean
"VAR": (str, "default") Optional with default
"VAR": (int, 8080) Optional int with default

Returns: EnvConfig — an immutable object with attribute access.

Type Conversion

Env Value Type Result
"hello" str "hello"
"5432" int 5432
"3.14" float 3.14
"true" bool True
"false" bool False

Boolean Parsing

envcheck accepts common boolean representations (case-insensitive):

True Values False Values
true, t false, f
yes, y no, n
on off
1 0

EnvConfig Methods

config = env({"VAR": str})

# Attribute access
config.VAR

# Dict-like access
config.get("VAR", "default")
config.to_dict()

# Iteration
for key in config:
    print(key, config.get(key))

# Check existence
"VAR" in config

# Length
len(config)

Real-World Examples

FastAPI Application

# config.py
from envcheck import env

config = env({
    "DATABASE_URL": str,
    "REDIS_URL": str,
    "SECRET_KEY": str,
    "DEBUG": (bool, False),
    "PORT": (int, 8000),
    "WORKERS": (int, 4),
})

# main.py
from config import config
import uvicorn

if __name__ == "__main__":
    uvicorn.run("app:app", host="0.0.0.0", port=config.PORT, workers=config.WORKERS)

Docker Compose

# docker-compose.yml
services:
  app:
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/app
      - REDIS_URL=redis://redis:6379
      - SECRET_KEY=${SECRET_KEY}
      - DEBUG=false

GitHub Actions

# .github/workflows/test.yml
env:
  DATABASE_URL: postgres://localhost:5432/test
  DEBUG: true
  SECRET_KEY: test-secret

Why envcheck?

Before (what you're doing now)

import os

db_url = os.getenv("DATABASE_URL")  # Could be None
port = os.getenv("DB_PORT", "5432")  # Still a string!
debug = os.getenv("DEBUG", "false") == "true"  # Fragile

# Somewhere later, your app crashes...
# "NoneType has no attribute 'split'"

After (with envcheck)

from envcheck import env

config = env({
    "DATABASE_URL": str,
    "DB_PORT": (int, 5432),
    "DEBUG": (bool, False),
})

# If we get here, everything is valid and typed

Design Philosophy

  1. Zero dependencies — just Python's stdlib
  2. One functionenv() does everything
  3. Fail fast — crash immediately, not in production
  4. Be obvious — clear errors, no magic
  5. Stay minimal — ~200 lines of code total

License

MIT License — use it however you want.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

envcheck_py-0.1.0.tar.gz (12.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

envcheck_py-0.1.0-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file envcheck_py-0.1.0.tar.gz.

File metadata

  • Download URL: envcheck_py-0.1.0.tar.gz
  • Upload date:
  • Size: 12.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for envcheck_py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6685b7b4ad7cec67e70b82d67265e6d1e95063c8cfbddb942aae238049bfc382
MD5 8a629ce15469472cc75a273c58d05b66
BLAKE2b-256 20337a8138aaafa25ef9190726dc8320aa3d666387ec98bd944e1ce74708b7fe

See more details on using hashes here.

File details

Details for the file envcheck_py-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: envcheck_py-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for envcheck_py-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3f276c0b802ac5040041e0cfa54363084f84b37d5f5f4eaf9cb8db7229a90e45
MD5 f4bebccaaf5736f5ea2ff7808a3812eb
BLAKE2b-256 da71244bc60113077c3dabda10f53b0f7a279edeea9c383e988b4b09dbe598a6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page