# Лётно-технические характеристики

Интеграция профилей лётно-технических характеристик ВС — данные ICAO Doc 8643 для планирования с учётом дальности, скорости и категории турбулентности следа.



Готовые к запуску примеры получения и сравнения лётно-технических характеристик воздушных судов по коду типа ICAO. Определения полей и примечания о покрытии данных приведены в полном справочнике [Характеристики воздушных судов](/docs/v31/aircraft-performance).

| # | Вопрос                                                                 | Используемые данные                 |
| - | ---------------------------------------------------------------------- | ----------------------------------- |
| 1 | Каковы лётно-технические характеристики Boeing 737-800?                | `/aircraft/performance/{icao_type}` |
| 2 | Как A320, B738 и A35K соотносятся по дальности и крейсерской скорости? | `/aircraft/performance/{icao_type}` |

<DocRequirements>
  <DocRequirementAuth />
</DocRequirements>

### Установка [#install]

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

```bash
pip install requests rich
```

***

### 1. Характеристики Boeing 737-800 (B738) [#1-look-up-performance-specs-for-a-boeing-737-800-b738]

**Вопрос:** Каковы крейсерская скорость, дальность, габариты и эксплуатационные ограничения B738?

Данные о характеристиках привязаны к коду типа ICAO. Ответ 404 означает, что тип ещё не добавлен в базу характеристик, — это нормально для редких или совсем новых типов.

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

ICAO_TYPE = "B738"


def fetch_performance(icao_type: str) -> dict | None:
    r = requests.get(
        f"{BASE}/aircraft/performance/{icao_type}",
        headers=HEADERS,
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return None
    r.raise_for_status()
    return r.json()


def main() -> None:
    data = fetch_performance(ICAO_TYPE)

    if data is None:
        console.print(f"[yellow]Type {ICAO_TYPE} not in performance database.[/yellow]")
        return

    cruise_kt = data["cruise_speed_ktas"]
    cruise_kmh = round(cruise_kt * 1.852)
    range_nm = data["max_range_nm"]
    range_km = round(range_nm * 1.852)
    mtow_t = data["mtow_t"]
    mtow_lb = round(mtow_t * 2204.6)

    table = Table(title=f"Performance — {data['icao_type']} {data['name']}", border_style="cyan")
    table.add_column("Field", style="bold")
    table.add_column("Value")

    table.add_row("ICAO Type", data["icao_type"])
    table.add_row("Name", data["name"])
    table.add_row("Engine Type", data["engine_type"])
    table.add_row("Wake Category", data["wake_category"])
    table.add_row("Cruise Speed", f"{cruise_kt} kt  ({cruise_kmh} km/h)")
    table.add_row("Service Ceiling", f"{data['service_ceiling_ft']:,} ft")
    table.add_row("Max Range", f"{range_nm:,} nm  ({range_km:,} km)")
    table.add_row("Wingspan", f"{data['wing_span_m']} m")
    table.add_row("Length", f"{data['length_m']} m")
    table.add_row("MTOW", f"{mtow_t} t  ({mtow_lb:,} lb)")
    table.add_row("Max Passengers", str(data["max_passengers"]))

    console.print(table)


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

**Результат:** Таблица со всеми полями характеристик, включая пересчёт в другие единицы (km/h, km, lb).

***

### 2. Сравнение крейсерской скорости и дальности A320, B738 и A35K [#2-compare-cruise-speed-and-range-for-a320-vs-b738-vs-a35k]

**Вопрос:** Какой из трёх распространённых узкофюзеляжных и широкофюзеляжных типов имеет наибольшую дальность и как они соотносятся по крейсерской скорости?

Запросите каждый тип параллельно, отсортируйте по убыванию `max_range_nm` и отметьте тип с наибольшей дальностью символом ★. Типы, для которых получен ответ 404, пропускаются с предупреждением.

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

TYPES = ["A320", "B738", "A35K"]


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


def main() -> None:
    found: list[dict] = []
    missing: list[str] = []

    with ThreadPoolExecutor(max_workers=5) as pool:
        futures = {pool.submit(fetch_performance, t): t for t in TYPES}
        for future in as_completed(futures):
            icao_type, data = future.result()
            if data is None:
                missing.append(icao_type)
            else:
                found.append(data)

    if missing:
        console.print(f"[yellow]Skipped (not in database): {', '.join(missing)}[/yellow]")

    if not found:
        console.print("[red]No performance data available for any of the requested types.[/red]")
        return

    found.sort(key=lambda d: d["max_range_nm"], reverse=True)
    best_range = found[0]["icao_type"]

    table = Table(title="Aircraft Performance Comparison", border_style="cyan")
    table.add_column("Type", style="bold")
    table.add_column("Name")
    table.add_column("Cruise (kt)", justify="right")
    table.add_column("Range (nm)", justify="right")
    table.add_column("Ceiling (ft)", justify="right")
    table.add_column("Wake", justify="center")

    for d in found:
        star = " ★" if d["icao_type"] == best_range else ""
        table.add_row(
            d["icao_type"] + star,
            d["name"],
            str(d["cruise_speed_ktas"]),
            f"{d['max_range_nm']:,}",
            f"{d['service_ceiling_ft']:,}",
            d["wake_category"],
        )

    console.print(table)


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

**Результат:** Сравнительная таблица, отсортированная по убыванию дальности. Тип с наибольшей дальностью отмечен символом ★.
