# Flugpläne

Flughafen-Flugpläne integrieren – Abflug- und Ankunftstafeln mit historischen und zeitnah bevorstehenden Zeitfenstern.



Lauffähige Beispiele für Abflug- und Ankunftstafeln von Flughäfen über den Endpoint [Flugpläne](/docs/v31/schedules). Behandelt werden Tafeln für einzelne Flughäfen, Verspätungsanalysen und Verkehrsvergleiche nebeneinander.

| # | Frage                                                         | Verwendete Daten               |
| - | ------------------------------------------------------------- | ------------------------------ |
| 1 | Die nächsten heutigen Abflüge ab KJFK anzeigen                | Flugpläne (Abflüge)            |
| 2 | Wie viele Flüge sind heute in EGLL verspätet oder annulliert? | Flugpläne (Abflüge)            |
| 3 | Anzahl der Ankünfte und Abflüge in KJFK nebeneinander         | Flugpläne (Ankünfte + Abflüge) |

<DocRequirements>
  <DocRequirementAuth />
</DocRequirements>

### Installation [#install]

Die folgenden Skripte verwenden `requests` für API-Aufrufe und `rich` für die Terminalausgabe. Einmalig installieren:

```bash
pip install requests rich
```

***

### 1. Heutige Abflüge ab KJFK [#1-todays-departures-from-kjfk]

**Frage:** Die nächsten heutigen Abflüge ab KJFK anzeigen.

Die Schlüssel der Flugzeilen verwenden Großschreibung am Wortanfang: `Flight`, `Time`, `Status`, `Airline`, `Airport`. Kleingeschriebene Schlüssel liefern `None`.

```python
import os

import requests
from rich.console import Console
from rich.table import Table

console = Console()

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"

STATUS_STYLE: dict[str, str] = {
    "Departed": "green",
    "Delayed": "yellow",
    "Cancelled": "red",
    "Scheduled": "white",
    "Arrived": "green",
}


def fetch_departures(icao: str) -> list[dict]:
    r = requests.get(
        f"{BASE}/schedules/departures",
        headers=HEADERS,
        params={"icao": icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return []
    r.raise_for_status()
    return r.json().get("flights", [])


def main() -> None:
    flights = fetch_departures("KJFK")
    if not flights:
        console.print("[yellow]No departure data returned for KJFK.[/]")
        return

    display = flights[:10]

    table = Table(title=f"KJFK Departures — showing {len(display)} of {len(flights)}")
    table.add_column("Flight", style="cyan")
    table.add_column("Airline")
    table.add_column("Destination")
    table.add_column("Time")
    table.add_column("Status")

    for f in display:
        status = f.get("Status", "—")
        style = STATUS_STYLE.get(status, "white")
        table.add_row(
            f.get("Flight", "—"),
            f.get("Airline", "—"),
            f.get("Airport", "—"),
            f.get("Time", "—"),
            f"[{style}]{status}[/]",
        )

    console.print(table)


if __name__ == "__main__":
    main()
```

**Ausgabe:** Eine Tabelle mit bis zu 10 Abflügen mit Flugnummer, Fluggesellschaft, Code des Zielflughafens, planmäßiger Zeit und farbcodiertem Status (grün = Departed, gelb = Delayed, rot = Cancelled).

***

### 2. Übersicht über Verspätungen und Annullierungen in EGLL [#2-delay-and-cancellation-summary-at-egll]

**Frage:** Wie viele Flüge sind heute in EGLL derzeit verspätet oder annulliert?

```python
import os

import requests
from rich.console import Console
from rich.panel import Panel
from rich.table import Table

console = Console()

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"


def fetch_departures(icao: str) -> list[dict]:
    r = requests.get(
        f"{BASE}/schedules/departures",
        headers=HEADERS,
        params={"icao": icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return []
    r.raise_for_status()
    return r.json().get("flights", [])


def main() -> None:
    flights = fetch_departures("EGLL")
    if not flights:
        console.print("[yellow]No departure data returned for EGLL.[/]")
        return

    delayed = [f for f in flights if f.get("Status") == "Delayed"]
    cancelled = [f for f in flights if f.get("Status") == "Cancelled"]
    on_time = len(flights) - len(delayed) - len(cancelled)

    summary = (
        f"Total departures: [bold]{len(flights)}[/]\n"
        f"On time / departed: [green]{on_time}[/]\n"
        f"Delayed: [yellow]{len(delayed)}[/]\n"
        f"Cancelled: [red]{len(cancelled)}[/]"
    )
    console.print(Panel(summary, title="EGLL Departure Summary"))

    if delayed or cancelled:
        table = Table(title="Delayed and Cancelled Flights")
        table.add_column("Flight", style="cyan")
        table.add_column("Airline")
        table.add_column("Time")
        table.add_column("Status")

        for f in delayed:
            table.add_row(
                f.get("Flight", "—"),
                f.get("Airline", "—"),
                f.get("Time", "—"),
                "[yellow]Delayed[/]",
            )
        for f in cancelled:
            table.add_row(
                f.get("Flight", "—"),
                f.get("Airline", "—"),
                f.get("Time", "—"),
                "[red]Cancelled[/]",
            )

        console.print(table)


if __name__ == "__main__":
    main()
```

**Ausgabe:** Ein Übersichtspanel mit der Gesamtzahl sowie der Anzahl pünktlicher, verspäteter und annullierter Flüge, gefolgt von einer Tabelle aller betroffenen Flüge mit Fluggesellschaft, Zeit und Status.

***

### 3. Ankünfte und Abflüge in KJFK nebeneinander [#3-side-by-side-arrivals-and-departures-at-kjfk]

**Frage:** Wie verhalten sich die heutigen Gesamtzahlen der Ankünfte und Abflüge in KJFK zueinander, einschließlich der Anzahl der Störungen?

Ruft beide Richtungen parallel ab, um die tatsächliche Laufzeit zu verkürzen.

```python
import os
import concurrent.futures

import requests
from rich.console import Console
from rich.table import Table

console = Console()

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"


def fetch_schedule(icao: str, direction: str) -> list[dict]:
    r = requests.get(
        f"{BASE}/schedules/{direction}",
        headers=HEADERS,
        params={"icao": icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return []
    r.raise_for_status()
    return r.json().get("flights", [])


def summarize(flights: list[dict]) -> dict[str, int]:
    delayed = sum(1 for f in flights if f.get("Status") == "Delayed")
    cancelled = sum(1 for f in flights if f.get("Status") == "Cancelled")
    return {
        "total": len(flights),
        "delayed": delayed,
        "cancelled": cancelled,
        "on_time": len(flights) - delayed - cancelled,
    }


def main() -> None:
    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as ex:
        fut_arr = ex.submit(fetch_schedule, "KJFK", "arrivals")
        fut_dep = ex.submit(fetch_schedule, "KJFK", "departures")
        arrivals = fut_arr.result()
        departures = fut_dep.result()

    arr_stats = summarize(arrivals)
    dep_stats = summarize(departures)

    table = Table(title="KJFK Traffic Summary — Today")
    table.add_column("Direction", style="cyan")
    table.add_column("Total", justify="right")
    table.add_column("Delayed", justify="right")
    table.add_column("Cancelled", justify="right")
    table.add_column("On Time", justify="right")

    table.add_row(
        "Arrivals",
        str(arr_stats["total"]),
        f"[yellow]{arr_stats['delayed']}[/]",
        f"[red]{arr_stats['cancelled']}[/]",
        f"[green]{arr_stats['on_time']}[/]",
    )
    table.add_row(
        "Departures",
        str(dep_stats["total"]),
        f"[yellow]{dep_stats['delayed']}[/]",
        f"[red]{dep_stats['cancelled']}[/]",
        f"[green]{dep_stats['on_time']}[/]",
    )

    console.print(table)


if __name__ == "__main__":
    main()
```

**Ausgabe:** Eine zweizeilige Tabelle, die Ankünfte und Abflüge in KJFK vergleicht: Gesamtzahl der Flüge sowie die Anzahl verspäteter, annullierter und pünktlicher Flüge nebeneinander.
