Метки углеродного следа
Готовые к запуску примеры оценки выбросов CO₂ рейса в расчёте на пассажира и по набору маршрутов. Подробности методологии и рекомендации по RFI приведены в справочнике Выбросы CO₂.
| # | Вопрос | Используемые данные |
|---|---|---|
| 1 | Рассчитать CO₂ на пассажира для KJFK → KLAX на B738 | GET /carbon/estimate |
| 2 | Сформировать метку углеродного следа для результата поиска рейсов | GET /carbon/estimate |
| 3 | Сравнить CO₂ по 3 трансатлантическим маршрутам из EGLL | GET /carbon/estimate |
Требования
x-api-key в каждом запросе (прямая подписка). Подробнее →Установка
Приведённые ниже скрипты используют requests для вызовов API и rich для вывода в терминал. Установите один раз:
pip install requests rich1. CO₂ на пассажира: KJFK → KLAX на B738
Вопрос: Сколько CO₂ приходится на одного пассажира рейса B738 из Нью-Йорка в Лос-Анджелес?
Оценка выполняется по методологии ICAO Doc 9988. По умолчанию RFI не применяется — передайте include_rfi=true, чтобы получить значение с поправкой на климатический эффект (примерно в 2 раза больше базового CO₂).
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"
def fetch_carbon(
departure_icao: str,
arrival_icao: str,
aircraft_type: str | None = None,
passengers: int = 1,
include_rfi: bool = False,
) -> dict | None:
params: dict[str, str | int | bool] = {
"departure_icao": departure_icao,
"arrival_icao": arrival_icao,
"passengers": passengers,
"include_rfi": str(include_rfi).lower(),
}
if aircraft_type:
params["aircraft_type"] = aircraft_type
r = requests.get(
f"{BASE}/carbon/estimate",
headers=HEADERS,
params=params,
timeout=(10, 15),
)
if r.status_code == 404:
return None
r.raise_for_status()
return r.json()
def main() -> None:
data = fetch_carbon("KJFK", "KLAX", aircraft_type="B738", passengers=1)
if not data:
console.print("[red]No carbon estimate returned.[/red]")
return
co2_pax = data.get("co2_kg_per_passenger", 0.0)
co2_total = data.get("co2_kg_total", 0.0)
rfi = data.get("rfi_applied", False)
body = (
f"Route: [bold]{data.get('departure_icao')} → "
f"{data.get('arrival_icao')}[/bold]\n"
f"Aircraft: {data.get('aircraft_type', '—')}\n"
f"Distance: {data.get('distance_nm', 0):,.1f} nm\n"
f"CO₂/passenger: [bold green]{co2_pax:.1f} kg[/bold green] "
f"({co2_pax / 1000:.3f} t)\n"
f"CO₂ total load: {co2_total:,.1f} kg\n"
f"Methodology: {data.get('methodology', 'ICAO Doc 9988')}\n"
f"RFI applied: {'Yes' if rfi else 'No'}"
)
console.print(Panel(body, title="Carbon Estimate", style="green"))
console.print(
"[dim]Use include_rfi=true for climate-adjusted estimates "
"(applies ~2× multiplier per ICAO guidance).[/dim]"
)
if __name__ == "__main__":
main()Результат: Панель с маршрутом, типом ВС, расстоянием, CO₂ на пассажира в килограммах и тоннах, общими выбросами ВС, методологией и флагом RFI.
2. Метка углеродного следа для результата поиска рейсов
Вопрос: Какую категорию углеродного следа показать пассажиру рейса EGLL → KJFK на A380?
Отнесите значение CO₂ на пассажира к категории LOW / MEDIUM / HIGH / VERY HIGH для отображения в интерфейсе поиска авиабилетов.
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"
def fetch_carbon(
departure_icao: str,
arrival_icao: str,
aircraft_type: str | None = None,
passengers: int = 1,
include_rfi: bool = False,
) -> dict | None:
params: dict[str, str | int] = {
"departure_icao": departure_icao,
"arrival_icao": arrival_icao,
"passengers": passengers,
"include_rfi": str(include_rfi).lower(),
}
if aircraft_type:
params["aircraft_type"] = aircraft_type
r = requests.get(
f"{BASE}/carbon/estimate",
headers=HEADERS,
params=params,
timeout=(10, 15),
)
if r.status_code == 404:
return None
r.raise_for_status()
return r.json()
def co2_category(kg: float) -> tuple[str, str]:
"""Return (label, rich color) based on per-passenger kg thresholds."""
if kg < 50:
return "LOW", "green"
if kg < 150:
return "MEDIUM", "yellow"
if kg < 400:
return "HIGH", "orange3"
return "VERY HIGH", "red"
def main() -> None:
data = fetch_carbon(
"EGLL", "KJFK", aircraft_type="A388", passengers=1, include_rfi=False
)
if not data:
console.print("[red]No carbon estimate returned.[/red]")
return
co2_pax = data.get("co2_kg_per_passenger", 0.0)
label, color = co2_category(co2_pax)
route = f"{data.get('departure_icao')} → {data.get('arrival_icao')}"
body = (
f"[bold]{route}[/bold] · {data.get('aircraft_type', '—')}\n\n"
f"CO₂ per passenger: [bold {color}]{co2_pax:.1f} kg[/bold {color}]\n"
f"Carbon category: [bold {color}]{label}[/bold {color}]\n\n"
f"[dim]< 50 kg = LOW | 50–150 kg = MEDIUM | "
f"150–400 kg = HIGH | > 400 kg = VERY HIGH[/dim]"
)
console.print(Panel(body, title="Carbon Label", style=color))
if __name__ == "__main__":
main()Результат: Панель метки углеродного следа с цветовой кодировкой, показывающая маршрут, CO₂ на пассажира в килограммах и категорию (LOW / MEDIUM / HIGH / VERY HIGH) — так, как это отображалось бы в интерфейсе поиска авиабилетов.
3. Сравнение CO₂ трансатлантических маршрутов из EGLL
Вопрос: Какой трансатлантический маршрут из Лондона даёт наименьшие выбросы CO₂ на пассажира?
Запросите три маршрута параллельно и ранжируйте их по возрастанию CO₂ на пассажира. Как правило, более короткие маршруты и более новые типы ВС дают меньше CO₂.
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"
ROUTES = [
("EGLL", "KJFK", "A388"),
("EGLL", "KEWR", "B77W"),
("EGLL", "KBOS", "B738"),
]
def fetch_carbon(
departure: str, arrival: str, aircraft: str
) -> tuple[str, str, str, dict | None]:
try:
r = requests.get(
f"{BASE}/carbon/estimate",
headers=HEADERS,
params={
"departure_icao": departure,
"arrival_icao": arrival,
"aircraft_type": aircraft,
"passengers": 1,
"include_rfi": "false",
},
timeout=(10, 15),
)
if r.status_code == 404:
return departure, arrival, aircraft, None
r.raise_for_status()
return departure, arrival, aircraft, r.json()
except Exception as exc: # noqa: BLE001
console.print(f"[red]{departure}→{arrival}: {exc}[/red]")
return departure, arrival, aircraft, None
def main() -> None:
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as pool:
results = list(pool.map(lambda r: fetch_carbon(*r), ROUTES))
valid = [
(dep, arr, ac, d)
for dep, arr, ac, d in results
if d and d.get("co2_kg_per_passenger") is not None
]
valid.sort(key=lambda x: x[3].get("co2_kg_per_passenger", 0))
table = Table(title="Transatlantic CO₂ Comparison (1 passenger, no RFI)", show_lines=True)
table.add_column("Route", style="cyan", no_wrap=True)
table.add_column("Aircraft", justify="center")
table.add_column("Distance (nm)", justify="right")
table.add_column("CO₂/pax (kg)", justify="right", style="bold")
for i, (dep, arr, ac, d) in enumerate(valid):
distance = d.get("distance_nm")
dist_str = f"{distance:,.0f}" if distance else "—"
co2 = d.get("co2_kg_per_passenger", 0.0)
star = " ★" if i == 0 else ""
table.add_row(
f"{dep} → {arr}",
ac,
dist_str,
f"{co2:.1f}{star}",
)
console.print(table)
console.print(
"[dim]★ = lowest CO₂/pax. Shorter routes and newer aircraft types "
"generally produce less CO₂ per passenger.[/dim]"
)
if __name__ == "__main__":
main()Результат: Таблица, отсортированная по возрастанию CO₂ на пассажира; вариант с наименьшими выбросами отмечен символом ★. Показаны маршрут, тип ВС, расстояние и CO₂ на пассажира в килограммах.