py-metrics

Usage

PyMetrics accepts a public GitHub URL, clones the repository, runs radon/pylint/pydriller over every non-test Python file, and persists four levels of results (file / class / function / summary) to SQLite. Artifacts are streamed to object storage so the UI can offer immediate CSV and ZIP downloads.

From the web UI

  1. Paste a GitHub URL on the Home page (https://github.com/<owner>/<repo>) and optionally a branch.
  2. Click Analyze. The page subscribes to the server-sent-events stream and reports stages such as pending, cloning, discovering, analyzing, git_analysis, generating, and done.
  3. When the run completes, the dashboard opens with KPI cards, a file-level table, and per-class / per-function drill-downs.
  4. Use the download buttons to export CSVs or the full ZIP bundle, and open Insights for trend, heatmap, scatter, quality-gate, PDF, and share-card views.

From the REST API

Trigger an analysis:

curl -X POST http://localhost:8000/api/analyses \
     -H "Content-Type: application/json" \
     -d '{"repo_url": "https://github.com/pallets/flask", "branch": "main"}'

Pin a tag or commit:

curl -X POST http://localhost:8000/api/analyses \
     -H "Content-Type: application/json" \
     -d '{"repo_url": "https://github.com/psf/requests", "ref": "v2.32.3"}'

Stream progress:

curl -N http://localhost:8000/api/analyses/<id>/stream

Download the CSV for a granularity level:

curl -o file.csv http://localhost:8000/api/analyses/<id>/download/file
curl -o all.zip  http://localhost:8000/api/analyses/<id>/download/all

On disk, completed runs are written under data/outputs/ with descriptive prefixes:

<repo>__<UTC timestamp>__ref-<branch-or-tag-or-sha>__a<analysis id>__sha-<commit>/

Example:

flask__20260503-002114__ref-main__a3__sha-1a2b3c4d5e6f/

List recent runs:

curl http://localhost:8000/api/analyses?limit=20

See /docs for the full OpenAPI schema.

Configuration knobs that change behavior

Setting Effect on output
CLONE_SHALLOW=false Enables git-history metrics (age_days, revisions, authors, avg_loc_added, avg_loc_deleted).
PYLINT_ENABLED=false pylint_* columns are null. Analysis completes ~50 % faster.
SKIP_TEST_FILES=true test_*.py, *_test.py, and files under tests/ are excluded.
MAX_FILE_COUNT Discovery stops past this cap and logs a warning.
MAX_REPO_SIZE_MB Rejects repositories that exceed the configured size after clone.

Quality gates

The Insights tab lets you pass thresholds and see which files fail:

These are presentation-only — they do not influence the stored metrics.