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-py

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.1.tar.gz (12.3 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.1-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: envcheck_py-0.1.1.tar.gz
  • Upload date:
  • Size: 12.3 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.1.tar.gz
Algorithm Hash digest
SHA256 6fdd13b209e2adcb64ebcf4e3ff899d360efcc162a7134cf7688b7acba57acd9
MD5 2d49a438d8fbf8a35cf0f3abe4491696
BLAKE2b-256 7ddc1e753f6daaae630a0c787f8d6371ac84c7af1026f3db57449a397a71f59f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: envcheck_py-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 9.4 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2150c2fa08d62ffb4ce38c3e08d0400c5e36616365f9e83ec2585e0008f23e08
MD5 8ec307f777cb7c43569bf0298d78438a
BLAKE2b-256 83131b09e331083be2c5912f4949dc14c33d45d9d162f7c9916df23754b5987b

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