City Pulse is a local MLOps demo that samples public MDOT traffic video, runs YOLO detections, stores counts in TimescaleDB, and shows live trends in Streamlit.
Pipeline:
HLS (.m3u8) -> ingest -> Redis -> vision worker -> YOLO (MLServer/aiSSEMBLE Inference) -> TimescaleDB -> Streamlit
- Python 3.12 (recommended)
- Docker Desktop (Compose)
- Redis
- TimescaleDB/Postgres
- MLServer YOLO container (
aissemble-inference-yolo) - Optional: Sumy container (
aissemble-inference-sumy) for daily brief generation
Python dependencies are installed from pyproject.toml:
- core app deps: Streamlit, psycopg, redis, opencv, etc.
- optional
aissembleextras for inference deploy tooling/runtimes
From repo root:
rtk python3.12 -m venv .venv
rtk bash -lc 'source .venv/bin/activate && pip install -e ".[dev]"'
cp .env.example .env
rtk bash scripts/run_local_stack.shOpen: http://localhost:8501
What scripts/run_local_stack.sh does:
- Starts Docker services (
redis,timescaledb,yolo) unless skipped - Runs preflight checks (Redis, Postgres, YOLO readiness)
- Runs:
city-pulse-ingestcity-pulse-vision-worker- Streamlit dashboard
Logs:
logs/ingest.loglogs/vision.loglogs/stack-console.log
See .env.example for all options. Most important:
DATABASE_URL,DATABASE_READONLY_URLREDIS_URLYOLO_ENDPOINTINGEST_M3U8_URLINGEST_CAMERA_KEYINGEST_SAMPLE_INTERVAL_SECONDSVISION_MIN_CONFIDENCEVISION_DEBUG_OVERLAY_ENABLED
Advanced counting controls:
VISION_ROI_NORM(normalized ROI:x1,y1,x2,y2)VISION_DEDUP_ENABLEDVISION_DEDUP_IOU_THRESHOLDVISION_DEDUP_TTL_SECONDS
This project is currently optimized for Docker/Compose deployment.
- Build images:
docker compose build yolo-
Set production env vars (
.envor secrets manager): DB/Redis/YOLO endpoints, ingest URL, camera key, and counting thresholds. -
Start services:
docker compose up -d redis timescaledb yolo- Start app processes (systemd/supervisor/containers):
city-pulse-ingestcity-pulse-vision-workerstreamlit run src/city_pulse/dashboard/app.py
- Verify health:
curl -sf http://127.0.0.1:8080/v2/health/ready && echo "YOLO OK"- Use only public, permitted camera feeds.
- Reset DB volume (destructive):
docker compose down -v- Full troubleshooting history:
docs/city-pulse-debugging-retrospective.md