Real-time bus tracking for the Region of Waterloo GRT feeds. This repo includes a FastAPI backend that normalizes GTFS data and a React + Vite frontend that renders live vehicle positions on a map.
- FastAPI backend pulls GTFS‑realtime vehicle positions, caches them in memory, and serves a JSON API.
- Static GTFS parsing provides route metadata (names, colors) and optional shapes for polylines.
- React frontend with Leaflet map markers, MUI UI, and React Query polling.
- Route panel shows vehicle counts by route and a quick overview.
- Backend: FastAPI, HTTPX, GTFS‑realtime protobuf bindings
- Frontend: React + Vite + TypeScript, Leaflet + React‑Leaflet, MUI, React Query, Tailwind
.
├─ backend/ # FastAPI service + GTFS parsing
├─ frontend/ # React app (Vite + TypeScript)
└─ README.md
From backend/:
- Create and activate a virtual environment.
- Install dependencies:
pip install -r requirements.txt
- Create
backend/.env(see the root.env.examplefor a template). - Run the API:
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 --env-file .env
From frontend/:
- Install dependencies:
npm install
- Create
frontend/.env(see the root.env.examplefor a template). - Run the dev server:
npm run dev
Required:
GRT_VEHICLE_POSITIONS_URL— GTFS‑realtime vehicle positions feed URL.GRT_GTFS_STATIC_URL— GTFS static zip URL.
Optional:
GRT_TRIP_UPDATES_URL— trip updates feed URL (required for arrival predictions).GRT_ALERTS_URL— alerts feed URL (not used yet).REFRESH_SECONDS— refresh interval in seconds (default: 30).GRT_ALLOW_WEAK_TLS— allow weak TLS parameters for feeds (use only if required).
GET /healthGET /api/vehiclesGET /api/vehicles/{vehicle_id}GET /api/vehicles/{vehicle_id}/arrivalsGET /api/routes
- Polls
/api/vehiclesevery 10 seconds and/api/routesevery 60 seconds. - Renders vehicles as colored route markers on an OpenStreetMap tile layer.
- Clicking a marker highlights the selected route and draws its GTFS shape (when available).
For container deployments, the frontend Nginx proxy target is runtime-configurable via NGINX_API_UPSTREAM (default backend:80).