Overview¤
| Name | Low-level API | Service and Cache Location |
|---|---|---|
| Flight List JSON |
flight_listflight_list_df |
FlightListServiceCache Location: flight_list/└── reg/└── {reg.upper()}.parquet└── flight_list/└── {iata_flight_num.upper()}.parquet |
| Playback JSON |
playbackplayback_df |
PlaybackServiceCache Location: playback/└── {fr24_hex_id.upper()}.parquet |
| Live Feed gRPC |
live_feedlive_feed_df |
LiveFeedServiceCache Location: feed/└── {timestamp_s}.parquet |
| Live Feed Playback gRPC |
live_feed_playbacklive_feed_df |
LiveFeedPlaybackServiceCache Location: feed/└── {timestamp_s}.parquet |
| Airport List JSON |
airport_list |
AirportListService |
| Airport Search JSON |
find |
FindService |
| Nearest Flights gRPC |
nearest_flights |
NearestFlightsServiceCache Location: nearest_flights/└── {lon_x1e6}_{lat_x1e6}_{timestamp_s}.parquet |
| Live Flight Status gRPC |
live_flights_status |
LiveFlightsStatusServiceCache Location: live_flights_status/└── {timestamp_s}.parquet |
gRPC |
search_index |
- |
| Follow Flight gRPC |
follow_flight_stream |
FollowFlightService |
| Top Flights gRPC |
top_flights |
TopFlightsServiceCache Location: top_flights/└── {timestamp_s}.parquet |
gRPC |
live_trail |
- |
gRPC |
historic_trail |
- |
| Flight Details gRPC |
flight_details |
FlightDetailsServiceCache Location: flight_details/└── {flight_id}_{timestamp_s}.parquet |
| Playback Flight gRPC |
playback_flight |
PlaybackFlightServiceCache Location: playback_flight/└── {flight_id}_{timestamp_s}.parquet |
You can find even more usage examples under tests/.
FR24 services¤
Flight list¤
Single page¤
from fr24 import FR24, FR24Cache
async def my_list() -> None:
async with FR24() as fr24:
result = await fr24.flight_list.fetch(reg="B-LRA", filter_by="historic")
print(result.to_polars())
result.write_table(FR24Cache.default())
await my_list()
shape: (10, 15)
┌────────────┬────────┬──────────┬─────────┬───┬────────────┬────────────┬────────────┬────────────┐
│ flight_id ┆ number ┆ callsign ┆ icao24 ┆ … ┆ ATOD ┆ STOA ┆ ETOA ┆ ATOA │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │
│ u64 ┆ str ┆ str ┆ u32 ┆ ┆ datetime[m ┆ datetime[m ┆ datetime[m ┆ datetime[m │
│ ┆ ┆ ┆ ┆ ┆ s, UTC] ┆ s, UTC] ┆ s, UTC] ┆ s, UTC] │
╞════════════╪════════╪══════════╪═════════╪═══╪════════════╪════════════╪════════════╪════════════╡
│ 1011667820 ┆ CX170 ┆ CPA170 ┆ 7867035 ┆ … ┆ 2025-09-20 ┆ 2025-09-20 ┆ null ┆ 2025-09-21 │
│ ┆ ┆ ┆ ┆ ┆ 16:46:55 ┆ 23:55:00 ┆ ┆ 00:21:13 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 1011554520 ┆ CX171 ┆ CPA171 ┆ 7867035 ┆ … ┆ 2025-09-20 ┆ 2025-09-20 ┆ null ┆ 2025-09-20 │
│ ┆ ┆ ┆ ┆ ┆ 07:20:40 ┆ 14:40:00 ┆ ┆ 14:21:27 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 1011435329 ┆ CX648 ┆ CPA648 ┆ 7867035 ┆ … ┆ 2025-09-19 ┆ 2025-09-20 ┆ null ┆ 2025-09-20 │
│ ┆ ┆ ┆ ┆ ┆ 18:23:36 ┆ 02:55:00 ┆ ┆ 02:52:15 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 1011284495 ┆ CX647 ┆ CPA647 ┆ 7867035 ┆ … ┆ 2025-09-19 ┆ 2025-09-19 ┆ null ┆ 2025-09-19 │
│ ┆ ┆ ┆ ┆ ┆ 07:20:48 ┆ 16:10:00 ┆ ┆ 15:42:45 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 1011171753 ┆ CX648 ┆ CPA648 ┆ 7867035 ┆ … ┆ 2025-09-18 ┆ 2025-09-19 ┆ null ┆ 2025-09-19 │
│ ┆ ┆ ┆ ┆ ┆ 19:38:57 ┆ 04:05:00 ┆ ┆ 03:59:35 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 1011026581 ┆ CX647 ┆ CPA647 ┆ 7867035 ┆ … ┆ 2025-09-18 ┆ 2025-09-18 ┆ null ┆ 2025-09-18 │
│ ┆ ┆ ┆ ┆ ┆ 09:07:57 ┆ 17:25:00 ┆ ┆ 17:44:23 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 1010931855 ┆ CX110 ┆ CPA110 ┆ 7867035 ┆ … ┆ 2025-09-17 ┆ 2025-09-18 ┆ null ┆ 2025-09-18 │
│ ┆ ┆ ┆ ┆ ┆ 22:11:58 ┆ 07:15:00 ┆ ┆ 06:51:33 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 1010788305 ┆ CX111 ┆ CPA111 ┆ 7867035 ┆ … ┆ 2025-09-17 ┆ 2025-09-17 ┆ null ┆ 2025-09-17 │
│ ┆ ┆ ┆ ┆ ┆ 11:44:15 ┆ 20:10:00 ┆ ┆ 20:34:57 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 1010538830 ┆ CX300 ┆ CPA300 ┆ 7867035 ┆ … ┆ 2025-09-16 ┆ 2025-09-16 ┆ null ┆ 2025-09-16 │
│ ┆ ┆ ┆ ┆ ┆ 12:53:57 ┆ 22:50:00 ┆ ┆ 23:01:10 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 1010340276 ┆ CX301 ┆ CPA301 ┆ 7867035 ┆ … ┆ 2025-09-15 ┆ 2025-09-16 ┆ null ┆ 2025-09-16 │
│ ┆ ┆ ┆ ┆ ┆ 17:30:58 ┆ 05:55:00 ┆ ┆ 06:24:16 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
└────────────┴────────┴──────────┴─────────┴───┴────────────┴────────────┴────────────┴────────────┘
Paginate all pages¤
Queries for next page as long as user doesn't enter x, or if there are no pages left.
In each iteration, rows are upserted and saved to the cache.
Note that pagination cannot be run in parallel: fetching page N requires information from page N-1.
from fr24 import FR24, FR24Cache
cache = FR24Cache.default()
async def my_full_list() -> None:
async with FR24() as fr24:
results = fr24.flight_list.new_result_collection() # (1)!
async for result in fr24.flight_list.fetch_all(reg="B-LRA"):
results.append(result) # (2)!
if input() == "x":
break
results.write_table(cache)
print(results.to_polars()) # (3)!
await my_full_list()
- Create a new result collections, a list under the hood.
- Appends the current flight list to the collection. Note that it does not remove duplicates.
- Merges the collections into a single table. Removes duplicates (if any).
shape: (22, 15)
┌───────────┬────────┬──────────┬─────────┬───┬─────────────┬────────────┬────────────┬────────────┐
│ flight_id ┆ number ┆ callsign ┆ icao24 ┆ … ┆ ATOD ┆ STOA ┆ ETOA ┆ ATOA │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │
│ u64 ┆ str ┆ str ┆ u32 ┆ ┆ datetime[ms ┆ datetime[m ┆ datetime[m ┆ datetime[m │
│ ┆ ┆ ┆ ┆ ┆ , UTC] ┆ s, UTC] ┆ s, UTC] ┆ s, UTC] │
╞═══════════╪════════╪══════════╪═════════╪═══╪═════════════╪════════════╪════════════╪════════════╡
│ 952283415 ┆ CX382 ┆ CPA382 ┆ 7867035 ┆ … ┆ 2025-01-17 ┆ 2025-01-17 ┆ null ┆ 2025-01-17 │
│ ┆ ┆ ┆ ┆ ┆ 11:14:41 ┆ 22:25:00 ┆ ┆ 22:15:37 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 952264050 ┆ CX383 ┆ CPA383 ┆ 7867035 ┆ … ┆ null ┆ null ┆ null ┆ null │
│ 952125211 ┆ CX383 ┆ CPA383 ┆ 7867035 ┆ … ┆ 2025-01-16 ┆ 2025-01-17 ┆ null ┆ 2025-01-17 │
│ ┆ ┆ ┆ ┆ ┆ 17:57:05 ┆ 06:30:00 ┆ ┆ 06:53:54 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 951961210 ┆ CX710 ┆ CPA710 ┆ 7867035 ┆ … ┆ 2025-01-16 ┆ 2025-01-16 ┆ null ┆ 2025-01-16 │
│ ┆ ┆ ┆ ┆ ┆ 00:15:55 ┆ 03:55:00 ┆ ┆ 03:38:15 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 951777224 ┆ CX735 ┆ CPA735 ┆ 7867035 ┆ … ┆ 2025-01-15 ┆ 2025-01-15 ┆ null ┆ 2025-01-15 │
│ ┆ ┆ ┆ ┆ ┆ 06:44:49 ┆ 10:25:00 ┆ ┆ 10:31:32 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 951229708 ┆ CX624 ┆ CPA624 ┆ 7867035 ┆ … ┆ 2025-01-12 ┆ 2025-01-13 ┆ null ┆ 2025-01-13 │
│ ┆ ┆ ┆ ┆ ┆ 20:15:14 ┆ 01:30:00 ┆ ┆ 00:59:37 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 951146643 ┆ CX623 ┆ CPA623 ┆ 7867035 ┆ … ┆ 2025-01-12 ┆ 2025-01-12 ┆ null ┆ 2025-01-12 │
│ ┆ ┆ ┆ ┆ ┆ 12:57:58 ┆ 18:55:00 ┆ ┆ 18:23:19 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 951012767 ┆ CX714 ┆ CPA714 ┆ 7867035 ┆ … ┆ 2025-01-11 ┆ 2025-01-11 ┆ null ┆ 2025-01-11 │
│ ┆ ┆ ┆ ┆ ┆ 18:55:20 ┆ 21:10:00 ┆ ┆ 22:05:36 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 950956719 ┆ CX715 ┆ CPA715 ┆ 7867035 ┆ … ┆ 2025-01-11 ┆ 2025-01-11 ┆ null ┆ 2025-01-11 │
│ ┆ ┆ ┆ ┆ ┆ 13:03:44 ┆ 16:25:00 ┆ ┆ 16:29:15 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 950873921 ┆ CX162 ┆ CPA162 ┆ 7867035 ┆ … ┆ 2025-01-11 ┆ 2025-01-11 ┆ null ┆ 2025-01-11 │
│ ┆ ┆ ┆ ┆ ┆ 01:09:49 ┆ 09:30:00 ┆ ┆ 09:41:27 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
└───────────┴────────┴──────────┴─────────┴───┴─────────────┴────────────┴────────────┴────────────┘
Playback¤
Miracle on the Hudson¤
Downloads the flight trajectory for UA1549
import rich
from fr24 import FR24, FR24Cache
async def my_playback() -> None:
async with FR24() as fr24:
result = await fr24.playback.fetch(0x2FB3041) # (1)!
df = result.to_polars()
print(df)
rich.print(result.metadata())
result.write_table(FR24Cache.default())
await my_playback()
shape: (363, 9)
┌────────────┬───────────┬────────────┬──────────┬───┬───────────────┬───────┬────────┬────────────┐
│ timestamp ┆ latitude ┆ longitude ┆ altitude ┆ … ┆ vertical_spee ┆ track ┆ squawk ┆ ems │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ d ┆ --- ┆ --- ┆ --- │
│ u32 ┆ f32 ┆ f32 ┆ i32 ┆ ┆ --- ┆ i16 ┆ u16 ┆ struct[18] │
│ ┆ ┆ ┆ ┆ ┆ i16 ┆ ┆ ┆ │
╞════════════╪═══════════╪════════════╪══════════╪═══╪═══════════════╪═══════╪════════╪════════════╡
│ 1232049993 ┆ 40.770302 ┆ -73.862801 ┆ 0 ┆ … ┆ null ┆ 59 ┆ 0 ┆ null │
│ 1232049997 ┆ 40.770302 ┆ -73.862503 ┆ 0 ┆ … ┆ null ┆ 65 ┆ 0 ┆ null │
│ 1232050001 ┆ 40.770302 ┆ -73.862198 ┆ 0 ┆ … ┆ null ┆ 71 ┆ 0 ┆ null │
│ 1232050005 ┆ 40.770302 ┆ -73.862198 ┆ 0 ┆ … ┆ null ┆ 76 ┆ 0 ┆ null │
│ 1232050009 ┆ 40.770302 ┆ -73.862198 ┆ 0 ┆ … ┆ null ┆ 82 ┆ 0 ┆ null │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 1232051425 ┆ 40.781399 ┆ -73.998199 ┆ 326 ┆ … ┆ null ┆ 223 ┆ 0 ┆ null │
│ 1232051429 ┆ 40.779202 ┆ -73.999603 ┆ 274 ┆ … ┆ null ┆ 226 ┆ 0 ┆ null │
│ 1232051433 ┆ 40.777199 ┆ -74.001297 ┆ 187 ┆ … ┆ null ┆ 222 ┆ 0 ┆ null │
│ 1232051437 ┆ 40.775002 ┆ -74.002899 ┆ 106 ┆ … ┆ null ┆ 223 ┆ 0 ┆ null │
│ 1232051441 ┆ 40.773102 ┆ -74.004303 ┆ 42 ┆ … ┆ null ┆ 223 ┆ 0 ┆ null │
└────────────┴───────────┴────────────┴──────────┴───┴───────────────┴───────┴────────┴────────────┘
{
"flight_id": 50016321,
"callsign": "AWE1549",
"flight_number": "UA1549",
"status_type": "departure",
"status_text": None,
"status_diverted": None,
"status_time": None,
"model_code": "A320",
"icao24": 10493137,
"registration": "N106US",
"owner": None,
"airline": None,
"origin": "KLGA",
"destination": "KCLT",
"median_delay": None,
"median_time": None,
}
File operations¤
Saves trajectory data to disk, reads the track and metadata from it.
import rich
from fr24 import FR24, FR24Cache
cache = FR24Cache.default()
async def my_playback() -> None:
async with FR24() as fr24:
result = await fr24.playback.fetch(0x2FB3041)
result.write_table(cache) # (1)!
# some time later...
df_local = cache.playback.scan_table(0x2FB3041).collect() # (2)!
print(df_local)
await my_playback()
shape: (363, 9)
┌────────────┬───────────┬────────────┬──────────┬───┬───────────────┬───────┬────────┬────────────┐
│ timestamp ┆ latitude ┆ longitude ┆ altitude ┆ … ┆ vertical_spee ┆ track ┆ squawk ┆ ems │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ d ┆ --- ┆ --- ┆ --- │
│ u32 ┆ f32 ┆ f32 ┆ i32 ┆ ┆ --- ┆ i16 ┆ u16 ┆ struct[18] │
│ ┆ ┆ ┆ ┆ ┆ i16 ┆ ┆ ┆ │
╞════════════╪═══════════╪════════════╪══════════╪═══╪═══════════════╪═══════╪════════╪════════════╡
│ 1232049993 ┆ 40.770302 ┆ -73.862801 ┆ 0 ┆ … ┆ null ┆ 59 ┆ 0 ┆ null │
│ 1232049997 ┆ 40.770302 ┆ -73.862503 ┆ 0 ┆ … ┆ null ┆ 65 ┆ 0 ┆ null │
│ 1232050001 ┆ 40.770302 ┆ -73.862198 ┆ 0 ┆ … ┆ null ┆ 71 ┆ 0 ┆ null │
│ 1232050005 ┆ 40.770302 ┆ -73.862198 ┆ 0 ┆ … ┆ null ┆ 76 ┆ 0 ┆ null │
│ 1232050009 ┆ 40.770302 ┆ -73.862198 ┆ 0 ┆ … ┆ null ┆ 82 ┆ 0 ┆ null │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 1232051425 ┆ 40.781399 ┆ -73.998199 ┆ 326 ┆ … ┆ null ┆ 223 ┆ 0 ┆ null │
│ 1232051429 ┆ 40.779202 ┆ -73.999603 ┆ 274 ┆ … ┆ null ┆ 226 ┆ 0 ┆ null │
│ 1232051433 ┆ 40.777199 ┆ -74.001297 ┆ 187 ┆ … ┆ null ┆ 222 ┆ 0 ┆ null │
│ 1232051437 ┆ 40.775002 ┆ -74.002899 ┆ 106 ┆ … ┆ null ┆ 223 ┆ 0 ┆ null │
│ 1232051441 ┆ 40.773102 ┆ -74.004303 ┆ 42 ┆ … ┆ null ┆ 223 ┆ 0 ┆ null │
└────────────┴───────────┴────────────┴──────────┴───┴───────────────┴───────┴────────┴────────────┘
{
"flight_id": 50016321,
"callsign": "AWE1549",
"flight_number": "UA1549",
"status_type": "departure",
"status_text": None,
"status_diverted": None,
"status_time": None,
"model_code": "A320",
"icao24": 10493137,
"registration": "N106US",
"owner": None,
"airline": None,
"origin": "KLGA",
"destination": "KCLT",
"median_delay": None,
"median_time": None,
}
Airport List¤
import httpx
from fr24.types.json import AirportList
from fr24.json import airport_list, AirportListParams
from fr24.proto.headers import get_grpc_headers
import polars as pl
async def my_arrivals() -> AirportList:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
response = await airport_list(
client,
AirportListParams(airport="tls", mode="arrivals"),
headers=headers,
auth=None,
)
response.raise_for_status()
list_ = response.json()
return list_ # type: ignore
airports = await my_arrivals()
arrivals = airports["result"]["response"]["airport"]["pluginData"]["schedule"][
"arrivals"
]["data"]
assert arrivals is not None
df = pl.json_normalize(arrivals)
print(df)
shape: (10, 76)
┌───────────┬───────────┬───────────┬───────────┬───┬───────────┬───────────┬───────────┬──────────┐
│ flight.id ┆ flight.id ┆ flight.id ┆ flight.id ┆ … ┆ flight.ti ┆ flight.ai ┆ flight.ow ┆ flight.a │
│ entificat ┆ entificat ┆ entificat ┆ entificat ┆ ┆ me.other. ┆ rcraft.im ┆ ner ┆ irline │
│ ion.id ┆ ion.row ┆ ion.numbe ┆ ion.numbe ┆ ┆ duration ┆ ages ┆ --- ┆ --- │
│ --- ┆ --- ┆ r.d… ┆ r.a… ┆ ┆ --- ┆ --- ┆ null ┆ null │
│ str ┆ i64 ┆ --- ┆ --- ┆ ┆ null ┆ null ┆ ┆ │
│ ┆ ┆ str ┆ str ┆ ┆ ┆ ┆ ┆ │
╞═══════════╪═══════════╪═══════════╪═══════════╪═══╪═══════════╪═══════════╪═══════════╪══════════╡
│ 3963916d ┆ 563063588 ┆ AF6132 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 1 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ null ┆ 563365562 ┆ null ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 4 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 39638d76 ┆ 563085809 ┆ T71527 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 3963a803 ┆ 563063662 ┆ AF7408 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 396399a4 ┆ 563087474 ┆ U24849 ┆ EC4849 ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 7 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ null ┆ 563088423 ┆ V72371 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 4 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 3963978d ┆ 563085809 ┆ T73718 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 1 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 3963ab98 ┆ 563089434 ┆ XK720 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 8 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 396398ab ┆ 563071223 ┆ FR3903 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 6 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 3963b61f ┆ 563072081 ┆ GP155 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 9 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
└───────────┴───────────┴───────────┴───────────┴───┴───────────┴───────────┴───────────┴──────────┘
Airport Search¤
from fr24.types.json import Find
from fr24 import FR24
import polars as pl
async def my_find() -> Find:
async with FR24() as fr24:
result = await fr24.find.fetch(query="paris")
return result.to_dict()
results = await my_find()
df = pl.json_normalize(results["results"])
print(df)
shape: (9, 7)
┌─────┬───────────────────────────────┬─────────┬──────────┬────────────┬────────────┬─────────────┐
│ id ┆ label ┆ type ┆ match ┆ detail.lat ┆ detail.lon ┆ detail.size │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ str ┆ str ┆ str ┆ f64 ┆ f64 ┆ i64 │
╞═════╪═══════════════════════════════╪═════════╪══════════╪════════════╪════════════╪═════════════╡
│ CDG ┆ Paris Charles de Gaulle ┆ airport ┆ begins ┆ 49.012516 ┆ 2.555752 ┆ 201280 │
│ ┆ Airpor… ┆ ┆ ┆ ┆ ┆ │
│ ORY ┆ Paris Orly Airport (ORY / ┆ airport ┆ begins ┆ 48.723331 ┆ 2.379444 ┆ 84510 │
│ ┆ LFPO… ┆ ┆ ┆ ┆ ┆ │
│ LBG ┆ Paris Le Bourget Airport (LBG ┆ airport ┆ begins ┆ 48.958801 ┆ 2.4336 ┆ 24465 │
│ ┆ … ┆ ┆ ┆ ┆ ┆ │
│ BVA ┆ Paris Beauvais-Tille Airport ┆ airport ┆ begins ┆ 49.453465 ┆ 2.115138 ┆ 15939 │
│ ┆ (… ┆ ┆ ┆ ┆ ┆ │
│ VIY ┆ Paris Villacoublay Velizy Air ┆ airport ┆ begins ┆ 48.774399 ┆ 2.20154 ┆ 1038 │
│ ┆ … ┆ ┆ ┆ ┆ ┆ │
│ PRX ┆ Paris Cox Field (PRX / KPRX) ┆ airport ┆ begins ┆ 33.636665 ┆ -95.450279 ┆ 953 │
│ XCR ┆ Paris Vatry Chalons Airport ┆ airport ┆ begins ┆ 48.759998 ┆ 4.2 ┆ 710 │
│ ┆ (X… ┆ ┆ ┆ ┆ ┆ │
│ PHT ┆ Paris Henry County Airport ┆ airport ┆ begins ┆ 36.336384 ┆ -88.38427 ┆ 199 │
│ ┆ (PH… ┆ ┆ ┆ ┆ ┆ │
│ OPL ┆ Opelousas St. Landry Parish ┆ airport ┆ contains ┆ 30.555695 ┆ -92.098915 ┆ 194 │
│ ┆ Ai… ┆ ┆ ┆ ┆ ┆ │
└─────┴───────────────────────────────┴─────────┴──────────┴────────────┴────────────┴─────────────┘
Live Feed¤
Live¤
This example is covered in detail in the quickstart.
from fr24 import FR24, FR24Cache, BoundingBox
bbox = BoundingBox(south=42, north=52, west=-8, east=10)
async def my_feed() -> None:
async with FR24() as fr24:
result = await fr24.live_feed.fetch(bbox)
print(result)
print(result.to_dict())
print(result.to_polars())
result.write_table(FR24Cache.default())
await my_feed()
LiveFeedResult(
request=LiveFeedParams(
bounding_box=BoundingBox(south=42, north=52, west=-8, east=10),
stats=False,
limit=1500,
maxage=14400,
fields={"reg", "route", "flight", "type"},
),
response=<Response [200 OK]>,
timestamp=1753150332,
)
{
"flights_list": [
{
"flightid": 995827034,
"lat": 43.11081,
"lon": -4.72674,
"track": 23,
"alt": 43000,
"speed": 513,
"icon": "A330",
"timestamp": 1753150329,
"callsign": "AFR407",
"extra_info": {
"flight": "AF407",
"reg": "F-HTYA",
"route": {"from": "SCL", "to": "CDG"},
"type": "A359",
},
"position_buffer": {
"recent_positions_list": [
{"delta_lat": 247, "delta_lon": 146, "delta_ms": 1088},
{"delta_lat": 434, "delta_lon": 255, "delta_ms": 2013},
{"delta_lat": 664, "delta_lon": 392, "delta_ms": 3038},
{"delta_lat": 958, "delta_lon": 568, "delta_ms": 4375},
{"delta_lat": 1172, "delta_lon": 699, "delta_ms": 5375},
{"delta_lat": 1382, "delta_lon": 817, "delta_ms": 6313},
{"delta_lat": 1707, "delta_lon": 1013, "delta_ms": 7875},
{"delta_lat": 2000, "delta_lon": 1189, "delta_ms": 9163},
{"delta_lat": 2252, "delta_lon": 1334, "delta_ms": 10288},
]
},
"timestamp_ms": "1753150329391",
},
...
],
"server_time_ms": "1753150332065",
}
shape: (171, 18)
┌──────────────┬───────────┬───────────┬───────────┬───┬─────┬────────┬──────────────┬─────────────┐
│ timestamp ┆ flightid ┆ latitude ┆ longitude ┆ … ┆ eta ┆ squawk ┆ vertical_spe ┆ position_bu │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ ed ┆ ffer │
│ datetime[ms, ┆ u32 ┆ f32 ┆ f32 ┆ ┆ u32 ┆ u16 ┆ --- ┆ --- │
│ UTC] ┆ ┆ ┆ ┆ ┆ ┆ ┆ i16 ┆ list[struct │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ [3]] │
╞══════════════╪═══════════╪═══════════╪═══════════╪═══╪═════╪════════╪══════════════╪═════════════╡
│ 2025-07-22 ┆ 995827034 ┆ 43.110809 ┆ -4.72674 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [{247,146,1 │
│ 02:12:09.391 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 088}, {434, │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 255,2013… │
│ 2025-07-22 ┆ 995947452 ┆ 43.176819 ┆ -3.079877 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [{210,95,10 │
│ 02:12:09.762 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 90}, {421,1 │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 91,2110}… │
│ 2025-07-22 ┆ 995945816 ┆ 42.667923 ┆ -2.855509 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [{45,-137,1 │
│ 02:12:10.242 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 140}, {149, │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ -455,377… │
│ 2025-07-22 ┆ 995924443 ┆ 45.168983 ┆ -3.100891 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [{299,307,1 │
│ 02:12:10.116 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 540}, {514, │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 529,2610… │
│ 2025-07-22 ┆ 995916683 ┆ 45.573853 ┆ -2.016594 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [{192,174,9 │
│ 02:12:09.579 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 90}, {370,3 │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 28,1880}… │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 2025-07-22 ┆ 995956094 ┆ 51.458233 ┆ 5.390149 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [{0,0,4902} │
│ 02:12:06.528 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ , {0,0,1000 │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 4}] │
│ 2025-07-22 ┆ 995956104 ┆ 51.45718 ┆ 5.388998 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [{0,0,5030} │
│ 02:12:06.722 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ , {0,0,1010 │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 0}] │
│ 2025-07-22 ┆ 995957785 ┆ 51.915054 ┆ 6.172904 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [{21,-324,9 │
│ 02:12:09.788 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 85}, {53,-6 │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 82,1980}… │
│ 2025-07-22 ┆ 995959079 ┆ 51.789047 ┆ 8.022098 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [{123,475,2 │
│ 02:12:09.029 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 309}, {186, │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 711,3455… │
│ 2025-07-22 ┆ 995949304 ┆ 51.774536 ┆ 8.631542 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [{27,-527,1 │
│ 02:12:09.460 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 535}, {45,- │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 920,2677… │
└──────────────┴───────────┴───────────┴───────────┴───┴─────┴────────┴──────────────┴─────────────┘
"""
# %%
from fr24 import FR24, BoundingBox
import time
yesterday = int(time.time() - 86400)
bbox = BoundingBox(south=42, north=52, west=-8, east=10)
async def my_feed() -> None:
async with FR24() as fr24:
result = await fr24.live_feed_playback.fetch(bbox, timestamp=yesterday)
print(result.to_polars())
await my_feed()
# %%
"""
shape: (139, 18)
┌──────────────┬───────────┬───────────┬───────────┬───┬─────┬────────┬──────────────┬─────────────┐
│ timestamp ┆ flightid ┆ latitude ┆ longitude ┆ … ┆ eta ┆ squawk ┆ vertical_spe ┆ position_bu │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ ed ┆ ffer │
│ datetime[ms, ┆ u32 ┆ f32 ┆ f32 ┆ ┆ u32 ┆ u16 ┆ --- ┆ --- │
│ UTC] ┆ ┆ ┆ ┆ ┆ ┆ ┆ i16 ┆ list[struct │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ [3]] │
╞══════════════╪═══════════╪═══════════╪═══════════╪═══╪═════╪════════╪══════════════╪═════════════╡
│ 2025-07-21 ┆ 995593418 ┆ 43.238297 ┆ -4.690012 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.408 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995708427 ┆ 42.489532 ┆ 1.29364 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.430 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995704634 ┆ 42.442608 ┆ -2.886849 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.895 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995658391 ┆ 43.957397 ┆ -7.309677 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.852 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995709110 ┆ 42.351471 ┆ 4.712822 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:59.310 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 2025-07-21 ┆ 995713747 ┆ 50.823303 ┆ 7.588361 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:59.020 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995713721 ┆ 50.925819 ┆ 7.402649 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.966 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995714247 ┆ 50.87875 ┆ 7.124541 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:54.967 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995715577 ┆ 50.983913 ┆ 7.240559 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.219 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995714961 ┆ 50.878696 ┆ 7.126026 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:59.524 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
└──────────────┴───────────┴───────────┴───────────┴───┴─────┴────────┴──────────────┴─────────────┘
"""
Playback¤
Fetches the live feed three days ago.
from fr24 import FR24, BoundingBox
import time
yesterday = int(time.time() - 86400)
bbox = BoundingBox(south=42, north=52, west=-8, east=10)
async def my_feed() -> None:
async with FR24() as fr24:
result = await fr24.live_feed_playback.fetch(bbox, timestamp=yesterday)
print(result.to_polars())
await my_feed()
shape: (139, 18)
┌──────────────┬───────────┬───────────┬───────────┬───┬─────┬────────┬──────────────┬─────────────┐
│ timestamp ┆ flightid ┆ latitude ┆ longitude ┆ … ┆ eta ┆ squawk ┆ vertical_spe ┆ position_bu │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ ed ┆ ffer │
│ datetime[ms, ┆ u32 ┆ f32 ┆ f32 ┆ ┆ u32 ┆ u16 ┆ --- ┆ --- │
│ UTC] ┆ ┆ ┆ ┆ ┆ ┆ ┆ i16 ┆ list[struct │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ [3]] │
╞══════════════╪═══════════╪═══════════╪═══════════╪═══╪═════╪════════╪══════════════╪═════════════╡
│ 2025-07-21 ┆ 995593418 ┆ 43.238297 ┆ -4.690012 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.408 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995708427 ┆ 42.489532 ┆ 1.29364 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.430 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995704634 ┆ 42.442608 ┆ -2.886849 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.895 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995658391 ┆ 43.957397 ┆ -7.309677 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.852 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995709110 ┆ 42.351471 ┆ 4.712822 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:59.310 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 2025-07-21 ┆ 995713747 ┆ 50.823303 ┆ 7.588361 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:59.020 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995713721 ┆ 50.925819 ┆ 7.402649 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.966 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995714247 ┆ 50.87875 ┆ 7.124541 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:54.967 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995715577 ┆ 50.983913 ┆ 7.240559 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:58.219 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 2025-07-21 ┆ 995714961 ┆ 50.878696 ┆ 7.126026 ┆ … ┆ 0 ┆ 0 ┆ 0 ┆ [] │
│ 02:15:59.524 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
└──────────────┴───────────┴───────────┴───────────┴───┴─────┴────────┴──────────────┴─────────────┘
Nearest Flights¤
from fr24 import FR24, FR24Cache
async def my_nearest_flights() -> None:
async with FR24() as fr24:
result = await fr24.nearest_flights.fetch(
lat=22.31257, lon=113.92708, radius=10000, limit=1500
)
print(result)
print(result.to_dict())
print(result.to_polars())
result.write_table(FR24Cache.default())
await my_nearest_flights()
NearestFlightsResult(
request=NearestFlightsParams(
lat=22.31257,
lon=113.92708,
radius=10000,
limit=1500
),
response=<Response [200 OK]>,
timestamp=1748177063
)
{
'flights_list': [
{
'flight': {
'flightid': 981376678,
'lat': 22.315142,
'lon': 113.92878,
'track': 67,
'timestamp': 1748178906,
'on_ground': True,
'extra_info': {'reg': 'B-18663', 'route': {'from': 'HKG'}, 'type': 'B738', 'logo_id': 86},
'timestamp_ms': '1748178906661'
},
'distance': 334
},
...
{
'flight': {
'flightid': 981339515,
'lat': 22.305908,
'lon': 113.83389,
'track': 71,
'alt': 875,
'speed': 130,
'icon': 'A330',
'timestamp': 1748178957,
'callsign': 'CPA381',
'extra_info': {
'flight': 'CX381',
'reg': 'B-LBJ',
'route': {'from': 'PVG', 'to': 'HKG'},
'type': 'A333',
'logo_id': 57
},
'timestamp_ms': '1748178957019'
},
'distance': 9629
}
]
}
shape: (20, 19)
┌────────────┬───────────┬───────────┬────────────┬───┬────────────┬────────┬───────────┬──────────┐
│ timestamp ┆ flightid ┆ latitude ┆ longitude ┆ … ┆ vertical_s ┆ squawk ┆ position_ ┆ distance │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ peed ┆ --- ┆ buffer ┆ --- │
│ u32 ┆ u32 ┆ f32 ┆ f32 ┆ ┆ --- ┆ u16 ┆ --- ┆ u32 │
│ ┆ ┆ ┆ ┆ ┆ i16 ┆ ┆ list[stru ┆ │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ct[3]] ┆ │
╞════════════╪═══════════╪═══════════╪════════════╪═══╪════════════╪════════╪═══════════╪══════════╡
│ 1748178906 ┆ 981376678 ┆ 22.315142 ┆ 113.92878 ┆ … ┆ 0 ┆ 0 ┆ [] ┆ 334 │
│ 1748178954 ┆ 981376632 ┆ 22.313118 ┆ 113.923676 ┆ … ┆ 0 ┆ 0 ┆ [] ┆ 355 │
│ 1748178953 ┆ 981376221 ┆ 22.31551 ┆ 113.929932 ┆ … ┆ 0 ┆ 0 ┆ [] ┆ 438 │
│ 1748178957 ┆ 981355789 ┆ 22.315166 ┆ 113.923164 ┆ … ┆ 0 ┆ 0 ┆ [] ┆ 495 │
│ 1748178958 ┆ 981375544 ┆ 22.313187 ┆ 113.921371 ┆ … ┆ 0 ┆ 0 ┆ [] ┆ 591 │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 1748178954 ┆ 981325451 ┆ 22.310371 ┆ 113.901993 ┆ … ┆ 0 ┆ 0 ┆ [] ┆ 2596 │
│ 1748178953 ┆ 981374338 ┆ 22.299173 ┆ 113.89856 ┆ … ┆ 0 ┆ 0 ┆ [] ┆ 3291 │
│ 1748178957 ┆ 981372281 ┆ 22.297474 ┆ 113.898857 ┆ … ┆ 0 ┆ 0 ┆ [] ┆ 3354 │
│ 1748178957 ┆ 981376434 ┆ 22.293045 ┆ 113.970421 ┆ … ┆ 0 ┆ 0 ┆ [] ┆ 4961 │
│ 1748178957 ┆ 981339515 ┆ 22.305908 ┆ 113.833893 ┆ … ┆ 0 ┆ 0 ┆ [] ┆ 9629 │
└────────────┴───────────┴───────────┴────────────┴───┴────────────┴────────┴───────────┴──────────┘
Live Flights Status¤
Retrieve the flight status for the closest flights from a location
from fr24 import FR24, FR24Cache
async def get_nearest_flight_ids(fr24: FR24) -> list[int]:
nearest_result = await fr24.nearest_flights.fetch(
lat=22.31257, lon=113.92708, radius=10000, limit=1500
)
return [
flight.flight.flightid
for flight in nearest_result.to_proto().flights_list
]
async def my_live_flights_status() -> None:
async with FR24() as fr24:
nearest_flight_ids = await get_nearest_flight_ids(fr24)
result = await fr24.live_flights_status.fetch(
flight_ids=nearest_flight_ids[:5]
)
print(result)
print(result.to_dict())
print(result.to_polars())
result.write_table(FR24Cache.default())
await my_live_flights_status()
LiveFlightsStatusResult(
request=LiveFlightsStatusParams(
flight_ids=[981395112, 981399624, 981364304, 981357406, 981398399]
),
response=<Response [200 OK]>,
timestamp=1748186042
)
{
'flights_map': [
{'flight_id': 981395112, 'data': {'lat': 22.311754, 'lon': 113.92508, 'status': 'LIVE'}},
{'flight_id': 981398399, 'data': {'lat': 22.313644, 'lon': 113.915115, 'status': 'LIVE'}},
{'flight_id': 981364304, 'data': {'lat': 22.318283, 'lon': 113.928314, 'status': 'LIVE'}},
{'flight_id': 981357406, 'data': {'lat': 22.313244, 'lon': 113.934654, 'status': 'LIVE'}},
{'flight_id': 981399624, 'data': {'lat': 22.310404, 'lon': 113.93139, 'status': 'LIVE'}}
]
}
shape: (5, 5)
┌───────────┬───────────┬────────────┬────────┬────────┐
│ flight_id ┆ latitude ┆ longitude ┆ status ┆ squawk │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ u32 ┆ f32 ┆ f32 ┆ u8 ┆ u16 │
╞═══════════╪═══════════╪════════════╪════════╪════════╡
│ 981395112 ┆ 22.311754 ┆ 113.925079 ┆ 4 ┆ 0 │
│ 981398399 ┆ 22.313644 ┆ 113.915115 ┆ 4 ┆ 0 │
│ 981364304 ┆ 22.318283 ┆ 113.928314 ┆ 4 ┆ 0 │
│ 981357406 ┆ 22.313244 ┆ 113.934654 ┆ 4 ┆ 0 │
│ 981399624 ┆ 22.310404 ┆ 113.931389 ┆ 4 ┆ 0 │
└───────────┴───────────┴────────────┴────────┴────────┘
Follow Flight¤
Stream real-time updates to the state vector of an aircraft.
Note
This is a streaming service which endlessly yields the latest updates.
Unlike other services, it does not offer a default serialisation strategy
(i.e. result.write_parquet does not exist). For a local setup, consider
inserting the updates to a SQLite database manually.
The first packet of data contains useful initial metadata (aircraft_info,
flight_plan and flight_trail_list), which will not be re-transmitted
in the subsequent updates.
Tip
The server often sends state vector packets every 1-60 seconds, but httpx
by default closes the stream after 5 seconds. We increase the timeout to 120
seconds to avoid premature closure.
import httpx
from fr24 import FR24
from fr24.proto.v1_pb2 import NearestFlightsResponse
async def get_nearest_flights(fr24: FR24) -> NearestFlightsResponse:
nearest_result = await fr24.nearest_flights.fetch(
lat=22.31257, lon=113.92708, radius=10000, limit=1500
)
return nearest_result.to_proto()
async def my_follow_flight() -> None:
timeout = httpx.Timeout(5, read=120)
async with FR24(client=httpx.AsyncClient(timeout=timeout)) as fr24:
nearest_flights_result = await get_nearest_flights(fr24)
flight_id = nearest_flights_result.flights_list[0].flight.flightid
i = 0
async for result in fr24.follow_flight.stream(flight_id=flight_id):
print(f"##### {i} #####")
print(result.to_proto())
i += 1
if i > 2:
break
await my_follow_flight()
##### 0 #####
aircraft_info {
icao_address: 7701252
reg: "RP-C9903"
type: "A321"
icon: A320
full_description: "Airbus A321-231"
images_list {
url: "https://www.jetphotos.com/photo/11825012"
copyright: "yajoo"
thumbnail: "https://cdn.jetphotos.com/200/5/2378185_1756401937_tb.jpg"
medium: "https://cdn.jetphotos.com/400/5/2378185_1756401937.jpg"
large: "https://cdn.jetphotos.com/640/5/2378185_1756401937.jpg"
}
images_list {
url: "https://www.jetphotos.com/photo/11813525"
copyright: "Landing HKG"
thumbnail: "https://cdn.jetphotos.com/200/6/522343_1755503883_tb.jpg"
medium: "https://cdn.jetphotos.com/400/6/522343_1755503883.jpg"
large: "https://cdn.jetphotos.com/640/6/522343_1755503883.jpg"
}
images_list {
url: "https://www.jetphotos.com/photo/11745327"
copyright: "saTrL"
thumbnail: "https://cdn.jetphotos.com/200/5/630999_1749204666_tb.jpg"
medium: "https://cdn.jetphotos.com/400/5/630999_1749204666.jpg"
large: "https://cdn.jetphotos.com/640/5/630999_1749204666.jpg"
}
msn_available: true
age_available: true
registered_owners: "Philippine Airlines"
is_country_of_reg_available: true
}
schedule_info {
flight_number: "PR311"
operated_by_id: 98
painted_as_id: 98
origin_id: 1366
destination_id: 2266
scheduled_departure: 1758466800
scheduled_arrival: 1758475200
arr_terminal: "1"
}
flight_progress {
traversed_distance: 657
remaining_distance: 1143081
great_circle_distance: 1143502
mean_flight_time: 5886
flight_stage: ON_GROUND
}
flight_info {
flightid: 1011880908
lat: 22.3098583
lon: 113.922615
track: 160
speed: 8
timestamp_ms: 1758466956660
on_ground: true
callsign: "PAL311"
ems_availability {
rs_availability: true
}
squawk_availability: true
airspace_availability: true
server_time_ms: 1758466960115
}
flight_trail_list {
snapshot_id: 1758466272
lat: 22.3157578
lon: 113.932076
spd: 3
heading: 177
}
...
}
flight_trail_list {
snapshot_id: 1758466950
lat: 22.3100777
lon: 113.922523
spd: 9
heading: 160
}
position_buffer {
recent_positions_list {
delta_lat: -5
delta_lon: 2
delta_ms: 1670
}
recent_positions_list {
delta_lat: -9
delta_lon: 3
delta_ms: 2610
}
recent_positions_list {
delta_lat: -21
delta_lon: 9
delta_ms: 6010
}
recent_positions_list {
delta_lat: -47
delta_lon: 18
delta_ms: 12350
}
}
##### 1 #####
schedule_info {
flight_number: "PR311"
operated_by_id: 98
painted_as_id: 98
origin_id: 1366
destination_id: 2266
scheduled_departure: 1758466800
scheduled_arrival: 1758475200
arr_terminal: "1"
}
flight_progress {
traversed_distance: 662
remaining_distance: 1143066
great_circle_distance: 1143502
mean_flight_time: 5886
flight_stage: ON_GROUND
}
flight_info {
flightid: 1011880908
lat: 22.3097286
lon: 113.922668
track: 160
speed: 8
timestamp_ms: 1758466960150
on_ground: true
callsign: "PAL311"
ems_availability {
rs_availability: true
}
squawk_availability: true
airspace_availability: true
server_time_ms: 1758466963120
}
##### 2 #####
schedule_info {
flight_number: "PR311"
operated_by_id: 98
painted_as_id: 98
origin_id: 1366
destination_id: 2266
scheduled_departure: 1758466800
scheduled_arrival: 1758475200
arr_terminal: "1"
}
flight_progress {
traversed_distance: 667
remaining_distance: 1143051
great_circle_distance: 1143502
mean_flight_time: 5886
flight_stage: ON_GROUND
}
flight_info {
flightid: 1011880908
lat: 22.3095818
lon: 113.922714
track: 160
speed: 9
timestamp_ms: 1758466963941
on_ground: true
callsign: "PAL311"
ems_availability {
rs_availability: true
}
squawk_availability: true
airspace_availability: true
server_time_ms: 1758466966122
}
Top Flights¤
from fr24 import FR24, FR24Cache
from rich import print
async def my_top_flights() -> None:
async with FR24() as fr24:
result = await fr24.top_flights.fetch(limit=10)
print(result)
print(result.to_dict())
print(result.to_polars())
result.write_table(FR24Cache.default())
await my_top_flights()
TopFlightsResult(
request=TopFlightsParams(limit=10),
response=<Response [200 OK]>,
timestamp=1748188667
)
{
'scoreboard_list': [
{
'flight_id': 981367259,
'live_clicks': 1438,
'total_clicks': 1438,
'flight_number': 'DOC72',
'callsign': 'DOC72',
'from_iata': 'FRG',
'from_city': 'Farmingdale',
'to_iata': 'FRG',
'to_city': 'Farmingdale',
'type': 'B29',
'full_description': 'Boeing TB-29 Superfortress'
},
...
{
'flight_id': 981290224,
'live_clicks': 514,
'total_clicks': 514,
'flight_number': 'SQ326',
'callsign': 'SIA326',
'from_iata': 'SIN',
'from_city': 'Singapore',
'to_iata': 'FRA',
'to_city': 'Frankfurt',
'type': 'A388',
'full_description': 'Airbus A380-841'
}
]
}
shape: (10, 12)
┌───────────┬─────────────┬────────────┬────────────┬───┬─────────┬────────────┬──────┬────────────┐
│ flight_id ┆ live_clicks ┆ total_clic ┆ flight_num ┆ … ┆ to_iata ┆ to_city ┆ type ┆ full_descr │
│ --- ┆ --- ┆ ks ┆ ber ┆ ┆ --- ┆ --- ┆ --- ┆ iption │
│ u32 ┆ u32 ┆ --- ┆ --- ┆ ┆ str ┆ str ┆ str ┆ --- │
│ ┆ ┆ u32 ┆ str ┆ ┆ ┆ ┆ ┆ str │
╞═══════════╪═════════════╪════════════╪════════════╪═══╪═════════╪════════════╪══════╪════════════╡
│ 981367259 ┆ 1438 ┆ 1438 ┆ DOC72 ┆ … ┆ FRG ┆ Farmingdal ┆ B29 ┆ Boeing │
│ ┆ ┆ ┆ ┆ ┆ ┆ e ┆ ┆ TB-29 Supe │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ rfortress │
│ 981383686 ┆ 1066 ┆ 1066 ┆ RRR4952 ┆ … ┆ RZE ┆ Rzeszow ┆ A400 ┆ Airbus │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ A400M │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ Atlas │
│ 981393352 ┆ 890 ┆ 890 ┆ ┆ … ┆ ┆ ┆ DC3 ┆ Douglas │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ DC-3C │
│ 981407748 ┆ 831 ┆ 831 ┆ ┆ … ┆ ┆ ┆ EC35 ┆ Airbus Hel │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ icopters │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ H135 │
│ 981398120 ┆ 707 ┆ 707 ┆ ┆ … ┆ RTM ┆ Rotterdam ┆ SR22 ┆ Cirrus │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ SR22 │
│ 981400483 ┆ 673 ┆ 673 ┆ ┆ … ┆ ┆ ┆ BR23 ┆ BRM Aero │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ Bristell │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ B23 │
│ 981402316 ┆ 616 ┆ 616 ┆ ┆ … ┆ ┆ ┆ DHC6 ┆ Viking │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ DHC-6-400 │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ Twin Otter │
│ 981368239 ┆ 554 ┆ 554 ┆ VJT750 ┆ … ┆ GIG ┆ Rio de ┆ GL7T ┆ Bombardier │
│ ┆ ┆ ┆ ┆ ┆ ┆ Janeiro ┆ ┆ Global │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 7500 │
│ 981404508 ┆ 535 ┆ 535 ┆ ┆ … ┆ ┆ ┆ GLID ┆ Alexander │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ Schleicher │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ASK-23B │
│ 981290224 ┆ 514 ┆ 514 ┆ SQ326 ┆ … ┆ FRA ┆ Frankfurt ┆ A388 ┆ Airbus │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ A380-841 │
└───────────┴─────────────┴────────────┴────────────┴───┴─────────┴────────────┴──────┴────────────┘
Flight Details¤
Retrieve detailed information about a flight
from fr24 import FR24, FR24Cache
async def get_farthest_flight_id(fr24: FR24) -> int:
nearest_result = await fr24.nearest_flights.fetch(
lat=22.31257, lon=113.92708, radius=10000, limit=1500
)
return nearest_result.to_proto().flights_list[-1].flight.flightid
async def my_flight_details() -> None:
async with FR24() as fr24:
flight_id = await get_farthest_flight_id(fr24)
result = await fr24.flight_details.fetch(flight_id=flight_id)
print(result)
print(result.to_dict())
print(result.to_polars())
result.write_table(FR24Cache.default())
await my_flight_details()
FlightDetailsResult(
request=FlightDetailsParams(flight_id=1011852915, restriction_mode=0, verbose=True),
response=<Response [200 OK]>,
timestamp=1758466410
)
{
"aircraft_info": {
"icao_address": 7864687,
"reg": "B-HNG",
"type": "B773",
"icon": "B777",
"full_description": "Boeing 777-367",
"images_list": [
{
"url": "https://www.jetphotos.com/photo/11821124",
"copyright": "kuzuma",
"thumbnail": "https://cdn.jetphotos.com/200/5/505864_1756100441_tb.jpg",
"medium": "https://cdn.jetphotos.com/400/5/505864_1756100441.jpg",
"large": "https://cdn.jetphotos.com/640/5/505864_1756100441.jpg",
},
{
"url": "https://www.jetphotos.com/photo/11808578",
"copyright": "tobiashsu1217_spotter",
"thumbnail": "https://cdn.jetphotos.com/200/6/1544325_1755012630_tb.jpg",
"medium": "https://cdn.jetphotos.com/400/6/1544325_1755012630.jpg",
"large": "https://cdn.jetphotos.com/640/6/1544325_1755012630.jpg",
},
{
"url": "https://www.jetphotos.com/photo/11804947",
"copyright": "Stanley Joe Hidayat",
"thumbnail": "https://cdn.jetphotos.com/200/5/389644_1754704150_tb.jpg",
"medium": "https://cdn.jetphotos.com/400/5/389644_1754704150.jpg",
"large": "https://cdn.jetphotos.com/640/5/389644_1754704150.jpg",
},
],
"msn_available": True,
"age_available": True,
"registered_owners": "Cathay Pacific",
"is_country_of_reg_available": True,
},
"schedule_info": {
"flight_number": "CX902",
"operated_by_id": 57,
"painted_as_id": 57,
"origin_id": 2266,
"destination_id": 1366,
"scheduled_departure": 1758457200,
"scheduled_arrival": 1758466500,
"actual_departure": 1758460310,
"arr_terminal": "1",
"baggage_belt": "10",
},
"flight_progress": {
"traversed_distance": 1146491,
"remaining_distance": 3113,
"elapsed_time": 6100,
"remaining_time": 29,
"eta": 1758466439,
"great_circle_distance": 1143502,
"mean_flight_time": 5846,
"flight_stage": "AIRBORNE",
"delay_status": "GREEN",
"progress_pct": 99,
},
"flight_info": {
"flightid": 1011852915,
"lat": 22.324324,
"lon": 113.89048,
"track": 70,
"speed": 120,
"timestamp_ms": "1758466407324",
"callsign": "CPA902",
"ems_availability": {
"qnh_availability": True,
"amcp_availability": True,
"oat_availability": True,
"ias_availability": True,
"tas_availability": True,
"mach_availability": True,
"agps_availability": True,
"agpsdiff_availability": True,
"wind_dir_availability": True,
"wind_speed_availability": True,
},
"squawk_availability": True,
"airspace_availability": True,
"server_time_ms": "1758466410387",
},
"flight_plan": {},
"flight_trail_list": [
{
"snapshot_id": "1758458895",
"lat": 14.517563,
"lon": 121.01436,
"spd": 1,
"heading": 101,
},
...
{
"snapshot_id": "1758466399",
"lat": 22.322754,
"lon": 113.88553,
"altitude": 100,
"spd": 141,
"heading": 70,
},
],
"position_buffer": {
"recent_positions_list": [
{"delta_lat": 43, "delta_lon": 131, "delta_ms": 2079},
{"delta_lat": 94, "delta_lon": 294, "delta_ms": 4660},
{"delta_lat": 112, "delta_lon": 350, "delta_ms": 5589},
{"delta_lat": 156, "delta_lon": 495, "delta_ms": 7660},
{"delta_lat": 196, "delta_lon": 614, "delta_ms": 9579},
{"delta_lat": 234, "delta_lon": 721, "delta_ms": 11019},
]
},
}
shape: (1, 32)
┌─────────────┬───────┬──────────┬─────────────┬───┬────────┬────────────┬────────────┬────────────┐
│ icao_addres ┆ reg ┆ typecode ┆ flight_numb ┆ … ┆ squawk ┆ ems ┆ flight_tra ┆ position_b │
│ s ┆ --- ┆ --- ┆ er ┆ ┆ --- ┆ --- ┆ il_list ┆ uffer │
│ --- ┆ str ┆ str ┆ --- ┆ ┆ u16 ┆ struct[13] ┆ --- ┆ --- │
│ u32 ┆ ┆ ┆ str ┆ ┆ ┆ ┆ list[struc ┆ list[struc │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ t[8]] ┆ t[3]] │
╞═════════════╪═══════╪══════════╪═════════════╪═══╪════════╪════════════╪════════════╪════════════╡
│ 7864687 ┆ B-HNG ┆ B773 ┆ CX902 ┆ … ┆ 0 ┆ {0,0,0,0,0 ┆ [{17584588 ┆ [{43,131,2 │
│ ┆ ┆ ┆ ┆ ┆ ┆ ,0,0,0,0,0 ┆ 95,14.5175 ┆ 079}, {94, │
│ ┆ ┆ ┆ ┆ ┆ ┆ ,0,0,0} ┆ 63,121.014 ┆ 294,4660}, │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ … ┆ … │
└─────────────┴───────┴──────────┴─────────────┴───┴────────┴────────────┴────────────┴────────────┘
Playback Flight¤
Retrieve detailed historical flight information including complete trail
from fr24 import FR24, FR24Cache
import polars as pl
async def get_last_flight(fr24: FR24, *, reg: str = "B-LRA") -> tuple[int, int]:
flight_list_result = await fr24.flight_list.fetch(reg=reg)
df = flight_list_result.to_polars()
landed = df.filter(pl.col("status").str.starts_with("Landed"))
assert landed.height > 0, "no landed flights found"
flight_id = landed[0, "flight_id"]
stod = int(landed[0, "ATOD"].timestamp())
return flight_id, stod
async def my_playback_flight() -> None:
async with FR24() as fr24:
flight_id, timestamp = await get_last_flight(fr24)
result = await fr24.playback_flight.fetch(
flight_id=flight_id, timestamp=timestamp
)
print(result)
print(result.to_dict())
print(result.to_polars())
result.write_table(FR24Cache.default())
await my_playback_flight()
PlaybackFlightResult(
request=PlaybackFlightParams(flight_id=1011667820, timestamp=1758386815),
response=<Response [200 OK]>
)
{
"aircraft_info": {
"icao_address": 7867035,
"reg": "B-LRA",
"type": "A359",
"icon": "A330",
"full_description": "Airbus A350-941",
"images_list": [
{
"url": "https://www.jetphotos.com/photo/11806625",
"copyright": "EthanLi",
"thumbnail": "https://cdn.jetphotos.com/200/5/682006_1754851444_tb.jpg",
"medium": "https://cdn.jetphotos.com/400/5/682006_1754851444.jpg",
"large": "https://cdn.jetphotos.com/640/5/682006_1754851444.jpg",
},
{
"url": "https://www.jetphotos.com/photo/11728089",
"copyright": "Hypocrite",
"thumbnail": "https://cdn.jetphotos.com/200/6/1954570_1747460006_tb.jpg",
"medium": "https://cdn.jetphotos.com/400/6/1954570_1747460006.jpg",
"large": "https://cdn.jetphotos.com/640/6/1954570_1747460006.jpg",
},
{
"url": "https://www.jetphotos.com/photo/11721357",
"copyright": "Steven-lzy",
"thumbnail": "https://cdn.jetphotos.com/200/5/778073_1746782825_tb.jpg",
"medium": "https://cdn.jetphotos.com/400/5/778073_1746782825.jpg",
"large": "https://cdn.jetphotos.com/640/5/778073_1746782825.jpg",
},
],
"msn_available": True,
"age_available": True,
"registered_owners": "Cathay Pacific",
"is_country_of_reg_available": True,
},
"schedule_info": {
"flight_number": "CX170",
"operated_by_id": 57,
"painted_as_id": 57,
"origin_id": 2730,
"destination_id": 1366,
"scheduled_departure": 1758384600,
"scheduled_arrival": 1758412500,
"actual_departure": 1758386815,
"actual_arrival": 1758414073,
"arr_terminal": "1",
"baggage_belt": "14",
},
"flight_info": {
"flightid": 1011667820,
"lat": -31.94989,
"lon": 115.962234,
"track": 194,
"speed": 168,
"timestamp_ms": "1758386809081",
"callsign": "CPA170",
"ems_availability": {
"qnh_availability": True,
"amcp_availability": True,
"mach_availability": True,
"agps_availability": True,
"agpsdiff_availability": True,
"rs_availability": True,
},
"squawk_availability": True,
"vspeed_availability": True,
"airspace_availability": True,
"server_time_ms": "1758466605103",
},
"flight_trail_list": [
{
"snapshot_id": "1758385543",
"lat": -31.94054,
"lon": 115.973206,
"heading": 151,
},
...
{
"snapshot_id": "1758415950",
"lat": 22.31186,
"lon": 113.92748,
"spd": 1,
"heading": 295,
},
],
}
shape: (1, 24)
┌─────────────┬───────┬──────────┬─────────────┬───┬──────────┬────────┬─────────────┬─────────────┐
│ icao_addres ┆ reg ┆ typecode ┆ flight_numb ┆ … ┆ callsign ┆ squawk ┆ ems ┆ flight_trai │
│ s ┆ --- ┆ --- ┆ er ┆ ┆ --- ┆ --- ┆ --- ┆ l_list │
│ --- ┆ str ┆ str ┆ --- ┆ ┆ str ┆ u16 ┆ struct[13] ┆ --- │
│ u32 ┆ ┆ ┆ str ┆ ┆ ┆ ┆ ┆ list[struct │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ [7]] │
╞═════════════╪═══════╪══════════╪═════════════╪═══╪══════════╪════════╪═════════════╪═════════════╡
│ 7867035 ┆ B-LRA ┆ A359 ┆ CX758 ┆ … ┆ CPA758 ┆ 0 ┆ {0,0,0,0,0, ┆ [{174815111 │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 0,0,0,0,0,0 ┆ 3,1.341973, │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ,0,0} ┆ 103.9865… │
└─────────────┴───────┴──────────┴─────────────┴───┴──────────┴────────┴─────────────┴─────────────┘
Low Level API¤
For maximum control, you can also use fr24 in a procedural style. You will have to manage the headers, authentication yourself. It is highly recommended to use services instead.
Flight list¤
import httpx
from datetime import datetime
from fr24.authentication import login
from fr24.json import flight_list, flight_list_df, FlightListParams
from fr24.types.json import FlightList
from fr24.proto.headers import get_grpc_headers
async def my_list() -> FlightList:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
auth = await login(client)
if auth is not None:
print(auth.get("message"))
response = await flight_list(
client,
FlightListParams(
flight="AF291",
timestamp=datetime.strptime("2025-01-16", "%Y-%m-%d"), # (1)!
),
headers=headers,
auth=auth,
)
response.raise_for_status()
list_ = response.json()
return list_ # type: ignore
list_ = await my_list()
df = flight_list_df(list_)
df
- Replace it with the current time.
shape: (6, 15)
┌───────────┬────────┬──────────┬─────────┬───┬─────────────┬────────────┬────────────┬────────────┐
│ flight_id ┆ number ┆ callsign ┆ icao24 ┆ … ┆ ATOD ┆ STOA ┆ ETOA ┆ ATOA │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │
│ u64 ┆ str ┆ str ┆ u32 ┆ ┆ datetime[ms ┆ datetime[m ┆ datetime[m ┆ datetime[m │
│ ┆ ┆ ┆ ┆ ┆ , UTC] ┆ s, UTC] ┆ s, UTC] ┆ s, UTC] │
╞═══════════╪════════╪══════════╪═════════╪═══╪═════════════╪════════════╪════════════╪════════════╡
│ null ┆ AF291 ┆ null ┆ null ┆ … ┆ null ┆ 2025-01-24 ┆ null ┆ null │
│ ┆ ┆ ┆ ┆ ┆ ┆ 18:00:00 ┆ ┆ │
│ ┆ ┆ ┆ ┆ ┆ ┆ UTC ┆ ┆ │
│ null ┆ AF291 ┆ null ┆ null ┆ … ┆ null ┆ 2025-01-22 ┆ null ┆ null │
│ ┆ ┆ ┆ ┆ ┆ ┆ 18:00:00 ┆ ┆ │
│ ┆ ┆ ┆ ┆ ┆ ┆ UTC ┆ ┆ │
│ null ┆ AF291 ┆ null ┆ null ┆ … ┆ null ┆ 2025-01-19 ┆ null ┆ null │
│ ┆ ┆ ┆ ┆ ┆ ┆ 18:00:00 ┆ ┆ │
│ ┆ ┆ ┆ ┆ ┆ ┆ UTC ┆ ┆ │
│ 952249857 ┆ AF291 ┆ AFR291 ┆ 3789477 ┆ … ┆ 2025-01-17 ┆ 2025-01-17 ┆ null ┆ 2025-01-17 │
│ ┆ ┆ ┆ ┆ ┆ 05:13:55 ┆ 18:00:00 ┆ ┆ 19:30:15 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 951756645 ┆ AF291 ┆ AFR291 ┆ 3789486 ┆ … ┆ 2025-01-15 ┆ 2025-01-15 ┆ null ┆ 2025-01-15 │
│ ┆ ┆ ┆ ┆ ┆ 03:45:20 ┆ 18:00:00 ┆ ┆ 17:58:06 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
│ 951093039 ┆ AF291 ┆ AFR291 ┆ 3789475 ┆ … ┆ 2025-01-12 ┆ 2025-01-12 ┆ null ┆ 2025-01-12 │
│ ┆ ┆ ┆ ┆ ┆ 05:15:13 ┆ 18:00:00 ┆ ┆ 19:03:13 │
│ ┆ ┆ ┆ ┆ ┆ UTC ┆ UTC ┆ ┆ UTC │
└───────────┴────────┴──────────┴─────────┴───┴─────────────┴────────────┴────────────┴────────────┘
Playback¤
import httpx
from fr24.authentication import login
from fr24.json import playback, playback_df, PlaybackParams
from fr24.types.json import Playback
from fr24.proto.headers import get_grpc_headers
async def my_playback() -> Playback:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
auth = await login(client)
if auth is not None:
print(auth.get("message"))
response = await playback(
client,
PlaybackParams(flight_id="38c59db3"),
headers=headers,
auth=auth,
)
response.raise_for_status()
list_ = response.json()
return list_ # type: ignore
list_ = await my_playback()
df = playback_df(list_)
df
shape: (203, 9)
┌────────────┬───────────┬────────────┬──────────┬───┬───────────────┬───────┬────────┬────────────┐
│ timestamp ┆ latitude ┆ longitude ┆ altitude ┆ … ┆ vertical_spee ┆ track ┆ squawk ┆ ems │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ d ┆ --- ┆ --- ┆ --- │
│ u32 ┆ f32 ┆ f32 ┆ i32 ┆ ┆ --- ┆ i16 ┆ u16 ┆ struct[18] │
│ ┆ ┆ ┆ ┆ ┆ i16 ┆ ┆ ┆ │
╞════════════╪═══════════╪════════════╪══════════╪═══╪═══════════════╪═══════╪════════╪════════════╡
│ 1737166526 ┆ 22.313072 ┆ 113.931381 ┆ 0 ┆ … ┆ 0 ┆ 317 ┆ 0 ┆ null │
│ 1737166557 ┆ 22.312778 ┆ 113.931618 ┆ 0 ┆ … ┆ 0 ┆ 270 ┆ 0 ┆ null │
│ 1737166584 ┆ 22.312763 ┆ 113.931953 ┆ 0 ┆ … ┆ 0 ┆ 250 ┆ 0 ┆ null │
│ 1737166816 ┆ 22.312626 ┆ 113.931557 ┆ 0 ┆ … ┆ 0 ┆ 250 ┆ 3041 ┆ null │
│ 1737166864 ┆ 22.312477 ┆ 113.931068 ┆ 0 ┆ … ┆ 0 ┆ 250 ┆ 3041 ┆ null │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 1737167965 ┆ 22.200348 ┆ 114.345802 ┆ 13500 ┆ … ┆ 3328 ┆ 142 ┆ 3041 ┆ null │
│ 1737167997 ┆ 22.154388 ┆ 114.382454 ┆ 14850 ┆ … ┆ 1536 ┆ 143 ┆ 3041 ┆ null │
│ 1737168028 ┆ 22.107239 ┆ 114.419304 ┆ 16050 ┆ … ┆ 2368 ┆ 143 ┆ 3041 ┆ null │
│ 1737168060 ┆ 22.059942 ┆ 114.456535 ┆ 17200 ┆ … ┆ 2048 ┆ 143 ┆ 3041 ┆ null │
│ 1737168092 ┆ 22.008501 ┆ 114.497017 ┆ 18350 ┆ … ┆ 2048 ┆ 143 ┆ 3041 ┆ null │
└────────────┴───────────┴────────────┴──────────┴───┴───────────────┴───────┴────────┴────────────┘
Airport List¤
import httpx
from fr24.types.json import AirportList
from fr24.json import airport_list, AirportListParams
from fr24.proto.headers import get_grpc_headers
import polars as pl
async def my_arrivals() -> AirportList:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
response = await airport_list(
client,
AirportListParams(airport="tls", mode="arrivals"),
headers=headers,
auth=None,
)
response.raise_for_status()
list_ = response.json()
return list_ # type: ignore
airports = await my_arrivals()
arrivals = airports["result"]["response"]["airport"]["pluginData"]["schedule"][
"arrivals"
]["data"]
assert arrivals is not None
df = pl.json_normalize(arrivals)
print(df)
shape: (10, 76)
┌───────────┬───────────┬───────────┬───────────┬───┬───────────┬───────────┬───────────┬──────────┐
│ flight.id ┆ flight.id ┆ flight.id ┆ flight.id ┆ … ┆ flight.ti ┆ flight.ai ┆ flight.ow ┆ flight.a │
│ entificat ┆ entificat ┆ entificat ┆ entificat ┆ ┆ me.other. ┆ rcraft.im ┆ ner ┆ irline │
│ ion.id ┆ ion.row ┆ ion.numbe ┆ ion.numbe ┆ ┆ duration ┆ ages ┆ --- ┆ --- │
│ --- ┆ --- ┆ r.d… ┆ r.a… ┆ ┆ --- ┆ --- ┆ null ┆ null │
│ str ┆ i64 ┆ --- ┆ --- ┆ ┆ null ┆ null ┆ ┆ │
│ ┆ ┆ str ┆ str ┆ ┆ ┆ ┆ ┆ │
╞═══════════╪═══════════╪═══════════╪═══════════╪═══╪═══════════╪═══════════╪═══════════╪══════════╡
│ 3963916d ┆ 563063588 ┆ AF6132 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 1 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ null ┆ 563365562 ┆ null ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 4 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 39638d76 ┆ 563085809 ┆ T71527 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 3963a803 ┆ 563063662 ┆ AF7408 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 396399a4 ┆ 563087474 ┆ U24849 ┆ EC4849 ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 7 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ null ┆ 563088423 ┆ V72371 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 4 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 3963978d ┆ 563085809 ┆ T73718 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 1 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 3963ab98 ┆ 563089434 ┆ XK720 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 8 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 396398ab ┆ 563071223 ┆ FR3903 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 6 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
│ 3963b61f ┆ 563072081 ┆ GP155 ┆ null ┆ … ┆ null ┆ null ┆ null ┆ null │
│ ┆ 9 ┆ ┆ ┆ ┆ ┆ ┆ ┆ │
└───────────┴───────────┴───────────┴───────────┴───┴───────────┴───────────┴───────────┴──────────┘
Airport Search¤
from fr24.types.json import Find
from fr24.json import find, FindParams
from fr24.proto.headers import get_grpc_headers
import polars as pl
import httpx
async def my_find() -> Find:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
response = await find(
client, FindParams(query="paris"), headers=headers, auth=None
)
response.raise_for_status()
results = response.json()
return results # type: ignore
results = await my_find()
df = pl.json_normalize(results["results"])
print(df)
shape: (9, 7)
┌─────┬───────────────────────────────┬─────────┬──────────┬────────────┬────────────┬─────────────┐
│ id ┆ label ┆ type ┆ match ┆ detail.lat ┆ detail.lon ┆ detail.size │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ str ┆ str ┆ str ┆ f64 ┆ f64 ┆ i64 │
╞═════╪═══════════════════════════════╪═════════╪══════════╪════════════╪════════════╪═════════════╡
│ CDG ┆ Paris Charles de Gaulle ┆ airport ┆ begins ┆ 49.012516 ┆ 2.555752 ┆ 201280 │
│ ┆ Airpor… ┆ ┆ ┆ ┆ ┆ │
│ ORY ┆ Paris Orly Airport (ORY / ┆ airport ┆ begins ┆ 48.723331 ┆ 2.379444 ┆ 84510 │
│ ┆ LFPO… ┆ ┆ ┆ ┆ ┆ │
│ LBG ┆ Paris Le Bourget Airport (LBG ┆ airport ┆ begins ┆ 48.958801 ┆ 2.4336 ┆ 24465 │
│ ┆ … ┆ ┆ ┆ ┆ ┆ │
│ BVA ┆ Paris Beauvais-Tille Airport ┆ airport ┆ begins ┆ 49.453465 ┆ 2.115138 ┆ 15939 │
│ ┆ (… ┆ ┆ ┆ ┆ ┆ │
│ VIY ┆ Paris Villacoublay Velizy Air ┆ airport ┆ begins ┆ 48.774399 ┆ 2.20154 ┆ 1038 │
│ ┆ … ┆ ┆ ┆ ┆ ┆ │
│ PRX ┆ Paris Cox Field (PRX / KPRX) ┆ airport ┆ begins ┆ 33.636665 ┆ -95.450279 ┆ 953 │
│ XCR ┆ Paris Vatry Chalons Airport ┆ airport ┆ begins ┆ 48.759998 ┆ 4.2 ┆ 710 │
│ ┆ (X… ┆ ┆ ┆ ┆ ┆ │
│ PHT ┆ Paris Henry County Airport ┆ airport ┆ begins ┆ 36.336384 ┆ -88.38427 ┆ 199 │
│ ┆ (PH… ┆ ┆ ┆ ┆ ┆ │
│ OPL ┆ Opelousas St. Landry Parish ┆ airport ┆ contains ┆ 30.555695 ┆ -92.098915 ┆ 194 │
│ ┆ Ai… ┆ ┆ ┆ ┆ ┆ │
└─────┴───────────────────────────────┴─────────┴──────────┴────────────┴────────────┴─────────────┘
Live feed¤
Demonstrates custom bounding boxes.
import httpx
from fr24.grpc import LiveFeedParams, BoundingBox, live_feed
from fr24.proto.v1_pb2 import LiveFeedResponse
from fr24.proto import parse_data
from fr24.proto.headers import get_grpc_headers
async def france_data() -> LiveFeedResponse:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
params = LiveFeedParams(
bounding_box=BoundingBox(north=50, west=-7, south=40, east=10)
)
response = await live_feed(client, params, headers)
result = parse_data(response.content, LiveFeedResponse)
return result.unwrap() # (1)!
data = await france_data()
data
- The type is a
Result[LiveFeedResponse, ProtoError], calling the.unwrap()method raises an exception if there is an error.
flights_list {
flightid: 941292228
lat: 40.0058289
lon: -5.02393532
track: 225
alt: 26800
speed: 427
icon: A320
timestamp: 1732481230
callsign: "IBS15MA"
extra_info {
flight: "IB1589"
reg: "EC-OAS"
route {
from: "MAD"
to: "TFN"
}
type: "A21N"
}
position_buffer {
recent_positions_list {
delta_lat: -418
delta_lon: -562
delta_ms: 3000
}
...
delta_lon: -1958
delta_ms: 10000
}
}
}
In JSON format:
from google.protobuf.json_format import MessageToDict
MessageToDict(data)["flightsList"]
[{'flightid': 941292228,
'lat': 40.00583,
'lon': -5.0239353,
'track': 225,
'alt': 26800,
'speed': 427,
'icon': 'A320',
'timestamp': 1732481230,
'callsign': 'IBS15MA',
'extraInfo': {'flight': 'IB1589',
'reg': 'EC-OAS',
'route': {'from': 'MAD', 'to': 'TFN'},
'type': 'A21N'},
'positionBuffer': {'recentPositionsList': [{'deltaLat': -418,
'deltaLon': -562,
'deltaMs': 3000}]}},
{'flightid': 941277503,
'lat': 40.050613,
'lon': -6.7190137,
'track': 24,
'alt': 38000,
'speed': 481,
'icon': 'A320',
'timestamp': 1732481230,
'callsign': 'VOE2RY',
...
'positionBuffer': {'recentPositionsList': [{'deltaLat': 315,
'deltaLon': -660,
'deltaMs': 3000},
{'deltaLat': 553, 'deltaLon': -1170, 'deltaMs': 6000},
{'deltaLat': 929, 'deltaLon': -1958, 'deltaMs': 10000}]}}]
Nearest Flights¤
import httpx
from fr24.grpc import nearest_flights
from fr24.proto.v1_pb2 import (
NearestFlightsResponse,
NearestFlightsRequest,
Geolocation,
)
from fr24.proto import parse_data
from fr24.proto.headers import get_grpc_headers
async def nearest_flights_data() -> NearestFlightsResponse:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
message = NearestFlightsRequest(
location=Geolocation(lat=22.31257, lon=113.92708),
radius=1000,
limit=1500,
)
response = await nearest_flights(client, message, headers)
return parse_data(response.content, NearestFlightsResponse).unwrap()
data = await nearest_flights_data()
data
flights_list {
flight {
flightid: 905701578
lat: 22.3095245
lon: 113.930717
track: 78
speed: 9
timestamp: 1720071634
on_ground: true
callsign: "CES502"
extra_info {
flight: "MU502"
reg: "B-1908"
route {
from: "HKG"
to: "PVG"
}
type: "B738"
logo_id: 131
}
}
distance: 504
}
flights_list {
flight {
...
logo_id: 335
}
}
distance: 783
}
Live Flight Status¤
import httpx
from fr24.grpc import live_flights_status
from fr24.proto.v1_pb2 import (
LiveFlightsStatusRequest,
LiveFlightsStatusResponse,
)
from fr24.proto import parse_data
from fr24.proto.headers import get_grpc_headers
async def live_flights_status_data() -> LiveFlightsStatusResponse:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
message = LiveFlightsStatusRequest(
flight_ids_list=[0x35FBC363, 0x35FBF180]
)
response = await live_flights_status(client, message, headers)
return parse_data(response.content, LiveFlightsStatusResponse).unwrap()
data = await live_flights_status_data()
data
flights_map {
flight_id: 905703808
data {
lat: 21.7237415
lon: 114.917908
status: LIVE
}
}
flights_map {
flight_id: 905692003
data {
lat: 21.9285736
lon: 113.912445
status: LIVE
}
}
Search Index¤
Unstable API: returns empty DATA frame
import httpx
from fr24.grpc import search_index
from fr24.proto.v1_pb2 import FetchSearchIndexRequest, FetchSearchIndexResponse
from fr24.proto import parse_data
from fr24.proto.headers import get_grpc_headers
async def search_index_data() -> FetchSearchIndexResponse:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
message = FetchSearchIndexRequest()
response = await search_index(client, message, headers)
return parse_data(response.content, FetchSearchIndexResponse).unwrap()
data = await search_index_data()
data
GrpcError('empty DATA frame')
Follow Flight¤
See above for more information.
import httpx
from fr24.grpc import follow_flight_stream
from fr24.proto.v1_pb2 import FollowFlightRequest, FollowFlightResponse
from fr24.proto import parse_data
from fr24.proto.headers import get_grpc_headers
async def follow_flight_data() -> None:
timeout = httpx.Timeout(5, read=120)
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient(timeout=timeout) as client:
message = FollowFlightRequest(flight_id=0x3C500FDB)
i = 0
async for response in follow_flight_stream(client, message, headers):
print(f"##### {i} #####")
print(parse_data(response, FollowFlightResponse))
i += 1
if i > 3:
break
await follow_flight_data()
##### 0 #####
Ok(_value=aircraft_info {
icao_address: 7866977
reg: "B-KQM"
type: "B77W"
icon: B777
full_description: "Boeing 777-367(ER)"
images_list {
url: "https://www.jetphotos.com/photo/11825817"
copyright: "ZSHC_Linzx"
thumbnail: "https://cdn.jetphotos.com/200/5/1291679_1756473618_tb.jpg"
medium: "https://cdn.jetphotos.com/400/5/1291679_1756473618.jpg"
large: "https://cdn.jetphotos.com/640/5/1291679_1756473618.jpg"
}
images_list {
url: "https://www.jetphotos.com/photo/11813969"
copyright: "CAN-Eric"
thumbnail: "https://cdn.jetphotos.com/200/5/967682_1755532162_tb.jpg"
medium: "https://cdn.jetphotos.com/400/5/967682_1755532162.jpg"
large: "https://cdn.jetphotos.com/640/5/967682_1755532162.jpg"
}
images_list {
url: "https://www.jetphotos.com/photo/11803561"
copyright: "cc12214"
thumbnail: "https://cdn.jetphotos.com/200/6/585221_1754572527_tb.jpg"
medium: "https://cdn.jetphotos.com/400/6/585221_1754572527.jpg"
large: "https://cdn.jetphotos.com/640/6/585221_1754572527.jpg"
}
msn_available: true
age_available: true
registered_owners: "Cathay Pacific (Oneworld Livery)"
is_country_of_reg_available: true
}
schedule_info {
flight_number: "CX251"
operated_by_id: 57
painted_as_id: 57
origin_id: 1366
destination_id: 1942
scheduled_departure: 1758465600
scheduled_arrival: 1758516000
actual_departure: 1758466901
arr_terminal: "3"
}
flight_progress {
traversed_distance: 21783
remaining_distance: 9668300
elapsed_time: 295
remaining_time: 51569
eta: 1758518765
great_circle_distance: 9647791
mean_flight_time: 48161
flight_stage: ASCENDING
delay_status: RED
}
flight_info {
flightid: 1011879899
lat: 22.1949
lon: 114.087921
track: 169
alt: 7525
speed: 303
timestamp_ms: 1758467194561
callsign: "CPA251"
ems_availability {
qnh_availability: true
amcp_availability: true
oat_availability: true
ias_availability: true
tas_availability: true
mach_availability: true
agps_availability: true
agpsdiff_availability: true
wind_dir_availability: true
wind_speed_availability: true
rs_availability: true
}
squawk_availability: true
vspeed_availability: true
airspace_availability: true
server_time_ms: 1758467196527
}
flight_trail_list {
snapshot_id: 1758465991
lat: 22.3132782
lon: 113.934616
heading: 70
}
flight_trail_list {
snapshot_id: 1758466089
lat: 22.3131981
lon: 113.934303
spd: 2
heading: 70
}
...
flight_trail_list {
snapshot_id: 1758467188
lat: 22.2043304
lon: 114.086678
altitude: 7450
spd: 300
heading: 179
}
position_buffer {
recent_positions_list {
delta_lat: -155
delta_lon: 34
delta_ms: 1090
}
recent_positions_list {
delta_lat: -517
delta_lon: 94
delta_ms: 3710
}
recent_positions_list {
delta_lat: -746
delta_lon: 119
delta_ms: 5270
}
recent_positions_list {
delta_lat: -942
delta_lon: 124
delta_ms: 6700
}
recent_positions_list {
delta_lat: -1107
delta_lon: 129
delta_ms: 7870
}
recent_positions_list {
delta_lat: -1364
delta_lon: 129
delta_ms: 9710
}
recent_positions_list {
delta_lat: -1597
delta_lon: 129
delta_ms: 11380
}
}
)
##### 1 #####
Ok(_value=schedule_info {
flight_number: "CX251"
operated_by_id: 57
painted_as_id: 57
origin_id: 1366
destination_id: 1942
scheduled_departure: 1758465600
scheduled_arrival: 1758516000
actual_departure: 1758466901
arr_terminal: "3"
}
flight_progress {
traversed_distance: 21940
remaining_distance: 9668494
elapsed_time: 298
remaining_time: 51566
eta: 1758518765
great_circle_distance: 9647791
mean_flight_time: 48161
flight_stage: ASCENDING
delay_status: RED
}
flight_info {
flightid: 1011879899
lat: 22.1930809
lon: 114.088387
track: 167
alt: 7550
speed: 303
timestamp_ms: 1758467195921
callsign: "CPA251"
ems_availability {
qnh_availability: true
amcp_availability: true
oat_availability: true
ias_availability: true
tas_availability: true
mach_availability: true
agps_availability: true
agpsdiff_availability: true
wind_dir_availability: true
wind_speed_availability: true
rs_availability: true
}
squawk_availability: true
vspeed_availability: true
airspace_availability: true
server_time_ms: 1758467199530
}
)
##### 2 #####
Ok(_value=schedule_info {
flight_number: "CX251"
operated_by_id: 57
painted_as_id: 57
origin_id: 1366
destination_id: 1942
scheduled_departure: 1758465600
scheduled_arrival: 1758516000
actual_departure: 1758466901
arr_terminal: "3"
}
flight_progress {
traversed_distance: 22437
remaining_distance: 9669070
elapsed_time: 301
remaining_time: 51563
eta: 1758518765
great_circle_distance: 9647791
mean_flight_time: 48161
flight_stage: ASCENDING
delay_status: RED
}
flight_info {
flightid: 1011879899
lat: 22.1880341
lon: 114.09037
track: 158
alt: 7600
speed: 305
timestamp_ms: 1758467199681
callsign: "CPA251"
ems_availability {
qnh_availability: true
amcp_availability: true
oat_availability: true
ias_availability: true
tas_availability: true
mach_availability: true
agps_availability: true
agpsdiff_availability: true
wind_dir_availability: true
wind_speed_availability: true
rs_availability: true
}
squawk_availability: true
vspeed_availability: true
airspace_availability: true
server_time_ms: 1758467202532
}
)
##### 3 #####
Ok(_value=schedule_info {
flight_number: "CX251"
operated_by_id: 57
painted_as_id: 57
origin_id: 1366
destination_id: 1942
scheduled_departure: 1758465600
scheduled_arrival: 1758516000
actual_departure: 1758466901
arr_terminal: "3"
}
flight_progress {
traversed_distance: 22657
remaining_distance: 9669316
elapsed_time: 304
remaining_time: 51560
eta: 1758518765
great_circle_distance: 9647791
mean_flight_time: 48161
flight_stage: ASCENDING
delay_status: RED
}
flight_info {
flightid: 1011879899
lat: 22.1859741
lon: 114.09137
track: 154
alt: 7625
speed: 305
timestamp_ms: 1758467201271
callsign: "CPA251"
ems_availability {
qnh_availability: true
amcp_availability: true
oat_availability: true
ias_availability: true
tas_availability: true
mach_availability: true
agps_availability: true
agpsdiff_availability: true
wind_dir_availability: true
wind_speed_availability: true
rs_availability: true
}
squawk_availability: true
vspeed_availability: true
airspace_availability: true
server_time_ms: 1758467205534
}
)
Top Flights¤
import httpx
from fr24.grpc import top_flights
from fr24.proto.v1_pb2 import TopFlightsRequest, TopFlightsResponse
from fr24.proto import parse_data
from fr24.proto.headers import get_grpc_headers
async def top_flights_data() -> TopFlightsResponse:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
message = TopFlightsRequest(limit=10)
response = await top_flights(client, message, headers)
return parse_data(response.content, TopFlightsResponse).unwrap()
data = await top_flights_data()
data
scoreboard_list {
flight_id: 911336284
live_clicks: 1648
total_clicks: 6664
callsign: "LEE92"
from_iata: "QKG"
from_city: "Leeming"
type: "HUNT"
full_description: "Hawker Hunter T2"
}
scoreboard_list {
flight_id: 911326556
live_clicks: 1144
total_clicks: 8848
callsign: "SARAB"
type: "HAWK"
full_description: "British Aerospace Hawk Mk167"
}
scoreboard_list {
flight_id: 911338539
live_clicks: 904
total_clicks: 1764
flight_number: "TN80001"
callsign: "TN080001"
from_iata: "QCY"
...
to_iata: "RMQ"
to_city: "Taichung"
type: "B738"
full_description: "Boeing 737-8AL"
}
Live Trail¤
Unstable API: returns empty DATA frame as of Sep 2024
import httpx
from fr24.grpc import live_trail
from fr24.proto.v1_pb2 import LiveTrailRequest, LiveTrailResponse
from fr24.proto import parse_data
from fr24.proto.headers import get_grpc_headers
async def live_trail_data() -> LiveTrailResponse:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
message = LiveTrailRequest(flight_id=0x395C43CF)
response = await live_trail(client, message, headers)
return parse_data(response.content, LiveTrailResponse).unwrap()
data = await live_trail_data()
data
radar_records_list {
timestamp: 1720064455
lat: 30.2406578
lon: 120.420403
spd: 15
heading: 61
callsign: "CPA959"
}
radar_records_list {
timestamp: 1720064462
lat: 30.2408924
lon: 120.420937
heading: 61
callsign: "CPA959"
}
radar_records_list {
timestamp: 1720064480
lat: 30.2415791
lon: 120.422478
spd: 18
heading: 61
callsign: "CPA959"
}
radar_records_list {
timestamp: 1720064488
...
heading: 269
vspd: -960
squawk: 13874
callsign: "CPA959"
}
...
Historic Trail¤
Unstable API: gateway timeout
import httpx
from fr24.grpc import historic_trail
from fr24.proto.v1_pb2 import HistoricTrailRequest, HistoricTrailResponse
from fr24.proto import parse_data
from fr24.proto.headers import get_grpc_headers
async def historic_trail_data() -> HistoricTrailResponse:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
message = HistoricTrailRequest(flight_id=0x395C43CF)
response = await historic_trail(client, message, headers)
return parse_data(response.content, HistoricTrailResponse).unwrap()
data = await historic_trail_data()
data
504 GATEWAY TIMEOUT
Flight Details¤
import httpx
from fr24.grpc import FlightDetailsParams, flight_details
from fr24.proto.v1_pb2 import FlightDetailsResponse
from fr24.proto import parse_data
from fr24.proto.headers import get_grpc_headers
async def flight_details_data() -> FlightDetailsResponse:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
params = FlightDetailsParams(flight_id=0x3C500FDB)
response = await flight_details(client, params, headers)
return parse_data(response.content, FlightDetailsResponse).unwrap()
data = await flight_details_data()
data
aircraft_info {
icao_address: 7866977
reg: "B-KQM"
type: "B77W"
icon: B777
full_description: "Boeing 777-367(ER)"
images_list {
url: "https://www.jetphotos.com/photo/11825817"
copyright: "ZSHC_Linzx"
thumbnail: "https://cdn.jetphotos.com/200/5/1291679_1756473618_tb.jpg"
medium: "https://cdn.jetphotos.com/400/5/1291679_1756473618.jpg"
large: "https://cdn.jetphotos.com/640/5/1291679_1756473618.jpg"
}
images_list {
url: "https://www.jetphotos.com/photo/11813969"
copyright: "CAN-Eric"
thumbnail: "https://cdn.jetphotos.com/200/5/967682_1755532162_tb.jpg"
medium: "https://cdn.jetphotos.com/400/5/967682_1755532162.jpg"
large: "https://cdn.jetphotos.com/640/5/967682_1755532162.jpg"
}
images_list {
url: "https://www.jetphotos.com/photo/11803561"
copyright: "cc12214"
thumbnail: "https://cdn.jetphotos.com/200/6/585221_1754572527_tb.jpg"
medium: "https://cdn.jetphotos.com/400/6/585221_1754572527.jpg"
large: "https://cdn.jetphotos.com/640/6/585221_1754572527.jpg"
}
msn_available: true
age_available: true
registered_owners: "Cathay Pacific (Oneworld Livery)"
is_country_of_reg_available: true
}
schedule_info {
flight_number: "CX251"
operated_by_id: 57
painted_as_id: 57
origin_id: 1366
destination_id: 1942
scheduled_departure: 1758465600
scheduled_arrival: 1758516000
actual_departure: 1758466901
arr_terminal: "3"
}
flight_progress {
traversed_distance: 13728
remaining_distance: 9652855
elapsed_time: 156
remaining_time: 51708
eta: 1758518765
great_circle_distance: 9647791
mean_flight_time: 48161
flight_stage: ASCENDING
delay_status: RED
}
flight_info {
flightid: 1011879899
lat: 22.3374939
lon: 114.046074
track: 99
alt: 4975
speed: 205
timestamp_ms: 1758467055960
callsign: "CPA251"
ems_availability {
qnh_availability: true
amcp_availability: true
oat_availability: true
ias_availability: true
tas_availability: true
mach_availability: true
agps_availability: true
agpsdiff_availability: true
wind_dir_availability: true
wind_speed_availability: true
rs_availability: true
}
squawk_availability: true
vspeed_availability: true
airspace_availability: true
server_time_ms: 1758467057331
}
flight_plan {
}
flight_trail_list {
snapshot_id: 1758465991
lat: 22.3132782
lon: 113.934616
heading: 70
}
...
flight_trail_list {
snapshot_id: 1758467049
lat: 22.3383179
lon: 114.039337
altitude: 4800
spd: 206
heading: 91
}
position_buffer {
recent_positions_list {
delta_lat: -45
delta_lon: 274
delta_ms: 2710
}
recent_positions_list {
delta_lat: -50
delta_lon: 324
delta_ms: 3180
}
recent_positions_list {
delta_lat: -78
delta_lon: 585
delta_ms: 5720
}
recent_positions_list {
delta_lat: -86
delta_lon: 778
delta_ms: 7570
}
recent_positions_list {
delta_lat: -92
delta_lon: 976
delta_ms: 9540
}
recent_positions_list {
delta_lat: -91
delta_lon: 1073
delta_ms: 10500
}
}
Playback Flight¤
import httpx
from fr24.grpc import PlaybackFlightParams, playback_flight
from fr24.proto.v1_pb2 import PlaybackFlightResponse
from fr24.proto import parse_data
from fr24.proto.headers import get_grpc_headers
async def playback_flight_data() -> PlaybackFlightResponse:
headers = httpx.Headers(get_grpc_headers(auth=None))
async with httpx.AsyncClient() as client:
message = PlaybackFlightParams(
flight_id=0x3C500FDB, timestamp=1758467125
)
response = await playback_flight(client, message, headers)
return parse_data(response.content, PlaybackFlightResponse).unwrap()
data = await playback_flight_data()
data
aircraft_info {
icao_address: 7866977
reg: "B-KQM"
type: "B77W"
icon: B777
full_description: "Boeing 777-367(ER)"
images_list {
url: "https://www.jetphotos.com/photo/11825817"
copyright: "ZSHC_Linzx"
thumbnail: "https://cdn.jetphotos.com/200/5/1291679_1756473618_tb.jpg"
medium: "https://cdn.jetphotos.com/400/5/1291679_1756473618.jpg"
large: "https://cdn.jetphotos.com/640/5/1291679_1756473618.jpg"
}
images_list {
url: "https://www.jetphotos.com/photo/11813969"
copyright: "CAN-Eric"
thumbnail: "https://cdn.jetphotos.com/200/5/967682_1755532162_tb.jpg"
medium: "https://cdn.jetphotos.com/400/5/967682_1755532162.jpg"
large: "https://cdn.jetphotos.com/640/5/967682_1755532162.jpg"
}
images_list {
url: "https://www.jetphotos.com/photo/11803561"
copyright: "cc12214"
thumbnail: "https://cdn.jetphotos.com/200/6/585221_1754572527_tb.jpg"
medium: "https://cdn.jetphotos.com/400/6/585221_1754572527.jpg"
large: "https://cdn.jetphotos.com/640/6/585221_1754572527.jpg"
}
msn_available: true
age_available: true
registered_owners: "Cathay Pacific (Oneworld Livery)"
is_country_of_reg_available: true
}
schedule_info {
flight_number: "CX251"
operated_by_id: 57
painted_as_id: 57
origin_id: 1366
destination_id: 1942
scheduled_departure: 1758465600
scheduled_arrival: 1758516000
actual_departure: 1758466901
arr_terminal: "3"
}
flight_info {
flightid: 1011879899
lat: 22.2923298
lon: 114.087372
track: 173
alt: 6325
speed: 242
timestamp_ms: 1758467118710
callsign: "CPA251"
ems_availability {
qnh_availability: true
amcp_availability: true
oat_availability: true
ias_availability: true
tas_availability: true
mach_availability: true
agps_availability: true
agpsdiff_availability: true
wind_dir_availability: true
wind_speed_availability: true
rs_availability: true
}
squawk_availability: true
vspeed_availability: true
airspace_availability: true
server_time_ms: 1758467148386
}
flight_trail_list {
snapshot_id: 1758465991
lat: 22.3132782
lon: 113.934616
heading: 70
}
...
flight_trail_list {
snapshot_id: 1758467147
lat: 22.2578888
lon: 114.087273
altitude: 6800
spd: 267
heading: 180
}
"""