Integración con API de Clima ‐ Open‐Meteo - NSaldarriagaV/Ctrl-Store GitHub Wiki

Descripción

Ctrl+Store consume la API pública de Open-Meteo para mostrar el clima actual de Medellín en tiempo real en la barra de navegación principal.

API Consumida

URL: https://api.open-meteo.com/v1/forecast

Endpoint utilizado:

https://api.open-meteo.com/v1/forecast
?latitude=6.2518
&longitude=-75.5636
&current=temperature_2m,weather_code
&timezone=America/Bogota

Método: GET

Autenticación: No requerida (API pública y gratuita)

Documentación oficial: https://open-meteo.com/en/docs

Implementación

Ubicación en el Código

  • Servicio: ctrlstore/apps/common/weather.py → función get_medellin_weather()
  • Template Tag: ctrlstore/apps/common/templatetags/weather_tags.py → tag {% get_weather %}
  • Template: templates/base.html → muestra el clima en la navbar

Formato de Datos Recibidos

La API de Open-Meteo retorna JSON con esta estructura:

{
  "latitude": 6.125,
  "longitude": -75.75,
  "current": {
    "temperature_2m": 24.3,
    "weather_code": 3
  },
  "current_units": {
    "temperature_2m": "°C"
  }
}

Normalización y Procesamiento

Nuestro servicio procesa los datos:

  1. Temperatura: Extrae current.temperature_2m en grados Celsius
  2. Código de Clima: Extrae current.weather_code (código WMO)
  3. Mapeo a Descripción: Convierte el código numérico a descripción en español

Códigos WMO mapeados:

  • 0: Despejado
  • 1: Mayormente despejado
  • 2: Parcialmente nublado
  • 3: Nublado
  • 45: Niebla
  • 48: Niebla escarchada
  • 51-55: Llovizna (débil/normal/fuerte)
  • 61-65: Lluvia (débil/normal/fuerte)
  • 71-75: Nieve (débil/normal/fuerte)
  • 80-82: Chubascos (débiles/normales/fuertes)
  • 95: Tormenta

Funcionalidad

Visualización en Navbar

El clima se muestra en la barra de navegación principal (navbar) de todas las páginas:

Ubicación: Parte superior izquierda, junto al logo de Ctrl+Store

Formato mostrado:

Medellín: 24.3°C - Nublado

Características:

  • ✅ Temperatura en grados Celsius con 1 decimal
  • ✅ Descripción del estado del clima
  • ✅ Icono de clima (sol/nubes)
  • ✅ Actualización automática cada 5 minutos (caché)

Caché

El servicio implementa caché en memoria para optimizar llamadas:

  • TTL: 5 minutos (300 segundos)
  • Almacenamiento: Diccionario en memoria (_CACHE)
  • Ventaja: Reduce llamadas a la API y mejora el rendimiento

Manejo de Errores

  • ✅ Timeout de 5 segundos para evitar bloqueos
  • ✅ Fallback seguro: muestra "Clima no disponible" si falla
  • ✅ Logging de errores para debugging
  • ✅ No interrumpe la carga de la página si falla

Ejemplo de Uso

En Templates

{% load weather_tags %}
{% get_weather as weather %}

{% if weather.temp_c %}
    <span>{{ weather.temp_c|floatformat:1 }}°C</span>
{% endif %}
{% if weather.summary %}
    <span>{{ weather.summary }}</span>
{% endif %}

En Código Python

from ctrlstore.apps.common.weather import get_medellin_weather

weather = get_medellin_weather()
# Retorna: {"temp_c": 24.3, "summary": "Nublado"}

Parámetros de la API

Parámetro Valor Descripción
latitude 6.2518 Latitud de Medellín
longitude -75.5636 Longitud de Medellín
current temperature_2m,weather_code Variables actuales a obtener
timezone America/Bogota Zona horaria de Colombia

Limitaciones y Consideraciones

Límites de la API

  • Sin límite de llamadas (API pública y gratuita)
  • Sin API key requerida
  • Datos actualizados cada hora aproximadamente
  • ⚠️ Sin garantía de disponibilidad (servicio externo)

Rendimiento

  • Caché: 5 minutos reduce llamadas innecesarias
  • Timeout: 5 segundos evita bloqueos
  • Fallback: Si falla, no afecta la experiencia del usuario

Estructura del Código

Archivo: ctrlstore/apps/common/weather.py

def get_medellin_weather() -> dict:
    """
    Obtiene el clima actual de Medellín desde Open-Meteo.
    Retorna dict con 'temp_c' y 'summary'.
    Usa caché de 5 minutos.
    """
    # Verificar caché
    # Si expiró, llamar API
    # Procesar respuesta
    # Guardar en caché
    # Retornar resultado

Archivo: ctrlstore/apps/common/templatetags/weather_tags.py

@register.simple_tag
def get_weather():
    """Retorna el clima actual de Medellín."""
    return get_medellin_weather()

Pruebas

Para verificar que funciona:

  1. Visita cualquier página del sitio
  2. Verifica que aparezca el clima en la navbar superior
  3. Espera 5+ minutos y recarga para verificar el caché
  4. Revisa los logs si no aparece (puede ser bloqueo de red/firewall)

Troubleshooting

El clima no aparece

Posibles causas:

  1. Firewall/Red: Tu red bloquea conexiones salientes
  2. API caída: Open-Meteo temporalmente no disponible
  3. Timeout: La API tardó más de 5 segundos en responder

Solución:

  • Verifica conectividad: curl https://api.open-meteo.com/v1/forecast?latitude=6.2518&longitude=-75.5636&current=temperature_2m,weather_code&timezone=America/Bogota
  • Revisa logs de Django para ver errores específicos
  • El sistema mostrará "Clima no disponible" como fallback

El clima no se actualiza

Causa: Caché de 5 minutos activo

Solución:

  • Espera 5 minutos entre actualizaciones
  • O reinicia el servidor Django para limpiar caché

Alternativas Consideradas

  • OpenWeatherMap: Requiere API key (rechazado por simplicidad)
  • WeatherAPI: Requiere API key y tiene límites
  • Open-Meteo: ✅ Elegido por ser público, gratuito y sin límites

Mejoras Futuras

  • Agregar más ciudades (configurables)
  • Mostrar pronóstico de varios días
  • Caché distribuido (Redis) para producción
  • Widget de clima más detallado en página dedicada

Referencias

⚠️ **GitHub.com Fallback** ⚠️