Skip to content

rburketaylor/BahnVision

Repository files navigation

BahnVision

Real-time German transit data API and dashboard. Live departures, station search, and heatmap visualization powered by GTFS data with Valkey caching for fast, reliable responses.

Quick Start

Docker (Recommended)

docker compose up --build

Optional host access to Postgres/Valkey (for local tooling on localhost):

docker compose --profile host-access up --build

Docker + Observability (Prometheus + Grafana)

docker compose -f docker-compose.yml -f docker-compose.observability.yml up --build -d

Configure Grafana login and Prometheus retention in .env:

PROMETHEUS_RETENTION_TIME=7d
PROMETHEUS_RETENTION_SIZE=5GB
GRAFANA_ADMIN_USER=<set-a-custom-admin-username>
GRAFANA_ADMIN_PASSWORD=<set-a-long-random-password>

Local Development

Quick Setup (Recommended):

./scripts/setup-dev.sh   # Downloads Node.js (pinned in `.nvmrc`), sets up Python venv
source .dev-env          # Activate the environment

Auto-loading with direnv (recommended):

# Install direnv
sudo apt install direnv   # Ubuntu/Debian
# or: brew install direnv  # macOS

# Add to ~/.bashrc or ~/.zshrc:
echo 'eval "$(direnv hook bash)"' >> ~/.bashrc   # or zsh
source ~/.bashrc

# Allow the project's .envrc
direnv allow

The dev environment now loads automatically when you cd into the project.

Backend:

cd backend
uvicorn app.main:app --reload

Frontend:

cd frontend
npm run dev

API Endpoints

Endpoint Description
GET /api/v1/transit/stops/search?query=marienplatz Stop search
GET /api/v1/transit/departures?stop_id=de:09162:6 Live departures
GET /api/v1/heatmap/cancellations Heatmap activity data
GET /api/v1/heatmap/overview Heatmap overview
GET /api/v1/health Health check
GET /metrics Prometheus metrics

Response Headers:

  • X-Cache-Status: hit, miss, stale, or stale-refresh (heatmap endpoints)
  • X-Request-Id: Request correlation ID

Configuration

Copy .env.example to .env. Key variables:

Variable Default Description
VALKEY_URL valkey://localhost:6379/0 Cache connection
DATABASE_URL postgresql+asyncpg://... Database connection
VITE_API_BASE_URL http://localhost:8000 Frontend API URL

See docs/runtime-configuration.md for all options.

Testing

# Backend
pytest backend/tests/

# Frontend
cd frontend && npm test

Project Structure

├── backend/
│   ├── app/
│   │   ├── api/          # REST endpoints
│   │   ├── services/     # Business logic, caching
│   │   ├── models/       # Pydantic schemas
│   │   └── persistence/  # Database layer
│   └── tests/
├── frontend/
│   └── src/
│       ├── components/
│       ├── hooks/
│       └── services/
├── docs/                 # Documentation

Architecture

┌─────────────┐      ┌─────────────┐      ┌─────────────┐
│   Frontend  │─────▶│   FastAPI   │─────▶│  GTFS Feed  │
│   (React)   │      │   Backend   │      │  (Germany)  │
└─────────────┘      └──────┬──────┘      └─────────────┘
                           │
              ┌────────────┼────────────┐
              ▼            ▼            ▼
         ┌────────┐  ┌──────────┐  ┌──────────┐
         │ Valkey │  │ Postgres │  │ Fallback │
         │ Cache  │  │   (DB)   │  │  Cache   │
         └────────┘  └──────────┘  └──────────┘

Caching: Requests hit Valkey first. On miss, fetch from GTFS data and cache the result. Stale data is served while refreshing in the background. Circuit breaker falls back to in-memory cache if Valkey is unavailable.

Security Considerations

This project implements several security best practices:

  • Container Security: All containers run as non-root users (appuser, nginx)
  • Security Headers: HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and Permissions-Policy
  • CORS Protection: Strict mode available; wildcard origins rejected by default
  • Rate Limiting: Configurable request limits per minute/hour/day
  • Production Safeguards: Application refuses to start with default credentials in production mode
  • CI/CD Security Scanning: Bandit, Safety, Semgrep, npm audit, and Trivy container scanning

CSP Note: The Content Security Policy currently allows 'unsafe-inline' for compatibility with MapLibre GL's WebGL rendering pipeline.

Contributing

  • Use Conventional Commits (feat:, fix:, docs:)
  • Run tests before submitting PRs
  • See AGENTS.md for AI coding guidelines

About

Cancellation and delay heat map, station search, and application/data collection monitoring for the German public transit system with a cache-first FastAPI backend. React app delivering real-time and historical GTFS(-RT) data, optimized with Valkey caching and PostgreSQL for low-latency responses.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors