Skip to main content

envdoctor (Python)

Native Python port of envdoctor — a local-first consistency checker for environment variables, distributed on PyPI so Python projects can use it without Node.

Install

pip install arun-envdoctor

The PyPI distribution is named arun-envdoctor (PyPI blocks envdoctor as too similar to an existing project), but the installed command and the importable package are both still envdoctor.

Quick start

envdoctor scan --dir .        # audit; exit 1 on errors
envdoctor scan --strict       # treat warnings as errors too
envdoctor scan --json         # emit findings as a JSON array (no values)

What it detects

Reconciles the environment variables used in your Python source (os.getenv("X"), os.environ.get("X"), os.environ["X"], and the from os import environ forms) against those defined in your .env files, then reports:

Rule Severity Meaning
undefined-in-source error Referenced (source or infra files) but not defined in any .env file
duplicates error The same key is defined 2+ times within a single .env file
public-prefix error A secret-looking variable is exposed to client bundles via a public prefix (NEXT_PUBLIC_, VITE_, REACT_APP_, EXPO_PUBLIC_, GATSBY_, NUXT_PUBLIC_, VUE_APP_, PUBLIC_)
type-mismatch error A variable's value has incompatible inferred types across environments (e.g. PORT=3000 vs PORT=abc)
unused warning Defined in .env but never referenced in source
environment-diff warning Defined in some environment files but missing from others
weak-secret warning A secret-looking variable has a weak, empty, or placeholder value
typo warning A used-but-undefined name closely matches a defined one (likely a typo)

In addition to Python source, envdoctor scans Docker Compose (docker-compose.yml / compose.yaml), GitHub Actions workflows (.github/workflows/*.yml), and Kubernetes manifests (any YAML with both apiVersion: and kind:) for referenced variables. Detection is dependency-free (regex only, no YAML parser): shell-style interpolation ${VAR} / $VAR (including ${VAR:-default} forms) across all three, plus ${{ secrets.X }}, ${{ vars.X }}, and ${{ env.X }} references in Actions. These references feed the same missing/undefined and unused detectors, so a variable referenced only in infra files but never defined is flagged, and one defined and referenced only in infra is not reported unused.

Comments and docstrings are stripped before scanning, so documented examples don't cause false positives. Nothing is uploaded and variable values are never printed — they are used only for detection and never appear in any output (human or --json). envdoctor scan exits 1 when there are errors (or with --strict, warnings), making it CI-friendly. Pass --json to emit a JSON array of findings (each with rule, severity, name, message, file, line) for machine consumption.

Library use

from pathlib import Path
from envdoctor import scan

result = scan(Path("."))
for finding in result.errors:
    print(finding.name, finding.message)

Development

pip install -e ".[dev]" pytest
pytest

Subcommands

Alongside scan, every port shares these environment subcommands:

envdoctor diff <envA> <envB>       # compare two environments (add --json)
envdoctor sync <from> <to>         # copy missing keys (add --dry-run)
envdoctor init [--force]           # generate .env.example + ENVIRONMENT.md
envdoctor fix                      # (re)generate both docs

diff reports which variable names are only in one environment; sync appends the missing keys to the target .env file as empty KEY= placeholders — values are never copied.

init / fix

Both commands generate two files at the project root from the union of every variable name (defined in any .env* file ∪ referenced in source/infra), sorted ascending. Values are never written.

  • .env.example — a header comment followed by one NAME= line per variable.
  • ENVIRONMENT.md — a Markdown table of each variable with Defined/Used columns.

init writes each file only if it does not already exist (--force overwrites); fix always regenerates both. Every port produces byte-identical files.

Schema validation

Add an envdoctor.schema.json at your project root to validate .env values:

{
  "PORT":  { "type": "integer", "min": 1, "max": 65535 },
  "LEVEL": { "enum": ["debug", "info", "warn", "error"] },
  "TOKEN": { "type": "string", "optional": true }
}

Supported rule fields: type (string/integer/float/boolean/url/json), enum, regex, min, max, optional. Values that fail are reported as schema-validation errors (values are never printed).

Other languages

envdoctor ships as a standalone native port for each ecosystem:

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

arun_envdoctor-0.1.2.tar.gz (15.3 kB view details)

Uploaded Source

Built Distribution

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

arun_envdoctor-0.1.2-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

Details for the file arun_envdoctor-0.1.2.tar.gz.

File metadata

  • Download URL: arun_envdoctor-0.1.2.tar.gz
  • Upload date:
  • Size: 15.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for arun_envdoctor-0.1.2.tar.gz
Algorithm Hash digest
SHA256 e420941c4b1c2d8e6a1abc302295582a589ad25f3a5d0212150006ff48ea5d0e
MD5 0713b8c60f30f3c5d19fa2b842e3f3aa
BLAKE2b-256 46ca738845fa0ca91046063a8e22723fdc82f9f822ef9f52258598abd8af51a0

See more details on using hashes here.

Provenance

The following attestation bundles were made for arun_envdoctor-0.1.2.tar.gz:

Publisher: python-release.yml on arun-skg/envdoctor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file arun_envdoctor-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: arun_envdoctor-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 13.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for arun_envdoctor-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 2582558bada37a2a629d589eeaf831ae781b01b48697628e03525ff0c90815e3
MD5 6b77de159a81b84e527e0feaac9405ab
BLAKE2b-256 0a8d20190adf6ef6525f00fa480e3ccab0181a8e8f915e00f1db8e78fa6c52e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for arun_envdoctor-0.1.2-py3-none-any.whl:

Publisher: python-release.yml on arun-skg/envdoctor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page