A personal F1 companion app — live race timing, results, qualifying, sprint, standings, and schedule, all in one place.
Unofficial project. Not affiliated with Formula 1 or FOM.
automated-f1-stats/
├── backend/ # Python FastAPI server (data engine)
├── android/ # Android app — Java + Material Design 3
├── .gitignore
└── README.md ← you are here
OpenF1 API ──┐
├──▶ Python Backend ──▶ REST API ──▶ Android App
Jolpica API ──┘ (APScheduler) JSON
- OpenF1 provides live timing during sessions (~1–3s delay)
- Jolpica provides the race calendar, final results, and standings
- APScheduler arms polling jobs automatically based on real session times
- Android app calls your backend over your local network or a deployed server
- Koyeb (or any cloud provider) hosts the backend — configure the URL inside the app without rebuilding
| Software | Version | Why | Download |
|---|---|---|---|
| Python | 3.11+ | Runs the backend | python.org |
| pip | Comes with Python | Installs packages | — |
| Git | Any | Version control | git-scm.com |
Optional but recommended: A code editor — VS Code is free and works great.
⚠️ If you install the VS Code Java extension, make sure Android Studio's Gradle JDK is not accidentally pointing to the VS Code JRE. Setorg.gradle.java.home=C:/Program Files/Android/Android Studio/jbringradle.propertiesif needed.
Once Python is installed, everything else is handled by pip install -r requirements.txt.
| Software | Version | Why | Download |
|---|---|---|---|
| Android Studio | Hedgehog (2023.1.1) or newer | Full Android IDE | developer.android.com/studio |
| JDK (Java) | 17+ | Bundled inside Android Studio | — |
| Android SDK | API 26+ (Android 8.0) | Bundled inside Android Studio | — |
| Gradle | Bundled | Build tool | — |
⚠️ Android Studio is a large download (~1GB installer, ~3–4GB once set up). You do not need to install Java/JDK separately — Android Studio bundles it. A physical Android phone with USB Debugging enabled is recommended over the emulator.
The backend can be deployed to any cloud provider that supports Docker. Recommended free options:
| Option | Cost | Region | Notes |
|---|---|---|---|
| Koyeb | Free tier | Frankfurt | Always-on, no sleep, Docker deploy |
| Railway | $5 credit/month | Frankfurt | Easy GitHub deploy, sleeps on inactivity |
| Render | Free tier | Frankfurt | Similar to Railway, ~30s cold start |
Once deployed, update the backend URL in the Android app via Settings → gear icon — no rebuild needed.
git clone https://github.com/YOUR_USERNAME/automated-f1-stats.git
cd automated-f1-statscd backend
# Create a virtual environment (optional but recommended)
python -m venv venv
venv\Scripts\activate # Windows
source venv/bin/activate # macOS / Linux
# Install dependencies
pip install -r requirements.txt
# Run the server
uvicorn app.main:app --reload --port 8000Backend is live at http://localhost:8000 Interactive API docs at http://localhost:8000/docs
The backend/ folder contains a Dockerfile ready for deployment.
For Koyeb:
- Push repo to GitHub
- Create a new service → GitHub source → Dockerfile builder
- Set Dockerfile location to
backend/Dockerfile, work directory tobackend - Select Frankfurt region, free instance, port 8000
- Deploy
1. Open the /android folder in Android Studio
2. Let Gradle sync and download dependencies
3. Build and run on your device
4. Go to Settings (gear icon, top right)
5. Enter your backend URL (local IP or cloud URL)
| Screen | Features |
|---|---|
| Home | Next race countdown, championship leader with points gap, last race winner with team and race name |
| Live | Live session timing for all session types (Practice, Qualifying, Sprint, Race) |
| Results | Full season round list, race results, qualifying (Q1/Q2/Q3), sprint |
| Standings | Driver and constructor championship tables with DNF counts and podiums |
| Schedule | Full season calendar with all session times |
| Settings | Configure backend URL without rebuilding the app |
- Animated shimmer skeleton on first load
- Instant load from cache on reopen
- Pull-to-refresh with snackbar confirmation on all screens
- Error state with retry button when backend is unreachable
- Season selector on Results and Standings (back to 1950)
- Championship leader shows points gap to P2
- Off-season: shows last season's champion with correct label
- App icon and splash screen (F1 red background)
| Endpoint | Rate Limit | Description |
|---|---|---|
GET /schedule |
30/min | Full race calendar |
GET /schedule/next |
30/min | Next race weekend |
GET /live |
60/min | Live session snapshot |
GET /results/latest |
30/min | Latest race results with race name |
GET /results/{year}/{round} |
60/min | Results for a specific round |
GET /standings/drivers |
30/min | Driver championship standings |
GET /standings/constructors |
30/min | Constructor standings |
GET /sessions/{key}/pit-stops |
30/min | Pit stops |
GET /sessions/{key}/race-control |
— | Flags, safety car messages |
GET /session-key/{year}/{round} |
30/min | OpenF1 session key lookup |
Full docs auto-generated at /docs when the server is running.
- 5 minutes — live/current data (standings, next race, latest results)
- 7 days — historical data (past seasons, completed rounds)
- SQLite — current season standings and results persisted across restarts
| Source | What it provides | Cost |
|---|---|---|
| OpenF1 | Live timing, positions, gaps, tyres, pit stops, weather | Free (historical) / €9.90/mo (live) |
| Jolpica | Race calendar, final results, standings | Free |
- Python backend — FastAPI + APScheduler + SQLite cache
- Dual-tier caching (5-min live, 7-day historical)
- Rate limiting (slowapi — 30–60 req/min per IP)
- Android app — home screen with countdown, leader, last winner
- Android app — live timing screen (all session types)
- Android app — results screen (race, qualifying, sprint)
- Android app — standings screen (drivers + constructors)
- Android app — schedule screen
- Android app — shimmer loading skeleton
- Android app — instant cache load on reopen
- Android app — pull-to-refresh with snackbar on all screens
- Android app — error state with retry button
- Android app — settings screen (configure backend URL without rebuild)
- Android app — season selector (back to 1950)
- Android app — app icon + splash screen
- Off-season fallback (shows last season champion with correct label)
- Backend deployed to cloud (Koyeb — Frankfurt, always-on, free)
- Push notifications for session start / results available
This is an unofficial personal project. All F1 data is sourced from community APIs (OpenF1, Jolpica). Not affiliated with Formula 1, FOM, or any F1 team. F1, FORMULA ONE, and related marks are trademarks of Formula One Licensing BV.