NOTAM
Готовые к запуску примеры работы с NOTAM: сводки действующих извещений, фильтрация по аэродрому и предполётная проверка нескольких аэропортов. Описание полей см. в справочнике NOTAM.
| # | Вопрос | Используемые данные |
|---|---|---|
| 1 | Получить все действующие NOTAM для KJFK и вывести сводку | GET /notams/{icao} |
| 2 | Отфильтровать NOTAM, связанные с ВПП (область действия — аэродром), в EGLL | GET /notams/{icao} |
| 3 | Предполётная проверка NOTAM: аэропорты вылета и прилёта | GET /notams/{icao} |
Требования
x-api-key в каждом запросе (прямая подписка). Подробнее →Установка
Приведённые ниже скрипты используют requests для вызовов API и rich для вывода в терминал. Установите их один раз:
pip install requests rich1. Сводка действующих NOTAM для KJFK
Вопрос: какие NOTAM сейчас действуют в KJFK?
NOTAM обновляются часто — кэшируйте их не дольше 5 минут. Этот скрипт получает все действующие извещения и выводит сводную таблицу с сортировкой.
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()Результат: таблица всех действующих NOTAM, отсортированных по времени вступления в силу, с идентификатором, типом, областью действия, периодом действия и первыми 60 символами текста.
2. NOTAM аэродрома EGLL
Вопрос: какие NOTAM в EGLL относятся к аэродрому (закрытие ВПП и рулёжных дорожек, отказы светосигнального оборудования)?
NOTAM аэродрома (scope == "AERODROME") напрямую влияют на наземные операции. Отфильтруйте их перед брифингом по рулению. Вместо фильтрации на стороне клиента можно также исключить записи с scope: "FIR" на стороне сервера с помощью ?exclude_scope=FIR.
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()Результат: панель с количеством NOTAM аэродрома, за которой следует таблица с идентификатором, типом, Q-кодом и сокращённым текстом. Если совпадений нет, выводится «No aerodrome NOTAMs active».
3. Предполётная проверка NOTAM: вылет и прилёт
Вопрос: какие NOTAM действуют в моих аэропортах вылета (KJFK) и прилёта (KLAX)?
Запрашивайте данные по обоим аэропортам параллельно, чтобы минимизировать задержку. Просматривайте все NOTAM — не полагайтесь только на автоматический разбор.
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()Результат: два раздела — по одному на каждый аэропорт, — в каждом из которых показано общее количество NOTAM и первые 5 извещений в виде компактного списка. В конце выводится напоминание просмотреть все NOTAM вручную.
Задержки FAA
Задержки FAA NAS в реальном времени: программы наземных задержек, запреты вылетов, закрытия и программы управления потоками для аэропортов США.
Задержки FAA
Интеграция задержек FAA в национальной системе воздушного пространства (NAS) — запреты вылетов, программы GDP и оповещения о закрытии аэропортов.