Github Heatmap
FastAPI service that receives requests through the GET /heatmap/me endpoint with an Authorization: Bearer <GITHUB_TOKEN> header, reads GitHub contribution activity for the authenticated user, and returns a heatmap-friendly JSON payload.
It was created to integrate with my Django portfolio, but due to its API-first, stateless design it can cooperate with any backend framework. The service is containerized with Docker, and GitHub Actions workflows are included for automated testing and container image build checks. The service was deployed on Google Cloud Run.
Project Structure
github-heatmap/
|- backend/
| |- main.py # FastAPI app factory and app instance
| |- settings.py # Environment-based settings
| |- api/
| | |- schemas/
| | | |- heatmap.py # Pydantic response models
| | |- routes/
| | | |- heatmap.py # API routes/endpoints
| |- services/
| | |- heatmap_service.py # Heatmap business logic
| |- clients/
| | |- github_client.py # GitHub REST/GraphQL requests
| |- core/
| | |- security.py # Bearer token extraction/validation
| | |- observability.py # Sentry initialization
|- tests/
| |- test_main.py # API tests
| |- test_sentry.py # Sentry setup tests
|- docs/
| |- usage.md # Setup and run guide
|- Dockerfile
|- docker-compose.yml
|- pyproject.toml
|- uv.lock
|- .env.example
Showcase
Raw API Response
The service accepts a GitHub Bearer token via the Authorization header and returns a structured JSON payload, ready to be consumed by any frontend or backend.
Rendered Heatmap
The JSON output maps directly to a visual contribution heatmap. Each cell represents a single day; the intensity level drives the color, mimicking the familiar GitHub contribution graph.
Observability
Despite its minimal footprint, the service ships with two layers of observability:
Structured logs streamed to Google Cloud Logging give a real-time view of incoming requests, response times, and lifecycle events.
Sentry.io integration captures and groups exceptions automatically.
Usage
Docker:
docker compose up --build
Run tests:
uv run pytest -v
API endpoints:
GET /- basic hello responseGET /health/live- liveness probeGET /heatmap/me- authenticated heatmap payload (Bearer token required, validated byHeatmapResponsemodel)
See docs/usage.md for full setup details.
Solved Problems
- Converts GitHub contribution calendar into stable weekly heatmap JSON.
- Normalizes raw contribution counts into 5 visual levels (
0..4). - Handles missing/invalid bearer tokens with explicit
401responses. - Maps GitHub auth failures (
401/403) to API-level auth errors.
Roadmap
- Add persistent storage for sync history and caching.
- Add scheduled sync jobs for offline heatmap generation.
- Add metrics/observability (request timing, error rates).
- Add richer filtering options (date range, organization scope).
Detailed info: docs/.
License
MIT License. See LICENSE.