NOTAMs
Ausführbare Beispiele für die Arbeit mit NOTAMs: Zusammenfassungen aktiver Meldungen, Filterung nach Flugplatz und Vorflugprüfungen für mehrere Flughäfen. Feldbeschreibungen finden Sie in der Referenz zu NOTAMs.
| # | Frage | Verwendete Daten |
|---|---|---|
| 1 | Alle aktiven NOTAMs für KJFK abrufen und eine Zusammenfassung anzeigen | GET /notams/{icao} |
| 2 | Pistenbezogene NOTAMs (Geltungsbereich Flugplatz) in EGLL filtern | GET /notams/{icao} |
| 3 | NOTAM-Prüfung vor dem Flug: Abflug- und Zielflughafen | GET /notams/{icao} |
Voraussetzungen
x-api-key bei jeder Anfrage (Direktabonnement). Mehr erfahren →Installation
Die folgenden Skripte verwenden requests für API-Aufrufe und rich für die Terminalausgabe. Einmalig installieren:
pip install requests rich1. Zusammenfassung aktiver NOTAMs für KJFK
Frage: Welche NOTAMs sind derzeit in KJFK aktiv?
NOTAMs werden häufig aktualisiert — cachen Sie sie höchstens 5 Minuten lang. Dieses Skript ruft alle aktiven Meldungen ab und zeigt eine sortierbare Übersichtstabelle an.
import os
from datetime import datetime
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_notams(icao: str) -> dict | None:
r = requests.get(
f"{BASE}/notams/{icao}",
headers=HEADERS,
timeout=(10, 15),
)
if r.status_code == 404:
return None
r.raise_for_status()
return r.json()
def format_dt(val: str | None) -> str:
if not val:
return "—"
try:
return datetime.fromisoformat(val).strftime("%m/%d %H:%Mz")
except ValueError:
return val[:16]
def main() -> None:
data = fetch_notams("KJFK")
if not data:
console.print("[red]No NOTAM data returned for KJFK.[/red]")
return
notams = data.get("notams", [])
total = data.get("total", len(notams))
sorted_notams = sorted(
notams,
key=lambda n: n.get("effective") or "",
)
table = Table(
title=f"KJFK NOTAMs — {total} active",
show_lines=True,
)
table.add_column("NOTAM ID", style="cyan", no_wrap=True)
table.add_column("Type", justify="center")
table.add_column("Scope", justify="center")
table.add_column("Effective", no_wrap=True)
table.add_column("Expiration", no_wrap=True)
table.add_column("Body")
for n in sorted_notams:
body = n.get("body") or n.get("raw", "")
snippet = (body[:60] + "…") if len(body) > 60 else body
table.add_row(
n.get("notam_id") or n.get("notam_id_domestic") or "—",
n.get("type") or "—",
n.get("scope") or "—",
format_dt(n.get("effective")),
format_dt(n.get("expiration")),
snippet,
)
console.print(table)
if __name__ == "__main__":
main()Ausgabe: Eine Tabelle aller aktiven NOTAMs, sortiert nach Beginn der Gültigkeit, mit ID, Typ, Geltungsbereich, Gültigkeitszeitraum und einer Vorschau des Textes mit 60 Zeichen.
2. Flugplatz-NOTAMs in EGLL
Frage: Welche NOTAMs in EGLL haben den Geltungsbereich Flugplatz (Sperrungen von Pisten/Rollwegen, Ausfälle der Befeuerung)?
Flugplatz-NOTAMs (scope == "AERODROME") wirken sich direkt auf den Bodenbetrieb aus. Filtern Sie vor dem Rollbriefing nach diesen Meldungen. Sie können Einträge mit scope: "FIR" auch serverseitig mit ?exclude_scope=FIR ausschließen, statt clientseitig zu filtern.
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_notams(icao: str) -> dict | None:
r = requests.get(
f"{BASE}/notams/{icao}",
headers=HEADERS,
timeout=(10, 15),
)
if r.status_code == 404:
return None
r.raise_for_status()
return r.json()
def main() -> None:
data = fetch_notams("EGLL")
if not data:
console.print("[red]No NOTAM data returned for EGLL.[/red]")
return
all_notams = data.get("notams", [])
aerodrome = [n for n in all_notams if n.get("scope") == "AERODROME"]
if not aerodrome:
console.print("[yellow]No aerodrome NOTAMs active at EGLL.[/yellow]")
return
console.print(
Panel(
f"[bold]{len(aerodrome)}[/bold] aerodrome-scoped NOTAM(s) at EGLL "
f"(scope=AERODROME: runway/taxiway closures, lighting outages)",
style="yellow",
)
)
table = Table(show_lines=True)
table.add_column("NOTAM ID", style="cyan", no_wrap=True)
table.add_column("Type", justify="center")
table.add_column("Q-Code")
table.add_column("Body")
for n in aerodrome:
body = n.get("body") or n.get("raw", "")
snippet = (body[:80] + "…") if len(body) > 80 else body
table.add_row(
n.get("notam_id") or n.get("notam_id_domestic") or "—",
n.get("type") or "—",
n.get("q_code") or "—",
snippet,
)
console.print(table)
if __name__ == "__main__":
main()Ausgabe: Ein Panel mit der Anzahl der Flugplatz-NOTAMs, gefolgt von einer Tabelle mit ID, Typ, Q-Code und gekürztem Text. Gibt „No aerodrome NOTAMs active“ aus, wenn keine Meldung zutrifft.
3. NOTAM-Prüfung vor dem Flug: Abflug und Ankunft
Frage: Welche NOTAMs sind sowohl an meinem Abflughafen (KJFK) als auch an meinem Zielflughafen (KLAX) aktiv?
Rufen Sie beide Flughäfen parallel ab, um die Latenz zu minimieren. Prüfen Sie alle NOTAMs — verlassen Sie sich nicht allein auf die automatische Auswertung.
import os
import concurrent.futures
import requests
from rich.console import Console
from rich.panel import Panel
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"
DEPARTURE = "KJFK"
ARRIVAL = "KLAX"
def fetch_notams(icao: str) -> tuple[str, dict | None]:
try:
r = requests.get(
f"{BASE}/notams/{icao}",
headers=HEADERS,
timeout=(10, 15),
)
if r.status_code == 404:
return icao, None
r.raise_for_status()
return icao, r.json()
except Exception as exc: # noqa: BLE001
console.print(f"[red]Error fetching {icao}: {exc}[/red]")
return icao, None
def print_airport_notams(icao: str, data: dict | None) -> None:
if not data:
console.print(Panel(f"[red]No data for {icao}[/red]"))
return
notams = data.get("notams", [])
total = data.get("total", len(notams))
console.print(
Panel(
f"[bold cyan]{icao}[/bold cyan] — {total} active NOTAM(s)",
style="blue",
)
)
for n in notams[:5]:
body = n.get("body") or n.get("raw", "")
notam_id = n.get("notam_id") or n.get("notam_id_domestic") or "—"
scope = n.get("scope") or "—"
snippet = (body[:80] + "…") if len(body) > 80 else body
console.print(f" [cyan]{notam_id}[/cyan] [{scope}] {snippet}")
if total > 5:
console.print(f" [dim]… and {total - 5} more NOTAM(s)[/dim]")
console.print()
def main() -> None:
airports = [DEPARTURE, ARRIVAL]
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as pool:
results = dict(pool.map(lambda a: fetch_notams(a), airports))
for icao in airports:
print_airport_notams(icao, results.get(icao))
console.print(
"[bold yellow]⚠ Review all NOTAMs — do not rely on automated "
"parsing alone.[/bold yellow]"
)
if __name__ == "__main__":
main()Ausgabe: Zwei Abschnitte — einer pro Flughafen —, die jeweils die Gesamtzahl der NOTAMs und die ersten 5 Meldungen als kompakte Liste zeigen. Am Ende wird eine Erinnerung ausgegeben, alle NOTAMs manuell zu prüfen.