Кэширование и мониторинг
Обработка ошибок и коды 422: Обработка ошибок. HTTP-ошибки платформы и повторные попытки: Обработка ошибок.
Актуальность данных
Оба ML-эндпоинта возвращают детерминированные оценки для заданного набора входных данных. Результаты стабильны на горизонте от нескольких дней до нескольких недель — модель периодически переобучается, а не в реальном времени.
| Эндпоинт | Рекомендуемый TTL | Ключ кэша | Примечания |
|---|---|---|---|
GET /ml/flight-time | 24 часа | flighttime:{from}:{to}:{aircraft} | Статистика маршрутов меняется редко; 24 ч безопасно для большинства сценариев |
GET /carbon/estimate | 1–24 часа | carbon:{dep}:{arr}:{passengers}:{rfi} | Используйте более короткий TTL, если число пассажиров или флаг RFI часто меняются в вашем интерфейсе |
Статистика маршрутов рассчитывается на основе исторических эксплуатационных данных. TTL в 24 часа для времени полёта уместен, потому что нормы блочного времени для конкретной пары городов и типа ВС меняются только тогда, когда авиакомпании корректируют расписания по сезонам.
Раскрытие информации об ML: представляйте оценки как исторические средние значения, а не как прогнозы в реальном времени. Для времени полёта ветер и фактическая маршрутизация не моделируются. Оценки выбросов следуют методологии ICAO Doc 9988; при include_rfi=true значение включает индекс радиационного воздействия (Radiative Forcing Index) (~2× от базового CO₂), и это необходимо указывать в текстах для пассажиров.
import os
import time
import requests
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"
_cache: dict[str, tuple[dict, float]] = {}
def _cached_get(url: str, params: dict, ttl_seconds: int) -> dict | None:
"""In-process TTL cache. Replace with Redis for multi-instance deployments."""
key = url + str(sorted(params.items()))
cached = _cache.get(key)
if cached and time.time() < cached[1]:
return cached[0]
r = requests.get(url, headers=HEADERS, params=params, timeout=(10, 15))
if r.status_code == 404:
return None
r.raise_for_status()
data = r.json()
_cache[key] = (data, time.time() + ttl_seconds)
return data
def get_flight_time(
origin: str, destination: str, aircraft: str | None = None
) -> dict | None:
"""Cached ML flight time estimate. TTL 24 hours."""
params: dict[str, str] = {"from": origin, "to": destination}
if aircraft:
params["aircraft"] = aircraft
return _cached_get(f"{BASE}/ml/flight-time", params, ttl_seconds=86400)
def get_carbon(
departure_icao: str,
arrival_icao: str,
passengers: int = 1,
include_rfi: bool = False,
) -> dict | None:
"""Cached carbon estimate. TTL 1 hour (adjust to 24 h for stable routes)."""
params: dict[str, str | int] = {
"departure_icao": departure_icao,
"arrival_icao": arrival_icao,
"passengers": passengers,
"include_rfi": str(include_rfi).lower(),
}
return _cached_get(f"{BASE}/carbon/estimate", params, ttl_seconds=3600)
if __name__ == "__main__":
data = get_flight_time("KJFK", "KLAX", aircraft="B738")
if data:
print(
f"Estimated: {data['estimated_hours_display']} "
f"(range {data['min_minutes']}–{data['max_minutes']} min)"
)
print("Statistical average — wind not modelled.")
data2 = get_flight_time("KJFK", "KLAX", aircraft="B738")
print("Cache hit:", data2 is not None)Ограничения частоты запросов
Каждый ответ содержит заголовки ограничения частоты запросов. Отслеживайте X-RateLimit-Requests-Remaining суммарно по обоим эндпоинтам — каждый вызов /ml/flight-time и /carbon/estimate учитывается в вашей месячной квоте.
| Заголовок | Значение |
|---|---|
X-RateLimit-Requests-Limit | Месячная квота запросов вашего тарифа |
X-RateLimit-Requests-Remaining | Оставшиеся запросы в этом месяце |
X-RateLimit-Requests-Reset | Секунды до сброса квоты |
TTL в 24 часа для времени полёта сокращает число вызовов ML-эндпоинта до одного на маршрут в сутки — это важно, когда квота общая для всех эндпоинтов API.
Мониторинг
Логируйте при каждом ML-запросе:
endpoint(flight-timeилиcarbon)status_codeelapsed_msquota_remaining(изX-RateLimit-Requests-Remaining)cache_hit(boolean — был ли ответ получен из кэша?)
Оповещения настраивайте на:
status = 429— уменьшите частоту опроса или увеличьте TTLelapsed_ms > 5000неоднократно — рассмотрите более короткий тайм-аут с корректным фолбэкомquota_remaining < 200— приближение к месячному лимиту; увеличьте TTL или сократите число вызовов по уникальным маршрутам
См. также: Время полёта · Выбросы CO₂ · Обработка ошибок · Обработка ошибок