|
Este documento ha sido traducido automáticamente desde el inglés por Claude AI. Los términos del dominio WMO/meteorológico deben ser revisados por un hablante nativo antes de su uso en producción. Consulte el documento original en inglés para la versión autoritativa. |
1. Descripción general
WIS2 Downloader expone una REST API para gestionar suscripciones y supervisar el sistema.
-
URL base:
http://localhost:5002 -
Especificación OpenAPI:
http://localhost:5002/openapi -
Swagger UI:
http://localhost:5002/swagger
Reemplace localhost:5002 con la dirección de su servidor si despliega de forma remota. La URL base se configura mediante WIS2DOWNLOADER_SUBSCRIPTION_MANAGER_URL en .env.
|
2. Autenticación
La API no requiere autenticación. En producción, colóquela detrás de un proxy inverso con autenticación (consulte la sección Control de acceso de la Guía de administración).
3. API de suscripciones
Cada suscripción se identifica por un UUID y asocia un topic MQTT, una ruta de guardado, un filtro opcional, credenciales opcionales y una cola. Varias suscripciones pueden compartir el mismo topic — la conexión MQTT se abre una sola vez y los mensajes se enrutan a todas las suscripciones coincidentes.
3.1. Listar suscripciones
Devuelve todas las suscripciones activas agrupadas por topic.
GET /subscriptions
3.1.1. Respuesta
| Estado | Descripción |
|---|---|
200 |
Éxito — mapa de topic → mapa de UUID de suscripción → detalle de suscripción |
503 |
Redis no disponible |
3.1.2. Ejemplo
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. Crear suscripción
Crea una nueva suscripción. Asigna un UUID y devuelve el registro de suscripción completo.
Si es la primera suscripción para el topic dado, se abre una conexión MQTT. Las suscripciones adicionales para el mismo topic reutilizan la conexión existente.
POST /subscriptions
Content-Type: application/json
3.2.1. Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
|
string |
Sí |
Patrón de topic MQTT WIS2. Admite comodines |
|
string |
No |
Subdirectorio bajo la raíz de datos donde se guardan los archivos. |
|
objeto |
No |
Filtro basado en reglas. Consulte Esquema de filtro. |
|
objeto |
No |
Credenciales HTTP para conjuntos de datos con acceso controlado. Consulte Esquema de credenciales. |
|
string |
No |
Cola de descarga: |
3.2.2. Respuesta
| Estado | Descripción |
|---|---|
201 |
Creado — devuelve el registro de suscripción completo |
400 |
Solicitud incorrecta — campos faltantes o inválidos |
503 |
Servicio no disponible — fallo en la conexión a Redis |
3.2.3. Cabeceras de respuesta
| Cabecera | Descripción |
|---|---|
|
URL para obtener la suscripción creada ( |
3.2.4. Ejemplos
# Suscripción simple
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"
}'
# Suscripción con filtro
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" }
]
}
}'
# Suscripción a un conjunto de datos con acceso controlado usando autenticación básica
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" }
}'
# Enviar descargas grandes a la cola 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. Obtener suscripción
Devuelve el registro completo de una suscripción específica.
GET /subscriptions/{id}
3.3.1. Parámetros de ruta
| Parámetro | Tipo | Descripción |
|---|---|---|
|
string (UUID) |
UUID de la suscripción devuelto al crearla |
3.3.2. Respuesta
| Estado | Descripción |
|---|---|
200 |
Éxito |
404 |
Suscripción no encontrada |
3.3.3. Ejemplo
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"
}
Los secretos de credenciales (password, token) nunca se devuelven. Solo se incluyen type y username (para autenticación básica) en las respuestas.
|
3.4. Actualizar suscripción
Actualiza la ruta de guardado, el filtro, las credenciales o la cola de una suscripción existente. El topic no puede cambiarse — elimine y vuelva a crear la suscripción para cambiar el topic.
PUT /subscriptions/{id}
Content-Type: application/json
3.4.1. Cuerpo de la solicitud
Todos los campos son opcionales. Solo se actualizan los campos proporcionados.
| Campo | Tipo | Descripción |
|---|---|---|
|
string |
Nuevo subdirectorio bajo la raíz de datos |
|
objeto |
Nuevo filtro basado en reglas (reemplaza el filtro existente) |
|
objeto |
Nuevas credenciales (reemplaza las credenciales existentes) |
|
string |
Nueva cola: |
3.4.2. Respuesta
| Estado | Descripción |
|---|---|
200 |
Registro de suscripción actualizado |
400 |
Valor de campo inválido |
404 |
Suscripción no encontrada |
503 |
Redis no disponible |
3.4.3. Ejemplo
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. Eliminar suscripción
Elimina una suscripción. Si es la última suscripción para su topic, la conexión MQTT de ese topic se cierra.
DELETE /subscriptions/{id}
3.5.1. Respuesta
| Estado | Descripción |
|---|---|
200 |
Eliminado correctamente |
404 |
Suscripción no encontrada |
503 |
Redis no disponible |
3.5.2. Ejemplo
curl -X DELETE http://localhost:5002/subscriptions/550e8400-e29b-41d4-a716-446655440000
{ "status": "deleted", "id": "550e8400-e29b-41d4-a716-446655440000" }
4. API de supervisión
4.1. Comprobación de estado
GET /health
Siempre devuelve 200. Compruebe el campo status para conocer el estado real.
curl http://localhost:5002/health
{ "status": "healthy" }
4.2. Métricas Prometheus
Devuelve métricas en formato de texto Prometheus.
GET /metrics
4.2.1. Métricas disponibles
| Métrica | Tipo | Etiquetas | Descripción |
|---|---|---|---|
|
Counter |
status |
Total de notificaciones procesadas por Celery |
|
Counter |
cache, media_type |
Archivos descargados correctamente |
|
Counter |
cache, media_type |
Total de bytes descargados |
|
Counter |
reason |
Notificaciones omitidas por motivo |
|
Counter |
cache, reason |
Descargas fallidas |
|
Gauge |
queue_name |
Tareas actuales en todas las colas Celery |
4.2.2. Ejemplo
curl http://localhost:5002/metrics
4.3. Especificación OpenAPI
GET /openapi
4.4. Swagger UI
Documentación API interactiva disponible en:
GET /
GET /swagger
5. Respuestas de error
Todas las respuestas de error siguen este formato:
{ "error": "Error message describing the problem" }
5.1. Mensajes de error comunes
| Estado | Error | Causa |
|---|---|---|
400 |
"No topic provided" |
POST /subscriptions sin campo |
400 |
"credentials.type must be 'basic' or 'bearer'" |
Tipo de credenciales inválido |
400 |
"queue must be one of: high_priority, large_files, small_files" |
Nombre de cola desconocido |
404 |
"Subscription '{id}' not found" |
UUID inexistente |
503 |
"Failed to connect to Redis: …" |
Redis no disponible |
503 |
"Failed to queue subscription command…" |
Redis pub/sub fallido |
6. Esquemas de datos
6.1. Suscripción
Registro de suscripción completo tal como se almacena y devuelve por la API.
| Campo | Tipo | Descripción |
|---|---|---|
|
string (UUID) |
Identificador único asignado al crear la suscripción |
|
string |
Patrón de topic MQTT WIS2 |
|
string | null |
Subdirectorio bajo la raíz de datos donde se guardan los archivos |
|
objeto |
Filtro basado en reglas (objeto vacío |
|
objeto | null |
Credenciales usadas para la descarga. Los secretos se ocultan en las respuestas. |
|
string |
Cola de descarga: |
6.2. Esquema de filtro
Los filtros usan una lista ordenada de reglas. Las reglas se evalúan en orden; se aplica la acción de la primera regla que coincida. Si ninguna regla coincide, el archivo se acepta.
| Campo | Tipo | Descripción |
|---|---|---|
|
string |
Nombre del filtro para identificación |
|
array |
Lista ordenada de reglas de filtro |
6.2.1. Esquema de regla de filtro
| Campo | Tipo | Descripción |
|---|---|---|
|
string |
Identificador único de la regla |
|
integer |
Orden de ejecución — los valores más bajos se ejecutan primero |
|
objeto |
Condición a evaluar. Consulte Condiciones de coincidencia. |
|
string |
|
6.2.2. Condiciones de coincidencia
| Condición | Descripción |
|---|---|
|
Coincidencia en el tipo MIME del archivo |
|
Coincidencia en el tamaño del archivo en bytes |
|
Coincidencia en el ID del centro emisor (ej. |
|
Coincidencia en el ID de datos WIS2 |
|
Coincidencia en la URL de descarga |
|
Coincidencia incondicional (usar como regla comodín predeterminada) |
Operadores de cadena: equals, not_equals, in, not_in, pattern (glob), regex
Operadores de tamaño/numérico: gt_bytes, lt_bytes, gte_bytes, lte_bytes, between_bytes
Combinadores lógicos: all (Y), any (O), not
6.2.3. Ejemplo de filtro
Aceptar solo archivos BUFR menores de 10 MB; rechazar todo lo demás:
{
"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. Esquema de credenciales
Se usa para autenticar descargas HTTP desde conjuntos de datos con acceso controlado.
password y token son de solo escritura — se aceptan en las solicitudes pero nunca se devuelven en las respuestas.
|
| Campo | Tipo | Descripción |
|---|---|---|
|
string |
|
|
string |
Requerido cuando |
|
string (solo escritura) |
Requerido cuando |
|
string (solo escritura) |
Requerido cuando |
7. Referencia de patrones de topics
7.1. Estructura de topics WIS2
{origin|cache}/a/wis2/{centre-id}/data/{data-policy}/{earth-system-domain}/{category}/...
-
origin— Datos originales del proveedor de datos -
cache— Copia en caché de un Global Cache (recomendado para mayor fiabilidad) -
{centre-id}— Identificador del centro. El primer campo es el código de país ISO2C y el segundo es un nombre descriptivo del centro (ej.de-dwdpara Deutscher Wetterdienst,fr-meteofrancepara Météo-France) -
{data-policy}— Política de datos unificada WMO:core(libre acceso) orecommended(puede requerir credenciales) -
{earth-system-domain}— Dominio del sistema terrestre de la política de datos unificada WMO
7.2. Comodines
| Patrón | Símbolo | Descripción |
|---|---|---|
Nivel único |
|
Coincide exactamente con un nivel |
Multinivel |
|
Coincide con cero o más niveles (debe estar al final) |
7.3. Ejemplos
| Patrón | Coincide con |
|---|---|
|
Todos los datos del Deutscher Wetterdienst |
|
Observaciones de superficie de todos los centros |
|
Todos los datos básicos de cualquier centro |
|
Todos los datos meteorológicos (cualquier política) de cualquier centro |