Skip to main content

One command. One score. Built for AI agents. Scans Python codebases and returns a 0-100 health score.

Project description

Python Doctor

One command. One score. Built for AI agents.

Tests PyPI Python License: MIT Docs

Python Doctor scans a Python codebase and returns a 0-100 health score with structured, actionable output. It wraps security scanning, linting, complexity analysis, and more into a single command — so an AI agent can run it, read the results, fix the issues, and verify the fix in a loop without human intervention.

$ python-doctor .

🐍 Python Doctor v2026.3.21
Scanning: /home/user/myproject

📊 Score: 82/100 (Good)

🔒 Security (25/25) ✓
  ✓ All clear.

🧹 Lint (16/20)
  ✗ F841: unused variable 'x' (api/views.py:45)
  ✗ F401: unused import 'os' (utils/helpers.py:1)
  ⚠ W291: trailing whitespace (models/user.py:12)
  ... and 2 more

🔄 Complexity (15/15) ✓
  ✓ All clear.

🧘 Zen (12/15)
  ⚠ deep-nesting: 6 levels deep (core/engine.py:88)
  ⚠ long-function: 92 lines (core/engine.py:45)

🏗 Structure (8/10)
  ⚠ low-test-ratio: test:source ratio is 0.3 (< 0.5)

⚡ Exceptions (10/10) ✓
  ✓ All clear.

🔗 Imports (5/5) ✓
  ✓ All clear.

Table of Contents

Installation

# Recommended (isolated environment)
pipx install python-doctor

# Using uv
uv tool install python-doctor

# Using pip
pip install python-doctor

# Or install the binary (no Python required)
curl -sL https://raw.githubusercontent.com/saikatkumardey/python-doctor/main/install.sh | sh

Requires Python 3.10+. Dependencies (ruff, bandit, radon, vulture) are installed automatically.

Install from source
git clone https://github.com/saikatkumardey/python-doctor.git
cd python-doctor
uv sync
uv run python-doctor /path/to/project

Quick Start

# Scan a project
python-doctor .

# See all findings with line numbers
python-doctor . --verbose

# Auto-fix what can be fixed (via ruff --fix)
python-doctor . --fix

# Just the score (for scripts and CI)
python-doctor . --score
# → 82

# Structured JSON output (for agents)
python-doctor . --json

JSON Output

The --json flag returns machine-readable output that agents can parse directly:

{
  "version": "2026.3.21",
  "path": "/home/user/myproject",
  "score": 82,
  "label": "Good",
  "categories": {
    "security": {
      "score": 25,
      "max": 25,
      "deduction": 0,
      "error": null,
      "findings": []
    },
    "lint": {
      "score": 16,
      "max": 20,
      "deduction": 4,
      "error": null,
      "findings": [
        {
          "rule": "F841",
          "message": "Local variable `x` is assigned to but never used",
          "file": "/home/user/myproject/api/views.py",
          "line": 45,
          "severity": "error"
        }
      ]
    }
  }
}

Agent Integration

Python Doctor works with any agent that can run shell commands. Install the CLI, then add the appropriate rule for your agent.

Claude Code

Install as a plugin for the /python-doctor slash command:

/plugin marketplace add saikatkumardey/python-doctor
/plugin install python-doctor@python-doctor-plugins
Manual setup (without plugin)

Add to your CLAUDE.md:

## Python Health Check

Before finishing work on Python files, run:
  python-doctor . --json

Fix any findings with severity "error". Target score: 80+.
If score drops below 50, do not commit — fix the issues first.

Cursor

Add to .cursor/rules/python-doctor.mdc:

---
description: Python codebase health check
globs: "**/*.py"
alwaysApply: false
---

Run `python-doctor . --json` after modifying Python files.
Fix findings. Target score: 80+. Do not commit below 50.

OpenAI Codex

Add to AGENTS.md:

## Python Health Check

After modifying Python files, run `python-doctor . --json` to check codebase health.
Fix any findings. Target score: 80+. Exit code 1 means score < 50 — fix before committing.

Windsurf / Cline / Aider

Add to your project rules or system prompt:

After modifying Python files, run: python-doctor . --json
Read the output. Fix findings with severity "error" first, then warnings.
Re-run to verify the score improved. Target: 80+.

The Agent Loop

This is the intended workflow:

1. python-doctor . --json  → read the report
2. Fix findings (--fix for auto-fixable, manual for the rest)
3. python-doctor . --score → verify improvement
4. Repeat until score target met

We built Python Doctor, then ran it on itself. Score: 47. Fixed everything it flagged. Score: 92. The tool eats its own dogfood.

CLI Reference

python-doctor [PATH] [OPTIONS]

Arguments:
  PATH                   Directory to scan (default: .)

Options:
  -v, --verbose          Show all findings with line numbers
  --score                Output only the numeric score
  --json                 Structured JSON output for agents
  --fix                  Auto-fix issues via ruff --fix, then report the rest
  --badge                Output a shields.io badge markdown snippet
  --ci                   Output a GitHub Actions workflow for badge auto-update
  --pre-commit           Install as a git pre-commit hook
  --min-score N          Minimum score threshold (exit 1 if below). Default: 50
  --profile TYPE         Override auto-detected profile (cli|web|library|script)
  --version              Show version and exit
  -h, --help             Show help and exit

Exit Codes

Code Meaning
0 Score >= 50
1 Score < 50 (critical health)

What It Checks

7 categories, weighted by impact:

Category Weight Max Deduction What it catches
Security 5 25 Bandit findings: SQL injection, hardcoded secrets, unsafe calls. Context-aware: skips test/example/docs files.
Lint 4 20 Ruff: unused imports, undefined names, style violations. Excludes docs/.
Complexity 3 15 Radon: cyclomatic complexity > 15. Excludes test files.
Zen 3 15 Deep nesting (>5 levels), long functions (>75 lines), too many params (>10), large classes (>15 methods)
Structure 2 10 Large files (>1000 lines), test ratio, type hints, README, LICENSE, linter config
Exceptions 2 10 Bare except:, silently swallowed exceptions
Imports 1 5 Star imports (from x import *), circular dependency detection

Scoring

Score = max(0, 100 - total_deductions)

  • Weights are relative. Max deductions auto-scale so they always sum to exactly 100.
  • Adding or removing a category automatically rebalances the weights.
  • Deductions are capped per category (a single category can't tank the whole score).
Score Label Meaning
90-100 Excellent Clean codebase, ready for production
75-89 Good Minor issues, nothing blocking
50-74 Needs Work Significant issues to address
0-49 Critical Major problems, CI will fail (exit code 1)

Configuration

Configure via [tool.python-doctor] in your pyproject.toml:

[tool.python-doctor]
# Override the auto-detected project profile
profile = "web"

# Suppress specific rules globally
suppress = ["bandit/B101", "structure/no-py-typed"]

# Suppress rules for specific files (glob patterns)
[tool.python-doctor.per-file-suppress]
"tests/**" = ["bandit/B101"]
"scripts/*" = ["structure/large-file"]

# Override max deduction for a category
[tool.python-doctor.max-deduction]
security = 15
structure = 5

Profiles

Python Doctor auto-detects your project type and adjusts rules accordingly:

Profile Detection Adjustments
web flask, django, fastapi, etc. in dependencies Default rules
cli click, typer, etc. in deps, or [project.scripts] defined Suppresses subprocess-related Bandit rules (B404, B603, B607), caps security at 15
library Has [build-system] but no scripts Default rules
script Few .py files, no package directory Relaxed structure checks, no tests/license requirement

Override with --profile <type> or set profile in pyproject.toml.

Pre-commit Hook

Block commits when the health score drops too low.

Quick install (git hook)

# Install with default threshold (score < 50 blocks commit)
python-doctor --pre-commit

# Or set a custom threshold
python-doctor --pre-commit --min-score 80

Using the pre-commit framework

Add to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/saikatkumardey/python-doctor
    rev: v2026.3.21
    hooks:
      - id: python-doctor

CI/CD

GitHub Actions

Add a health check step to any workflow:

- name: Health Check
  run: |
    pipx install python-doctor
    python-doctor . --verbose

Exits with code 1 if score drops below 50.

Auto-Updating Badge

Add a live score badge to your README:

# 1. Get your badge markdown (runs a scan)
python-doctor . --badge

# 2. Generate the CI workflow
python-doctor --ci > .github/workflows/python-doctor.yml

# 3. Commit and push
git add README.md .github/workflows/python-doctor.yml
git commit -m "Add python-doctor badge"
git push

The workflow runs on every push to main, updates the badge score in your README, and auto-commits the change.

Benchmarks

Scores on popular open-source projects:

Project Stars Score Profile Top Findings
requests 52k+ 81/100 (Good) library Weak hashes (B324), complexity (CC 21), large files, no type hints
flask 69k+ 78/100 (Good) web Hardcoded passwords, complexity (CC 23), large files (app.py: 1625 lines)
fastapi 82k+ 78/100 (Good) web Complexity (CC 45), large files (routing.py: 4956 lines), many params

Test and example files are excluded from security and complexity analysis. Docs directories are excluded from linting.

Contributing

See CONTRIBUTING.md for development setup, how to add analyzers, and release process.

# Quick start
git clone https://github.com/saikatkumardey/python-doctor.git
cd python-doctor
uv sync --extra dev
uv run pytest tests/ -v

License

MIT - Saikat Kumar Dey, 2026

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

python_doctor-2026.3.22.tar.gz (49.7 kB view details)

Uploaded Source

Built Distribution

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

python_doctor-2026.3.22-py3-none-any.whl (28.0 kB view details)

Uploaded Python 3

File details

Details for the file python_doctor-2026.3.22.tar.gz.

File metadata

  • Download URL: python_doctor-2026.3.22.tar.gz
  • Upload date:
  • Size: 49.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for python_doctor-2026.3.22.tar.gz
Algorithm Hash digest
SHA256 c83900d25b3c7ad5b82544112d6531064e180c7ab8983eec5621a797c48c22a0
MD5 5efaceef09f4df583ccdf2cc269656b4
BLAKE2b-256 ab5355bb6e3ec0d8acdcf848463f2392685c5c107a726279c21ff42a57b7f3c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_doctor-2026.3.22.tar.gz:

Publisher: release.yml on saikatkumardey/python-doctor

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

File details

Details for the file python_doctor-2026.3.22-py3-none-any.whl.

File metadata

File hashes

Hashes for python_doctor-2026.3.22-py3-none-any.whl
Algorithm Hash digest
SHA256 c08c7a6ffd840c4e4b5c808ea8502ba9660da88eecd3222b51fb2d62e2c9e7a2
MD5 d8909768cc251e392bb25d583fea3d43
BLAKE2b-256 bd7e730a2ce356e672b2c62b5b74fcbdb40523e8464ce728cd8ba1dfcba742e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_doctor-2026.3.22-py3-none-any.whl:

Publisher: release.yml on saikatkumardey/python-doctor

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

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