Metadata-Version: 2.4
Name: envproof
Version: 0.2.0
Summary: Validate environment variables at startup with typed, clear error messages. Zero dependencies.
Project-URL: Homepage, https://github.com/CoderSufiyan/envguard
Project-URL: Repository, https://github.com/CoderSufiyan/envguard
Project-URL: Issues, https://github.com/CoderSufiyan/envguard/issues
License: MIT
License-File: LICENSE
Keywords: config,dotenv,env,environment,settings,validation
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# envproof

> Validate environment variables at startup with typed, clear error messages. Zero dependencies. Production-ready.

[![PyPI version](https://img.shields.io/pypi/v/envproof.svg)](https://pypi.org/project/envproof/)
[![Python versions](https://img.shields.io/pypi/pyversions/envproof.svg)](https://pypi.org/project/envproof/)
[![CI](https://github.com/CoderSufiyan/envguard/actions/workflows/ci.yml/badge.svg)](https://github.com/CoderSufiyan/envguard/actions)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/CoderSufiyan/envguard/blob/main/LICENSE)
[![Open Source](https://img.shields.io/badge/Open%20Source-%E2%9D%A4-red)](https://github.com/CoderSufiyan/envguard)

---

Every backend app reads environment variables. The standard way fails silently or crashes with a cryptic error deep inside your app at runtime:

```python
# Crashes 10 minutes in, on an obscure code path
db = connect(os.environ["DATABASE_URL"])  # KeyError: DATABASE_URL

# PORT is a string — breaks math silently
port = os.environ["PORT"]  # "8080", not 8080
```

**envproof catches all of this at startup**, before your app serves a single request:

```python
from envproof import EnvGuard

class Env(EnvGuard):
    DATABASE_URL: str
    PORT: int = 8080
    DEBUG: bool = False
    ALLOWED_HOSTS: list = []

env = Env()
print(env.PORT)  # 8080 — already an int
```

If anything is wrong, you get a clear error immediately:

```
EnvProofError:
Missing required environment variables:
  - DATABASE_URL (str): not set

Invalid environment variable values:
  - PORT: expected int, got 'abc'
  - DEBUG: expected bool, got 'maybe'
```

All errors reported at once — not one at a time.

---

## Install

```bash
pip install envproof
```

---

## Usage

### Recommended: one `env.py` file in your project

```python
# env.py
from envproof import EnvGuard

class Env(EnvGuard):
    # Required — raises EnvProofError at startup if not set
    DATABASE_URL: str
    SECRET_KEY: str
    API_KEY: str

    # Optional — uses default if not set
    PORT: int = 8080
    DEBUG: bool = False
    LOG_LEVEL: str = "INFO"
    ALLOWED_HOSTS: list = []

env = Env()
```

Then import `env` anywhere in your app:

```python
# app.py
from env import env

app.run(port=env.PORT, debug=env.DEBUG)
```

```python
# database.py
from env import env

db = connect(env.DATABASE_URL)
```

### One-liner style (no subclass needed)

```python
from envproof import guard

env = guard(DATABASE_URL=str, PORT=int, DEBUG=bool)
print(env.DATABASE_URL)
```

### Works great with python-dotenv

```python
from dotenv import load_dotenv
load_dotenv()          # loads .env file into environment

from env import env    # envproof validates it
```

---

## Supported types

| Type    | Example env value              | Python value        |
|---------|--------------------------------|---------------------|
| `str`   | `hello`                        | `"hello"`           |
| `int`   | `8080`                         | `8080`              |
| `float` | `3.14`                         | `3.14`              |
| `bool`  | `true`, `1`, `yes`, `on`       | `True`              |
| `bool`  | `false`, `0`, `no`, `off`      | `False`             |
| `list`  | `localhost,example.com`        | `["localhost", "example.com"]` |

---

## Why envproof?

| | envproof | `os.environ` | `pydantic-settings` |
|---|---|---|---|
| Type coercion | Yes | No | Yes |
| Clear error messages | Yes | No | Partial |
| Zero dependencies | Yes | Yes | No (~2MB) |
| Fail fast at startup | Yes | No | Yes |
| Works anywhere | Yes | Yes | Pydantic only |

**vs `pydantic-settings`:** great library, but pulls in Pydantic (~2MB). envproof is a single file with zero dependencies — ideal for serverless functions, lightweight containers, or any project that doesn't already use Pydantic.

---

## Production use

envproof is designed for production. The "fail fast" pattern — crashing at startup rather than during a request — is standard practice in production backend systems. Your app either starts correctly or doesn't start at all. No surprises mid-flight.

Used in: FastAPI apps, Flask apps, Django projects, CLI tools, serverless functions, Docker containers.

---

## Open Source

envproof is MIT licensed and open for contributions. See [CONTRIBUTING.md](CONTRIBUTING.md) for how to get started.

Things we'd love help with:
- New types: `dict`, `Path`, `Enum`
- Framework integrations (FastAPI lifespan hooks, Django `AppConfig.ready()`)
- Better error formatting
- More test coverage

[Open an issue](https://github.com/CoderSufiyan/envguard/issues) or submit a PR — all contributions welcome.

---

## License

[MIT](LICENSE) © Sufiyan Khan
