Skip to main content

Find the gaps in your Python environment config.

Project description

envgap

Find the gaps in your Python environment config.

envgap is a diagnostic CLI for Python projects that use .env files, .env.example, shell variables, and os.environ / os.getenv in code. It does not load your config. It shows the gaps between what your app expects, what your project documents, and what your environment actually provides.

envgap terminal diagnosis screenshot

30-Second Demo

Given a project with:

# .env
DB_URL=postgres://localhost/app
OPENAI_API_KEY=changeme
# app.py
import os

DATABASE_URL = os.environ["DATABASE_URL"]

Run:

$ DATABASE_URL=postgres://shell/app envgap check examples/basic

envgap check
===============

Checked:
  shell environment: available (1/4 expected key(s) found)
  .env: found (3 key(s))
  .env.example: found (3 key(s))
  Python code: 3 env usage(s)

Diagnosis:
  DATABASE_URL
    ! Missing value: DATABASE_URL is missing from .env (app.py:3)
      It is present in your shell environment, so local commands may work while CI or Docker still fails.
      Suggested fix: Add DATABASE_URL=... to .env or document how CI/Docker should provide it.

  DB_URL
    ~ Possible typo: DB_URL may be a typo for DATABASE_URL (.env:1)
      Suggested fix: Rename DB_URL to DATABASE_URL if they represent the same setting.

Why

Environment config bugs are boring until they eat an afternoon.

Common examples:

  • The app expects DATABASE_URL, but .env contains DB_URL.
  • .env.example says a key exists, but local .env never got it.
  • A secret is still set to changeme.
  • A variable works locally only because it is exported in your shell.
  • CI, Docker, or another developer's machine fails because the real required variables are not documented.

envgap is for that moment when you want the project to explain itself.

Install

pip install envgap

From a local checkout:

pip install -e ".[dev]"

Quick Start

Run a check in the current project:

envgap check

Try the included broken example:

envgap check examples/basic

Show machine-readable output:

envgap check --json

Ignore shell variables for deterministic CI checks:

envgap check --no-shell

Fail on warnings as well as errors:

envgap check --strict

--ci is supported as a CI-friendly alias for --strict:

envgap check --ci

Use custom dotenv filenames:

envgap check --env-file .env.local --example-file .env.example

What It Checks Today

envgap check currently inspects:

  • current shell environment
  • .env
  • .env.example
  • Python files using common environment variable APIs

It detects:

  • missing keys
  • undocumented extra keys
  • duplicate keys
  • empty values
  • placeholder values like your-key-here, changeme, todo, and replace-me
  • likely typo pairs like DB_URL vs DATABASE_URL
  • required env vars used in Python code but missing from .env.example
  • missing .env
  • missing .env.example

It scans Python code for:

os.environ["DATABASE_URL"]
os.getenv("DATABASE_URL")
os.getenv("DATABASE_URL", "sqlite:///local.db")
os.environ.get("DATABASE_URL", "sqlite:///local.db")

Required vs optional behavior:

  • os.environ["KEY"] is required
  • os.getenv("KEY") is required
  • os.getenv("KEY", default) is optional
  • os.environ.get("KEY", default) is optional

Exit Codes

Command Exit code behavior
envgap check exits 1 when errors are present
envgap check --strict exits 1 when errors or warnings are present
envgap check --ci same as --strict
envgap check --json same pass/fail behavior, JSON output
envgap check --no-shell ignores current shell variables when diagnosing missing keys

Warnings do not fail a normal check unless --strict or --ci is used.

CI

name: envgap

on: [push, pull_request]

jobs:
  envgap:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install envgap
      - run: envgap check --ci

Example Diagnosis

Given:

# .env
DB_URL=postgres://localhost/app
OPENAI_API_KEY=changeme
# .env.example
DATABASE_URL=
OPENAI_API_KEY=your-key-here
# app.py
import os

DATABASE_URL = os.environ["DATABASE_URL"]
DEBUG = os.getenv("DEBUG", "false")

envgap can report:

  • DATABASE_URL is required in code but missing from .env
  • DB_URL may be a typo for DATABASE_URL
  • OPENAI_API_KEY still looks like a placeholder
  • DEBUG is optional because it has a default

Why Not Just python-dotenv?

python-dotenv loads environment variables.

envgap explains whether the environment variables your app expects match the variables your project defines and documents.

The useful question is not only:

Did .env load?

It is:

What does my app expect, where should it come from, and why is it missing or wrong here?

Current Scope

This is intentionally a small diagnostic tool, not a config framework.

In scope now:

  • .env
  • .env.example
  • shell environment
  • Python os.environ / os.getenv scanning
  • terminal and JSON reports
  • CI-friendly exit codes

Not in scope yet:

  • loading or mutating your environment
  • validating every framework-specific settings pattern
  • Docker Compose parsing
  • GitHub Actions secrets parsing
  • Pydantic BaseSettings extraction

Roadmap

  • Pydantic BaseSettings support
  • Django settings helper detection
  • Docker Compose env detection
  • GitHub Actions env/secrets detection
  • precedence explanations for shell vs .env vs framework defaults
  • GitHub Actions annotations
  • richer JSON schema for editor and CI integrations

Development

python -m venv .venv
. .venv/bin/activate
pip install -e ".[dev]"
pytest

Run the example locally:

envgap check examples/basic

Run the shell-aware example:

DATABASE_URL=postgres://shell/app envgap check examples/basic

License

MIT

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

envgap-0.1.0.tar.gz (17.0 kB view details)

Uploaded Source

Built Distribution

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

envgap-0.1.0-py3-none-any.whl (16.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for envgap-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ee003567cc05a0fe74f073f846ab9c3bb8e17229880b6aeb8433f0d8e5837871
MD5 60e12b094d17051e8cf977be9f27b77b
BLAKE2b-256 dc22006820bdf8d018089d10a34c60437bf0718de57ba1df634bfa2dc333f522

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for envgap-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 aec0a9ff034d8b48a13c35cae3dd4c2849afb758691a8c837fbd9d813656363a
MD5 3848814d60f7a1b52c8e8ec0c11f624a
BLAKE2b-256 0f0f45f13a554d89da0249fece3c08c3788c41a5f059f32e9f195fba16259fc7

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