# Flughäfen

Integrationsübersicht für Flughafendaten – detaillierte Profile, Suche und Funknavigationsanlagen (Navaids) mit lauffähigen Beispielen und Mustern für den Produktivbetrieb.



Lauffähige Beispiele für Flughafendaten: Eckdaten, Funkfrequenzen und ein Start- und Landebahnvergleich mehrerer Flughäfen über den Endpoint [Flughäfen](/docs/v31/airports).

| # | Frage                                                                                            | Verwendete Daten |
| - | ------------------------------------------------------------------------------------------------ | ---------------- |
| 1 | Welche Eckdaten hat ein bestimmter Flughafen, und welche ist seine längste Start- und Landebahn? | /airports/search |
| 2 | Welche Funkfrequenzen veröffentlicht dieser Flughafen?                                           | /airports/search |
| 3 | Zwei Flughäfen anhand ihrer Start- und Landebahndaten für die Flugzeugplanung vergleichen        | /airports/search |

<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. Eckdaten des Flughafens und längste Start- und Landebahn [#1-airport-key-facts-and-longest-runway]

**Frage:** Welche Eckdaten hat ein bestimmter Flughafen, und welche ist seine längste Start- und Landebahn?

Der Endpoint `/airports/search` liefert die vollständigen Flughafen-Metadaten einschließlich aller Start- und Landebahnen. Dieses Skript extrahiert das Wesentliche und ermittelt die längste verfügbare Start- und Landebahn.

```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"


def fetch_airport(icao: str) -> dict | None:
    r = requests.get(
        f"{BASE}/airports/search",
        headers=HEADERS,
        params={"icao": icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return None
    r.raise_for_status()
    return r.json()


def main() -> None:
    airport = fetch_airport("KJFK")
    if not airport:
        console.print("[yellow]Airport not found.[/]")
        return

    runways = airport.get("runways") or []
    longest = max((rwy.get("length_ft") or 0 for rwy in runways), default=0)

    table = Table(title=f"Airport Facts — {airport.get('ident', 'N/A')}")
    table.add_column("Field", style="cyan", no_wrap=True)
    table.add_column("Value")

    table.add_row("Name", airport.get("name", "—"))
    table.add_row("ICAO", airport.get("icao_code", "—"))
    table.add_row("IATA", airport.get("iata_code", "—"))
    table.add_row("Type", airport.get("type", "—"))
    table.add_row("Elevation", f"{airport.get('elevation_ft', '—')} ft")
    table.add_row("Municipality", airport.get("municipality", "—"))
    table.add_row("Country", (airport.get("country") or {}).get("name", "—"))
    table.add_row("Runways", str(len(runways)))
    table.add_row("Longest Runway", f"{longest:,} ft" if longest else "—")

    console.print(table)


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

**Ausgabe:** Eine Tabelle mit Name, ICAO-/IATA-Codes, Typ, Höhe, Gemeinde, Anzahl der Start- und Landebahnen und Länge der längsten Start- und Landebahn für KJFK.

***

### 2. Funkfrequenzen des Flughafens [#2-airport-radio-frequencies]

**Frage:** Welche Funkfrequenzen veröffentlicht dieser Flughafen?

ATC-Frequenzen (ATIS, GND, TWR, APP, DEP) sind in der Flughafen-Antwort enthalten. Sie werden nach Typ sortiert, damit Sie sie bei der Flugvorbereitung schnell nachschlagen können.

```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"


def fetch_airport(icao: str) -> dict | None:
    r = requests.get(
        f"{BASE}/airports/search",
        headers=HEADERS,
        params={"icao": icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return None
    r.raise_for_status()
    return r.json()


def main() -> None:
    airport = fetch_airport("EGLL")
    if not airport:
        console.print("[yellow]Airport not found.[/]")
        return

    frequencies = airport.get("frequencies") or []
    if not frequencies:
        console.print(f"[yellow]No frequencies published for {airport.get('ident')}.[/]")
        return

    frequencies.sort(key=lambda f: f.get("type", ""))

    table = Table(title=f"Radio Frequencies — {airport.get('name', 'N/A')}")
    table.add_column("Type", style="cyan", no_wrap=True)
    table.add_column("Description")
    table.add_column("Frequency (MHz)", justify="right")

    for freq in frequencies:
        table.add_row(
            freq.get("type", "—"),
            freq.get("description", "—"),
            str(freq.get("frequency_mhz", "—")),
        )

    console.print(table)
    console.print(
        "\n[dim]Tip: chain to [bold]/weather/metar/EGLL[/bold] for live wind and altimeter to "
        "cross-check ATIS readback.[/]"
    )


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

**Ausgabe:** Eine sortierte Tabelle der ATIS-, GND-, TWR-, APP- und DEP-Frequenzen für London Heathrow (EGLL) sowie ein Hinweis auf den [METAR](https://en.wikipedia.org/wiki/METAR)-Endpoint für aktuelle Bedingungen.

***

### 3. Zwei Flughäfen anhand ihrer Start- und Landebahndaten vergleichen [#3-compare-two-airports-by-runway-specs]

**Frage:** Wie unterscheiden sich zwei Flughäfen in ihrer Start- und Landebahnkonfiguration für die Flugzeugplanung?

Ruft KLAX und KJFK parallel ab und gibt eine Gegenüberstellung aus. Für Startleistungsberechnungen übergeben Sie die ICAO-Codes an [`/weather/metar/{icao}`](/docs/v31/weather-metar), um aktuelle Temperatur und aktuellen Luftdruck zu erhalten.

```python
import os
from concurrent.futures import ThreadPoolExecutor, as_completed

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"

AIRPORTS = ["KLAX", "KJFK"]


def fetch_airport(icao: str) -> tuple[str, dict | None]:
    r = requests.get(
        f"{BASE}/airports/search",
        headers=HEADERS,
        params={"icao": icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return icao, None
    r.raise_for_status()
    return icao, r.json()


def main() -> None:
    results: dict[str, dict | None] = {}
    with ThreadPoolExecutor(max_workers=2) as pool:
        futures = {pool.submit(fetch_airport, icao): icao for icao in AIRPORTS}
        for future in as_completed(futures):
            icao, data = future.result()
            results[icao] = data

    table = Table(title="Runway Comparison")
    table.add_column("Field", style="cyan", no_wrap=True)
    for icao in AIRPORTS:
        table.add_column(icao, justify="right")

    def runway_stat(data: dict | None, stat: str) -> str:
        if not data:
            return "—"
        runways = data.get("runways") or []
        if stat == "count":
            return str(len(runways))
        if stat == "longest":
            longest = max((r.get("length_ft") or 0 for r in runways), default=0)
            return f"{longest:,} ft" if longest else "—"
        return "—"

    def field(data: dict | None, key: str) -> str:
        if not data:
            return "—"
        val = data.get(key, "—")
        return str(val) if val is not None else "—"

    rows = [
        ("Airport Name", lambda d: field(d, "name")),
        ("Municipality", lambda d: field(d, "municipality")),
        ("Elevation", lambda d: f"{field(d, 'elevation_ft')} ft"),
        ("Runways", lambda d: runway_stat(d, "count")),
        ("Longest Runway", lambda d: runway_stat(d, "longest")),
    ]

    for label, getter in rows:
        table.add_row(label, *[getter(results.get(icao)) for icao in AIRPORTS])

    console.print(table)
    console.print(
        "\n[dim]For takeoff performance: fetch [bold]/weather/metar/{icao}[/bold] "
        "to get current OAT and QNH for density altitude calculation.[/]"
    )


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

**Ausgabe:** Eine Gegenüberstellung von KLAX und KJFK nach Name, Gemeinde, Höhe, Anzahl der Start- und Landebahnen und Länge der längsten Start- und Landebahn.
