|
Этот документ был автоматически переведён с английского языка с помощью Claude AI. Термины из области WMO/метеорологии должны быть проверены носителем языка перед использованием в производственной среде. Смотрите оригинал на английском для авторитетной версии. |
1. Обзор
WIS2 Downloader предоставляет REST API для управления подписками и мониторинга системы.
-
Базовый URL:
http://localhost:5002 -
Спецификация OpenAPI:
http://localhost:5002/openapi -
Swagger UI:
http://localhost:5002/swagger
Замените localhost:5002 на адрес вашего сервера при удалённом развёртывании. Базовый URL настраивается через WIS2DOWNLOADER_SUBSCRIPTION_MANAGER_URL в .env.
|
2. Аутентификация
API не требует аутентификации. В production-среде разместите его за обратным прокси с аутентификацией (см. раздел Контроль доступа руководства администратора).
3. API подписок
Каждая подписка идентифицируется UUID и связывает MQTT-топик, путь сохранения, необязательный фильтр, необязательные учётные данные и очередь. Несколько подписок могут использовать один топик — MQTT-соединение открывается один раз, а сообщения маршрутизируются ко всем совпадающим подпискам.
3.1. Список подписок
Возвращает все активные подписки, сгруппированные по топику.
GET /subscriptions
3.1.1. Ответ
| Статус | Описание |
|---|---|
200 |
Успех — карта топик → карта UUID подписки → детали подписки |
503 |
Redis недоступен |
3.1.2. Пример
curl http://localhost:5002/subscriptions
{
"cache/a/wis2/+/data/core/weather/surface-based-observations/#": {
"550e8400-e29b-41d4-a716-446655440000": {
"save_path": "surface-obs",
"filter": {}
},
"661f9511-f30c-52e5-b827-557766551111": {
"save_path": "surface-obs-bufr",
"filter": {
"name": "bufr-only",
"rules": [
{ "id": "accept-bufr", "order": 1, "match": { "media_type": { "equals": "application/bufr" } }, "action": "accept" }
]
}
}
}
}
3.2. Создание подписки
Создаёт новую подписку. Присваивает UUID и возвращает полную запись подписки.
Если это первая подписка для указанного топика, открывается MQTT-соединение. Дополнительные подписки для того же топика используют существующее соединение.
POST /subscriptions
Content-Type: application/json
3.2.1. Тело запроса
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
|
string |
Да |
Шаблон MQTT-топика WIS2. Поддерживает подстановочные символы |
|
string |
Нет |
Подкаталог в корне данных, куда сохраняются файлы. |
|
объект |
Нет |
Фильтр на основе правил. См. Схема фильтра. |
|
объект |
Нет |
HTTP-учётные данные для наборов данных с контролируемым доступом. См. Схема учётных данных. |
|
string |
Нет |
Очередь загрузки: |
3.2.2. Ответ
| Статус | Описание |
|---|---|
201 |
Создано — возвращает полную запись подписки |
400 |
Неверный запрос — отсутствующие или недопустимые поля |
503 |
Сервис недоступен — сбой подключения к Redis |
3.2.3. Заголовки ответа
| Заголовок | Описание |
|---|---|
|
URL для получения созданной подписки ( |
3.2.4. Примеры
# Простая подписка
curl -X POST http://localhost:5002/subscriptions \
-H "Content-Type: application/json" \
-d '{
"topic": "cache/a/wis2/+/data/core/weather/surface-based-observations/#",
"target": "surface-obs"
}'
# Подписка с фильтром
curl -X POST http://localhost:5002/subscriptions \
-H "Content-Type: application/json" \
-d '{
"topic": "cache/a/wis2/+/data/core/weather/surface-based-observations/#",
"target": "surface-obs-bufr",
"filter": {
"name": "bufr-only",
"rules": [
{ "id": "accept-bufr", "order": 1, "match": { "media_type": { "equals": "application/bufr" } }, "action": "accept" },
{ "id": "default-reject", "order": 999, "match": { "always": true }, "action": "reject" }
]
}
}'
# Подписка на набор данных с контролируемым доступом с базовой аутентификацией
curl -X POST http://localhost:5002/subscriptions \
-H "Content-Type: application/json" \
-d '{
"topic": "cache/a/wis2/+/data/recommended/weather/surface-based-observations/#",
"target": "restricted-obs",
"credentials": { "type": "basic", "username": "myuser", "password": "s3cr3t" }
}'
# Направить крупные загрузки в очередь large-files
curl -X POST http://localhost:5002/subscriptions \
-H "Content-Type: application/json" \
-d '{
"topic": "cache/a/wis2/fr-meteofrance/data/core/weather/space-based-observations/noaa-21/cris",
"target": "space-obs",
"queue": "large_files"
}'
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"topic": "cache/a/wis2/+/data/core/weather/surface-based-observations/#",
"save_path": "surface-obs",
"filter": {},
"credentials": null,
"queue": "small_files"
}
3.3. Получение подписки
Возвращает полную запись конкретной подписки.
GET /subscriptions/{id}
3.3.1. Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
|
string (UUID) |
UUID подписки, возвращённый при её создании |
3.3.2. Ответ
| Статус | Описание |
|---|---|
200 |
Успех |
404 |
Подписка не найдена |
3.3.3. Пример
curl http://localhost:5002/subscriptions/550e8400-e29b-41d4-a716-446655440000
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"topic": "cache/a/wis2/+/data/core/weather/surface-based-observations/#",
"save_path": "surface-obs",
"filter": {},
"credentials": null,
"queue": "small_files"
}
Секреты учётных данных (password, token) никогда не возвращаются. В ответах включаются только type и username (для базовой аутентификации).
|
3.4. Обновление подписки
Обновляет путь сохранения, фильтр, учётные данные или очередь существующей подписки. Топик изменить нельзя — удалите подписку и создайте новую, чтобы изменить топик.
PUT /subscriptions/{id}
Content-Type: application/json
3.4.1. Тело запроса
Все поля необязательны. Обновляются только предоставленные поля.
| Поле | Тип | Описание |
|---|---|---|
|
string |
Новый подкаталог в корне данных |
|
объект |
Новый фильтр на основе правил (заменяет существующий) |
|
объект |
Новые учётные данные (заменяют существующие) |
|
string |
Новая очередь: |
3.4.2. Ответ
| Статус | Описание |
|---|---|
200 |
Обновлённая запись подписки |
400 |
Недопустимое значение поля |
404 |
Подписка не найдена |
503 |
Redis недоступен |
3.4.3. Пример
curl -X PUT http://localhost:5002/subscriptions/550e8400-e29b-41d4-a716-446655440000 \
-H "Content-Type: application/json" \
-d '{ "target": "surface-obs-v2", "queue": "high_priority" }'
3.5. Удаление подписки
Удаляет подписку. Если это последняя подписка для топика, MQTT-соединение для этого топика закрывается.
DELETE /subscriptions/{id}
3.5.1. Ответ
| Статус | Описание |
|---|---|
200 |
Успешно удалено |
404 |
Подписка не найдена |
503 |
Redis недоступен |
3.5.2. Пример
curl -X DELETE http://localhost:5002/subscriptions/550e8400-e29b-41d4-a716-446655440000
{ "status": "deleted", "id": "550e8400-e29b-41d4-a716-446655440000" }
4. API мониторинга
4.1. Проверка работоспособности
GET /health
Всегда возвращает 200. Проверьте поле status для фактического состояния.
curl http://localhost:5002/health
{ "status": "healthy" }
4.2. Метрики Prometheus
Возвращает метрики в текстовом формате Prometheus.
GET /metrics
4.2.1. Доступные метрики
| Метрика | Тип | Метки | Описание |
|---|---|---|---|
|
Counter |
status |
Всего уведомлений, обработанных Celery |
|
Counter |
cache, media_type |
Успешно загруженные файлы |
|
Counter |
cache, media_type |
Всего загруженных байт |
|
Counter |
reason |
Пропущенные уведомления по причине |
|
Counter |
cache, reason |
Неудачные загрузки |
|
Gauge |
queue_name |
Текущие задачи во всех очередях Celery |
4.2.2. Пример
curl http://localhost:5002/metrics
4.3. Спецификация OpenAPI
GET /openapi
4.4. Swagger UI
Интерактивная документация API доступна по адресу:
GET /
GET /swagger
5. Ответы об ошибках
Все ответы об ошибках имеют следующий формат:
{ "error": "Error message describing the problem" }
5.1. Распространённые сообщения об ошибках
| Статус | Ошибка | Причина |
|---|---|---|
400 |
"No topic provided" |
POST /subscriptions без поля |
400 |
"credentials.type must be 'basic' or 'bearer'" |
Недопустимый тип учётных данных |
400 |
"queue must be one of: high_priority, large_files, small_files" |
Неизвестное имя очереди |
404 |
"Subscription '{id}' not found" |
UUID не существует |
503 |
"Failed to connect to Redis: …" |
Redis недоступен |
503 |
"Failed to queue subscription command…" |
Сбой Redis pub/sub |
6. Схемы данных
6.1. Подписка
Полная запись подписки, как она хранится и возвращается API.
| Поле | Тип | Описание |
|---|---|---|
|
string (UUID) |
Уникальный идентификатор, присваиваемый при создании |
|
string |
Шаблон MQTT-топика WIS2 |
|
string | null |
Подкаталог в корне данных, куда сохраняются файлы |
|
объект |
Фильтр на основе правил (пустой объект |
|
объект | null |
Учётные данные для загрузки. Секреты скрыты в ответах. |
|
string |
Очередь загрузки: |
6.2. Схема фильтра
Фильтры используют упорядоченный список правил. Правила оцениваются по порядку; применяется действие первого совпавшего правила. Если ни одно правило не совпадает, файл принимается.
| Поле | Тип | Описание |
|---|---|---|
|
string |
Имя фильтра для идентификации |
|
массив |
Упорядоченный список правил фильтра |
6.2.1. Схема правила фильтра
| Поле | Тип | Описание |
|---|---|---|
|
string |
Уникальный идентификатор правила |
|
integer |
Порядок выполнения — меньшие значения выполняются первыми |
|
объект |
Условие для проверки. См. Условия совпадения. |
|
string |
|
6.2.2. Условия совпадения
| Условие | Описание |
|---|---|
|
Совпадение по MIME-типу файла |
|
Совпадение по размеру файла в байтах |
|
Совпадение по идентификатору источника данных (напр. |
|
Совпадение по идентификатору данных WIS2 |
|
Совпадение по URL загрузки |
|
Безусловное совпадение (используется как правило по умолчанию для всех) |
Строковые операторы: equals, not_equals, in, not_in, pattern (glob), regex
Операторы размера/чисел: gt_bytes, lt_bytes, gte_bytes, lte_bytes, between_bytes
Логические комбинаторы: all (И), any (ИЛИ), not
6.2.3. Пример фильтра
Принимать только BUFR-файлы размером менее 10 МБ; отклонять всё остальное:
{
"name": "bufr-small",
"rules": [
{
"id": "accept-small-bufr",
"order": 1,
"match": {
"all": [
{ "media_type": { "equals": "application/bufr" } },
{ "size": { "lt_bytes": 10485760 } }
]
},
"action": "accept"
},
{
"id": "default-reject",
"order": 999,
"match": { "always": true },
"action": "reject"
}
]
}
6.3. Схема учётных данных
Используется для аутентификации HTTP-загрузок из наборов данных с контролируемым доступом.
password и token доступны только для записи — принимаются в запросах, но никогда не возвращаются в ответах.
|
| Поле | Тип | Описание |
|---|---|---|
|
string |
|
|
string |
Обязательно, когда |
|
string (только запись) |
Обязательно, когда |
|
string (только запись) |
Обязательно, когда |
7. Справочник шаблонов топиков
7.1. Структура топиков WIS2
{origin|cache}/a/wis2/{centre-id}/data/{data-policy}/{earth-system-domain}/{category}/...
-
origin— Исходные данные от поставщика данных -
cache— Кэшированная копия из Global Cache (рекомендуется для надёжности) -
{centre-id}— Идентификатор центра. Первое поле — код страны ISO2C, второе — описательное название центра (напр.de-dwdдля Deutscher Wetterdienst,fr-meteofranceдля Météo-France) -
{data-policy}— Единая политика данных ВМО:core(свободный доступ) илиrecommended(может требовать учётные данные) -
{earth-system-domain}— Домен системы Земли из единой политики данных ВМО
7.2. Подстановочные символы
| Шаблон | Символ | Описание |
|---|---|---|
Один уровень |
|
Совпадает ровно с одним уровнем |
Несколько уровней |
|
Совпадает с нулём или более уровнями (должен стоять в конце) |
7.3. Примеры
| Шаблон | Совпадает с |
|---|---|
|
Все данные Deutscher Wetterdienst |
|
Наземные наблюдения от всех центров |
|
Все основные данные любого центра |
|
Все метеорологические данные (любая политика) от любого центра |