Save up to 17% with yearly billing

See pricing

Задержки FAA

Готовые к запуску примеры запросов программ задержки вылетов на земле (GDP), запретов вылетов (ground stop), закрытий и программ регулирования потоков в воздушном пространстве (AFP) FAA. Определения полей приведены в справочнике Задержки FAA. Данные охватывают только аэропорты США (программы FAA ATCSCC).

#ВопросИспользуемые данные
1Есть ли сейчас активные задержки FAA где-либо в США?GET /delays/faa
2Действует ли сейчас в KJFK программа задержки вылетов на земле?GET /delays/faa/{icao}
3Проверить хабовые аэропорты на наличие активных программGET /delays/faa/{icao}

Требования

Авторизация
x-api-key в каждом запросе (прямая подписка). Подробнее →

Установка

Приведённые ниже скрипты используют requests для вызовов API и rich для вывода в терминал. Установите один раз:

pip install requests rich

1. Сводка задержек FAA по всей стране

Вопрос: Есть ли сейчас активные задержки FAA где-либо в США?

Один вызов /delays/faa возвращает все текущие программы задержки вылетов на земле, запреты вылетов, закрытия и программы регулирования потоков в воздушном пространстве. Кэшируйте ответ не дольше 2 минут.

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_faa_delays() -> dict | None:
    r = requests.get(f"{BASE}/delays/faa", headers=HEADERS, timeout=(10, 15))
    if r.status_code == 404:
        return None
    r.raise_for_status()
    return r.json()


def main() -> None:
    data = fetch_faa_delays()
    if not data:
        console.print("[red]Could not retrieve FAA delay data.[/red]")
        return

    total = data.get("total_alerts", 0)
    if total == 0:
        console.print("[green]No active FAA delays.[/green]")
        return

    console.print(Panel(f"[bold]{total}[/bold] active FAA alert(s)", style="yellow"))

    ground_delays = data.get("ground_delays", [])
    if ground_delays:
        t = Table(title="Ground Delay Programs (GDP)", show_lines=True)
        t.add_column("Airport", style="yellow")
        t.add_column("Name")
        t.add_column("Avg Delay")
        t.add_column("Max Delay")
        t.add_column("Reason")
        for row in ground_delays:
            t.add_row(
                row.get("airport", "—"),
                row.get("airport_name", "—"),
                row.get("avg_delay", "—"),
                row.get("max_delay", "—"),
                row.get("reason", "—"),
            )
        console.print(t)

    ground_stops = data.get("ground_stops", [])
    if ground_stops:
        t = Table(title="Ground Stops (GS)", show_lines=True)
        t.add_column("Airport", style="red")
        t.add_column("Name")
        t.add_column("End Time")
        t.add_column("Reason")
        for row in ground_stops:
            t.add_row(
                row.get("airport", "—"),
                row.get("airport_name", "—"),
                row.get("end_time", "—"),
                row.get("reason", "—"),
            )
        console.print(t)

    closures = data.get("closures", [])
    if closures:
        t = Table(title="Closures", show_lines=True)
        t.add_column("Airport", style="magenta")
        t.add_column("Name")
        t.add_column("Begin")
        t.add_column("Reopen")
        t.add_column("Reason")
        for row in closures:
            t.add_row(
                row.get("airport", "—"),
                row.get("airport_name", "—"),
                row.get("begin", "—"),
                row.get("reopen", "—"),
                row.get("reason", "—"),
            )
        console.print(t)


if __name__ == "__main__":
    main()

Результат: Если ограничений нет, выводится «No active FAA delays». В противном случае выводится сводная панель, а за ней — таблицы с цветовой кодировкой для каждого типа оповещений: жёлтым — GDP, красным — запреты вылетов, пурпурным — закрытия.


2. Статус задержек в KJFK

Вопрос: Действует ли сейчас в KJFK программа задержки вылетов на земле?

Используйте эндпоинт для конкретного аэропорта, чтобы проверить один аэропорт, не загружая полную картину по всей стране.

import os

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"

AIRPORT = "KJFK"


def fetch_airport_delays(icao: str) -> dict | None:
    r = requests.get(
        f"{BASE}/delays/faa/{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_airport_delays(AIRPORT)
    if not data:
        console.print(f"[red]No delay data returned for {AIRPORT}.[/red]")
        return

    total = data.get("total_alerts", 0)
    if total == 0:
        console.print(
            Panel(f"[green]No active delays at {AIRPORT}.[/green]", style="green")
        )
        return

    for gd in data.get("ground_delays", []):
        console.print(
            Panel(
                f"[bold yellow]Ground Delay Program (GDP)[/bold yellow]\n"
                f"Avg delay: {gd.get('avg_delay', '—')}  "
                f"Max delay: {gd.get('max_delay', '—')}\n"
                f"Reason: {gd.get('reason', '—')}",
                style="yellow",
                title=AIRPORT,
            )
        )

    for gs in data.get("ground_stops", []):
        console.print(
            Panel(
                f"[bold red]Ground Stop (GS)[/bold red]\n"
                f"End time: {gs.get('end_time', '—')}\n"
                f"Reason: {gs.get('reason', '—')}",
                style="red",
                title=AIRPORT,
            )
        )

    for cl in data.get("closures", []):
        console.print(
            Panel(
                f"[bold magenta]Closure[/bold magenta]\n"
                f"Begin: {cl.get('begin', '—')}  Reopen: {cl.get('reopen', '—')}\n"
                f"Reason: {cl.get('reason', '—')}",
                style="magenta",
                title=AIRPORT,
            )
        )


if __name__ == "__main__":
    main()

Результат: Если ограничений нет — зелёная панель «No active delays». В противном случае — по панели с цветовой кодировкой на каждый тип оповещения (жёлтая — GDP, красная — запрет вылетов, пурпурная — закрытие) со сроками и причиной.


3. Панель задержек по хабовым аэропортам

Вопрос: В каких из моих хабовых аэропортов сейчас действуют программы FAA?

Запросите каждый хаб по отдельности и сведите результаты в одну таблицу-панель. Обновляйте данные не чаще одного раза в 2 минуты.

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"

HUB_AIRPORTS = ["KJFK", "KLAX", "KORD", "KATL"]


def fetch_airport_delays(icao: str) -> tuple[str, dict | None]:
    try:
        r = requests.get(
            f"{BASE}/delays/faa/{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 summarise(data: dict | None) -> tuple[str, str, str, str]:
    """Return (active, alert_type, avg_delay, reason_snippet)."""
    if not data or data.get("total_alerts", 0) == 0:
        return "NO", "—", "—", "—"

    types = []
    avg_delay = "—"
    reason = "—"

    for gd in data.get("ground_delays", []):
        types.append("GDP")
        avg_delay = gd.get("avg_delay", "—")
        reason = (gd.get("reason") or "")[:40]

    for _ in data.get("ground_stops", []):
        types.append("GS")

    for _ in data.get("closures", []):
        types.append("Closure")

    for _ in data.get("airspace_flow_programs", []):
        types.append("AFP")

    return "YES", ", ".join(types) or "—", avg_delay, reason or "—"


def main() -> None:
    with concurrent.futures.ThreadPoolExecutor(max_workers=4) as pool:
        results = dict(pool.map(fetch_airport_delays, HUB_AIRPORTS))

    table = Table(title="Hub Airport FAA Delay Dashboard", show_lines=True)
    table.add_column("Airport", style="bold", no_wrap=True)
    table.add_column("Active", justify="center")
    table.add_column("Alert Type")
    table.add_column("Avg Delay", justify="center")
    table.add_column("Reason")

    for icao in HUB_AIRPORTS:
        active, alert_type, avg_delay, reason = summarise(results.get(icao))
        color = "red" if active == "YES" else "green"
        table.add_row(
            icao,
            f"[{color}]{active}[/{color}]",
            alert_type,
            avg_delay,
            reason,
        )

    console.print(table)
    console.print("[dim]Cache for 2 minutes max — FAA ATCSCC data, US only.[/dim]")


if __name__ == "__main__":
    main()

Результат: Единая таблица-панель с одной строкой на каждый хаб. Аэропорты с активными программами выделены красным, аэропорты без ограничений — зелёным. В каждой строке указаны тип оповещения, средняя задержка и фрагмент причины.