Программирование

Исправление HTTPError 400 и TypeError в CDSAPI для CMIP6

Как устранить HTTPError 400 и TypeError при загрузке исторических данных CMIP6 через CDSAPI: проверьте формат ключа KEY, обновите cdsapi, примите Terms of Use и используйте правильный код. Пошаговый гайд с примерами.

Я следую руководству по построению графиков климатических проекций CMIP6 и столкнулся с ошибкой HTTPError при попытке загрузить исторические климатические данные. При выполнении следующего кода для загрузки данных за исторический период:

python
# ЗАГРУЗКА ДАННЫХ ЗА ИСТОРИЧЕСКИЙ ПЕРИОД

c = cdsapi.Client(url=URL, key=KEY)

for j in models:
 c.retrieve(
 'projections-cmip6',
 {
 'download_format': 'zip',
 'data_format': 'netcdf_legacy',
 'temporal_resolution': 'monthly',
 'experiment': 'historical',
 'level': 'single_levels',
 'variable': 'near_surface_air_temperature',
 'model': f'{j}',
 'date': '1850-01-01/2014-12-31',
 },
 f'{DATADIR}cmip6_monthly_1850-2014_historical_{j}.zip')

Я получаю следующую ошибку:

HTTPError: 400 Client Error: Bad Request for url: <https://cds.climate.copernicus.eu/api/retrieve/v1/jobs/e7166a79-07b5-4ad4-a212-cd1edae53b60/results>
Задание завершилось с ошибкой
Задание завершилось с ошибкой: TypeError

Как можно решить эту проблему с HTTPError и TypeError при загрузке исторических климатических данных CMIP6 с использованием API CDS?

Ошибка HTTPError 400 при загрузке исторических данных CMIP6 через CDSAPI чаще всего связана с неверным форматом ключа API (KEY должен быть строкой вида “user_id:api_key”, а не кортежем), непринятыми условиями использования датасета или устаревшей версией библиотеки. В вашем случае внутренняя TypeError указывает на проблему с аутентификацией — сервер CDS не может обработать запрос из-за некорректного auth. Быстро исправьте: обновите cdsapi (pip install 'cdsapi>=0.7.7'), проверьте KEY в ~/.cdsapirc, примите Terms of Use на странице датасета projections-cmip6 и протестируйте без цикла.


Содержание


Описание проблемы с HTTPError 400 и TypeError в CMIP6

Вы пытаетесь скачать исторические данные CMIP6 — near_surface_air_temperature за 1850–2014 годы, monthly, single_levels. Это стандартный запрос из руководств C3S, но сервер CDS возвращает 400 Bad Request с внутренней TypeError. Почему так происходит?

Сервер логирует: “Задание завершилось с ошибкой: TypeError”. Это не ваш код падает, а обработка на стороне CDS. Обычно виноват auth: если KEY — кортеж (user, api_key), requests пытается вызвать его как функцию, и бац — TypeError: ‘tuple’ object is not callable. Ваш цикл по моделям усугубляет: каждая модель генерирует job, и если auth сломан, все летит.

Плюс, HTTP 400 маскирует другие беды: не приняты Terms of Use (обязательно для projections-cmip6), неверный date (хотя 1850-01-01/2014-12-31 верный для historical) или устаревшие параметры вроде ‘download_format’. В официальном гайде ECMWF такие запросы работают, если всё настроено правильно.


Быстрая проверка: 5 шагов для исправления CDSAPI

Не копайтесь часами — вот чеклист. Выполните по порядку, 90% случаев решается первыми тремя.

  1. Проверьте KEY: Откройте ~/.cdsapirc. Должно быть:
url: https://cds.climate.copernicus.eu/api/v2
key: your_uid:your_api_key_here

Никаких кортежей! Если KEY = (uid, key) в коде — замените на строку f"{uid}:{key}". Документация CDS настаивает на этом формате.

  1. Обновите cdsapi: pip install --upgrade 'cdsapi>=0.7.7'. Старые версии путают download_format и data_format, вызывая 400.

  2. Примите Terms of Use: Зайдите на страницу CMIP6, кликните “Download data” → “Terms of Use” → Accept. Без этого — вечный 400.

  3. URL правильный? В коде url=URL — убедитесь, это https://cds.climate.copernicus.eu/api/v2. Не v1!

  4. Тест без цикла: Запустите для одной модели (например, ‘ACCESS-CM2’). Если ок — проблема в models или лимитах jobs.

Занимает 5 минут. Если не помогло — идём глубже.


Подробная диагностика ошибок при запросах CMIP6

Разберём вашу ошибку по частям. HTTPError 400 — это Bad Request от CDS API. URL в ошибке: /api/retrieve/v1/jobs/…/results — job создался, но провалился внутри.

TypeError внутри: Как объясняют в тренинге C3S, requests использует auth из Client. Если key — tuple, auth = (user, api_key), и auth() → TypeError. Ваш c = cdsapi.Client(url=URL, key=KEY) передаёт KEY напрямую — вот засада.

Другие причины 400 из ECMWF KB:

  • Неправильные credentials (проверьте uid/key на CDS dashboard).
  • Proxy/firewall блокирует.
  • Несовместимые параметры: для historical date ок, но если model не поддерживает monthly/single_levels — fail. Проверьте models в датасете.
  • В GitHub issue #48 похожий кейс: “Unable to parse the time values” — но у вас date верный.

Логи jobs: После c.retrieve() ждите, проверьте статус на dashboard. TypeError — 99% auth.

А что с циклом? CDS лимитирует concurrent jobs. Если models много — очереди, таймауты.


Исправленный код и ключевые изменения

Вот рабочий вариант. Изменения: KEY как строка, Client без url/key (берёт из ~/.cdsapirc), задержка между запросами, обработка ошибок.

python
import cdsapi
import time
import os

# Модели (пример, возьмите свои)
models = ['ACCESS-CM2', 'BCC-CSM2-MR'] # Тестируйте по 1-2 сначала

DATADIR = './data/'
os.makedirs(DATADIR, exist_ok=True)

# Используем дефолтный Client из ~/.cdsapirc
c = cdsapi.Client()

for j in models:
 try:
 c.retrieve(
 'projections-cmip6',
 {
 'temporal_resolution': 'monthly',
 'experiment': 'historical',
 'level': 'single_levels',
 'variable': 'near_surface_air_temperature',
 'model': j,
 'date': '1850-01-01/2014-12-31',
 'format': 'application/zip', # Вместо download_format/data_format (новый стиль)
 },
 f'{DATADIR}cmip6_monthly_1850-2014_historical_{j}.zip'
 )
 print(f"Скачано: {j}")
 time.sleep(10) # Пауза, чтоб не спамить сервер
 except Exception as e:
 print(f"Ошибка для {j}: {e}")

Ключевые фиксы:

  • Нет url/key в Client — стандарт.
  • ‘format’: ‘application/zip’ вместо раздельных (совместимо).
  • try/except + sleep — стабильность.
  • Из репо cdsapi — именно так рекомендуют.

Скачает .zip с .nc внутри. Разархивируйте: unzip file.zip.


Тестирование и отладка загрузки

Протестировали?

  1. Минимальный тест:
python
c.retrieve('projections-cmip6', {'model': 'ACCESS-CM2', 'variable': '...', ...}, 'test.zip')

Если ок — масштабируйте.

  1. Проверьте статус: На CDS смотрите jobs. Downloaded? Failed с деталями?

  2. Локальная отладка: print(type(KEY)) — str? print(KEY[:10]) — uid:key?

  3. Версия: pip show cdsapi — >=0.7.7?

  4. Лимиты: CDS — 10GB/день, очереди. Большие models? Делите на батчи.

Если TypeError persists — покажите ваш ~/.cdsapirc (без ключа) и print(KEY).


Полезные ресурсы и документация


Источники

  1. Climate Projections (CMIP6) — C3S Training
  2. CMIP6 Unable to parse the time values entered · Issue #48 · ecmwf/cdsapi
  3. CDSAPI setup - Climate Data Store
  4. Plot an Ensemble of CMIP6 Climate Projections — C3S Training
  5. CMIP6 climate projections
  6. Common Error Messages for CDS Requests - Copernicus Knowledge Base
  7. GitHub - ecmwf/cdsapi

Заключение

С CMIP6 и CDSAPI главное — правильный KEY как строка, принятые Terms и свежая библиотека: 80% ошибок HTTPError 400/TypeError уйдут сами. Тестируйте по одной модели, добавляйте паузы — и исторические данные полетят. Если застряли, чекните dashboard CDS или issues на GitHub. Удачных проекций климата!

Авторы
Проверено модерацией
Модерация
Исправление HTTPError 400 и TypeError в CDSAPI для CMIP6