Skip to main content

envcheck

CI Python License: MIT PyPI

Keep your .env.example in sync with the environment variables your code actually uses.

New teammate clones the repo, copies .env.example, runs the app — and it crashes on a KeyError for some variable nobody documented. envcheck catches that before it happens. It statically scans your Python (it never imports or runs your code) for os.getenv / os.environ access, compares the result to your example env file, and reports:

  • Undocumented vars — used in code but missing from .env.example (fails CI)
  • Possibly unused vars — in .env.example but never read by any code

Zero runtime dependencies, Python 3.8+, CI-friendly.

Demo

envcheck flagging an undocumented and an unused variable

The examples/sample project deliberately drifts from its .env.example so you can try it immediately: envcheck examples/sample.

Installation

pip install envcheck-sync

Or run from a checkout without installing:

PYTHONPATH=src python -m envcheck path/to/project

Usage

# Scan the current directory (auto-detects .env.example, .env.sample, ...)
envcheck .

# Point at a specific example file
envcheck . --env-file config/.env.template

# Machine-readable output for tooling
envcheck . --format json

Example

$ envcheck examples/sample
Scanned 3 env var(s) in code against examples/sample/.env.example.

Undocumented (1 variable used in code, not in the env file):
  - JWT_SECRET  (e.g. examples/sample/app.py:9)

Possibly unused (1 variable in the env file, not read by code):
  - LEGACY_FLAG

envcheck exits non-zero when undocumented variables are found, so it drops straight into CI or a pre-commit hook (use --no-fail to report without failing).

What it detects

Static, literal-key access in these forms:

  • os.getenv("X") and getenv("X")
  • os.environ.get("X") and environ.get("X")
  • os.environ["X"] and environ["X"]
  • os.environ.setdefault("X", ...)

Dynamic keys (e.g. os.getenv(some_variable)) are intentionally ignored — envcheck only reports what it can prove statically, so it never produces noisy false positives.

How it works

  1. Walk the project and parse each .py file with the standard-library ast module.
  2. Collect every literal-key environment-variable access, with its file and line.
  3. Parse the example env file for declared variable names.
  4. Diff the two sets and report the gaps.

Development

git clone https://github.com/gazzycodes/envcheck
cd envcheck
PYTHONPATH=src python -m unittest discover -s tests -v

Contributions are welcome — please open an issue or PR.

License

MIT — see LICENSE.

Metadata

Release files for envcheck-sync 0.1.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 envcheck-sync 0.1.0
File Size Uploaded Provenance
envcheck_sync-0.1.0.tar.gz 51.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for envcheck-sync 0.1.0
File Interpreter ABI Platform
envcheck_sync-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 61.6 kB

Release files / envcheck_sync-0.1.0.tar.gz

Download URL envcheck_sync-0.1.0.tar.gz
Size 51.7 kB
Tags Source
SHA-256 checksum
How to use checksums
6db285761077f6e25fe5ac20f6d72b9226e022c7d7e99af104bcdece7800c45f
BLAKE2b-256 checksum
How to use checksums
5da78113bc2c6c03db9045083799b746cae32a03a6370025fb5f2cfb7bad593b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / envcheck_sync-0.1.0-py3-none-any.whl

Download URL envcheck_sync-0.1.0-py3-none-any.whl
Size 9.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a84dfd62bee589de0839855ac705439521e7308f5b1f991623aee2900bcacf92
BLAKE2b-256 checksum
How to use checksums
721299f462302749bcef88bd7fd9bfd96f98f1e66a383fab070e3ec4e7e776ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Security for envcheck-sync 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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