rpmjp/portfolio
rpmjp/projects/communityshield/api-reference.md
CompletedMay – August 2025

CommunityShield

ML-powered crime pattern explorer for Chicago. 8.5M rows, 4 XGBoost models with SHAP explanations, beat-level heatmap, and an honest methodology page about what the data can and cannot tell you.

Python 3.12FastAPIPostgreSQL 16PostGISXGBoostSHAPReact 19MapLibre GL
Languages
TypeScript52.4%
Python41.8%
CSS3.2%
Other2.6%
api-reference.md

REST API Reference

CommunityShield exposes a FastAPI service with auto-generated OpenAPI docs at /docs. Every endpoint is unauthenticated and rate-limited — the data is public, but the compute isn't free.


Heatmap

EndpointMethodDescription
/heatmapGETPer-beat aggregate counts for the requested time window and category. Picks the right rollup table based on window length.
/heatmap/categoriesGETAvailable crime categories with citywide counts

Example response:

{
  "window": { "start": "2025-07-01T00:00:00Z", "end": "2025-08-01T00:00:00Z" },
  "category": "THEFT",
  "beats": [
    { "beat_id": 111, "beat_number": "0111", "count": 47, "intensity": 0.62 },
    { "beat_id": 112, "beat_number": "0112", "count": 23, "intensity": 0.31 }
  ]
}

Beat detail

EndpointMethodDescription
/beatsGETAll 274 beats with metadata
/beats/{beat_id}GETSingle beat: geometry, district, ward
/beats/{beat_id}/trendGETTime series for the beat over a configurable window
/beats/{beat_id}/incidentsGETRecent incidents at the beat, paginated, capped at 200 rows
/beats/{beat_id}/comparisonGETBeat vs. citywide median for each crime category

Prediction

EndpointMethodDescription
/predict/{beat_id}GETRun all four models for the beat, return predictions with SHAP attribution
/predict/{beat_id}/{category}GETSingle-category prediction with full SHAP breakdown

Example response:

{
  "beat_id": 111,
  "window": { "start": "2025-08-01T00:00:00Z", "end": "2025-08-02T00:00:00Z" },
  "category": "THEFT",
  "prediction": { "above_median": true, "probability": 0.74 },
  "top_features": [
    { "name": "theft_count_last_7d", "value": 18, "shap": 0.31 },
    { "name": "hour_of_week_baseline", "value": 4.2, "shap": 0.18 },
    { "name": "neighbor_beat_theft_24h", "value": 12, "shap": 0.11 }
  ],
  "model_version": "theft_classifier_v1.2.3"
}

Methodology

EndpointMethodDescription
/methodology/rocGETPre-computed ROC curve points for all four classifiers
/methodology/importanceGETGlobal feature importance for the model ensemble
/methodology/data-ceilingGETPR-AUC convergence data across hyperparameter trials

Health

EndpointMethodDescription
/healthGETLiveness check
/readyGETReadiness check (DB + all 4 models loaded)

Design notes

Unauthenticated, rate-limited. Crime data is public. The API is public. Rate limits prevent abuse without requiring API keys.

OpenAPI for free. FastAPI generates the full spec from Pydantic schemas. /docs renders the interactive Swagger UI; /redoc renders a cleaner reference style.

Cursor pagination on /beats/{beat_id}/incidents. Some beats have hundreds of thousands of historical incidents. Cursor pagination keeps the endpoint fast at any offset.

Rollup-aware time windows. The /heatmap and /beats/{beat_id}/trend endpoints accept any window length and automatically pick the appropriate rollup table (hourly, daily, weekly, monthly) based on window size. The caller doesn't need to know about the rollup structure.