Validate environment variables at startup. Fail fast with clear errors.
Project description
envcheck
Validate environment variables at startup. Fail fast with clear errors.
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
- Zero dependencies — just Python's stdlib
- One function —
env()does everything - Fail fast — crash immediately, not in production
- Be obvious — clear errors, no magic
- Stay minimal — ~200 lines of code total
License
MIT License — use it however you want.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6fdd13b209e2adcb64ebcf4e3ff899d360efcc162a7134cf7688b7acba57acd9
|
|
| MD5 |
2d49a438d8fbf8a35cf0f3abe4491696
|
|
| BLAKE2b-256 |
7ddc1e753f6daaae630a0c787f8d6371ac84c7af1026f3db57449a397a71f59f
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2150c2fa08d62ffb4ce38c3e08d0400c5e36616365f9e83ec2585e0008f23e08
|
|
| MD5 |
8ec307f777cb7c43569bf0298d78438a
|
|
| BLAKE2b-256 |
83131b09e331083be2c5912f4949dc14c33d45d9d162f7c9916df23754b5987b
|