Flight Tracker & METAR Dashboard
Your standing reference for building a real-time aircraft tracker from a bare Python interpreter to a deployed Flutter app with a FastAPI backend. Keep this open beside the editor — it's the map, not the walk.
How to use this handbook
You already know how to ship software — mobile apps, React Native, Node, APIs. What you haven't done yet is build something in Python from the ground up, understanding every layer. That's the actual goal. The flight tracker is the vehicle; genuine fluency is the destination.
Rules for using this document
- Don't skip phases because they look "easy." Skipping Phase 1 topics is the single most common reason people stall in Phase 4+.
- Every phase has a Knowledge Checkpoint. If you can't answer it without looking things up, stay in that phase longer.
- When you hit a wall in an interactive AI session, come back here first and re-read the phase's "Why this phase exists" and "Common mistakes" before asking for a code dump.
- This handbook deliberately delays Docker, Kubernetes, Redis, WebSockets, authentication, and AWS — see the Technology Map for why.
Where this ends up
MVP
A Streamlit page that shows live aircraft (from OpenSky) on a PyDeck map, with a searchable table and one airport's METAR weather displayed as text.
Version 1
A FastAPI backend serving /flights and /airports/{icao}/metar, consumed by a Flutter mobile app with a map screen and an aircraft detail screen.
Version 2
Airport search, multiple METAR stations, a details panel with full aircraft state, auto-refresh, and basic caching so the backend — not each user — talks to OpenSky.
Stretch goals
Flight trails, favorite airports/aircraft (needs a database), nearby-aircraft search, WebSocket push updates, user accounts, historical playback, weather alerts, offline caching.
What, and why now
Every technology below solves a specific problem that shows up naturally as the project grows. If you can't explain what problem a tool solves, you're not ready to add it yet — that's a deliberate constraint, not a limitation of this guide.
| Technology | Role | Why here, not earlier/later |
|---|---|---|
| Python | Core language for data + backend | Easiest language to learn API/data fundamentals in; huge ecosystem for this kind of work |
| requests | HTTP calls | Simplest, most standard way to call an API in Python |
| OpenSky API | Live aircraft data source | Free, public, no complicated auth to start |
| Pandas | Structuring/cleaning tabular data | Turns messy JSON into rows/columns you can filter, sort, aggregate |
| Streamlit | Rapid prototyping UI | See your data pipeline working visually without writing a full frontend |
| PyDeck | Map visualization in Streamlit | Purpose-built for plotting geographic points fast |
| AviationWeather.gov | METAR weather data | Official, free, no key required for basic METAR queries |
| FastAPI | Backend API layer | Modern, beginner-friendly, forces real REST + validation (Pydantic) concepts that transfer everywhere |
| Flutter / Dart | Mobile app | Cross-platform from one codebase; your React Native experience speeds up comparisons |
| PostgreSQL | Persistence | Only needed once you want favorites, history, or accounts — not before |
| Docker | Packaging for deployment | Only useful once you're deploying somewhere real |
| AWS | Hosting | Only introduced once there's a concrete reason to pay for/configure infrastructure |
Twenty-two steps, one order
Each track below is color-coded, and the same colors carry through the phase cards further down so you always know which part of the system you're in.
The phases
This is the core of the handbook. Work top to bottom — each phase assumes the ones before it.
Tick these off as you go
Checkboxes are just for this reading session (nothing is saved when you close the tab) — treat this as a working scratchpad while you build, not a permanent tracker.
Pacing, not deadlines
These are structures to guide pacing — go at the speed that produces real understanding.
Self-test at any point
Build in this order
MVP
Streamlit + PyDeck dashboard with live aircraft and one airport's METAR.
Version 1
FastAPI backend + Flutter app with map, aircraft list, and detail screens, consuming the backend over HTTP.
Version 2
Airport search, multiple METAR stations, backend-side caching (single collector, many clients), auto-refresh, cleaner UI polish.
Stretch goals
Pick a few, not all: flight trails, favorites (needs a DB), nearby-aircraft search, WebSocket push updates, user accounts, historical playback, weather alerts, offline caching.
Talking through it confidently
Read this after you've built Phases 0–15, not before — it will mean far more once you've actually written each piece. By the end, you should be able to draw this on a whiteboard and defend every arrow on it, without notes.
The full picture, end to end
The 60-second explanation
Practice saying this out loud until it's natural, not memorized word-for-word:
"It's a real-time flight tracker. A FastAPI backend polls OpenSky for live aircraft and AviationWeather.gov for METAR on independent schedules, caches both in memory, and serves that cache to any number of clients — so I only make one set of upstream API calls no matter how many users are connected. A Flutter mobile app consumes that backend over HTTP, showing aircraft on a map with detail screens, and a small Postgres database persists user-specific data like favorite airports. The interesting engineering problem was decoupling 'how fast does data change' from 'how often do clients ask for it,' which is what the caching layer solves."
Why each boundary exists
Follow-up questions you should be ready for
Self-test
- Draw the diagram from memory.
- Explain what would break if you deleted the lock from the caching code.
- Explain why
PositionHistory(if you build it) is a deliberate feature, not a byproduct of caching. - Explain, in your own words, the difference between what OpenSky's rate limits protect against and what your own cache protects against — they are not the same concern.
Making it read as a real portfolio piece
What makes it impressive
A clear separation between data layer, backend, and client; sensible caching so it doesn't hammer a public API; visible error handling; and evidence (via the README/limitations section) that you understand the tradeoffs you made, not just that you made it work.
Documentation, linked
This handbook is the map
Your separate interactive AI mentor session is where you'll actually debug and iterate. To use that session well:
- Bring the relevant phase's concepts and checkpoint with you before asking for help.
- When something breaks, ask "why doesn't this work" before "fix this" — get the explanation first.
- Expect (and ask for) small modification exercises after any code you're given, so you practice changing working code, not just receiving it.
- If you notice yourself asking for full implementations repeatedly without understanding them, that's a signal to slow down, not a signal the tool is failing you.
- Come back to this document at the start of each new phase and re-read the "Why this phase exists" and "Common mistakes" sections — most stuck points map directly onto something already flagged here.
Good luck — build it slow enough that you actually understand it.