REST · FastAPI · Sevilla · tiempo real

Una parada.
Todos sus tiempos.

La API de TUSSAM es interna, sin CORS y con un rate limit agresivo. Esta API la convierte en un servicio abierto: normaliza coordenadas, cachea tiempos, reintenta con criterio y responde aunque el origen se caiga.

docker pull ghcr.io/686f6c61/api-tussam:main

GET /cercanas · respuesta real

El tablón de llegadas, en JSON

Simulación con datos reales de la red: paradas junto a la Puerta de Carmona.

43
Recaredo (Puerta Carmona) Calle Recaredo, 5 · a 74 m
    44
    San Esteban Calle San Esteban, 12 · a 158 m
      petición
      curl 'http://localhost:8081/cercanas
        ?lat=37.3896&lon=-5.9842
        &radio=300&max_paradas=2'

      Bounding box + Haversine sobre las 967 paradas, tiempos con cache de 60 segundos y fallback a la última respuesta buena si TUSSAM no contesta.

      Ciclo de una petición

      Cada petición deja el origen en paz

      El objetivo es dar tiempos frescos sin castigar a la API interna de TUSSAM. Cache con TTL, una sola llamada en vuelo por parada y reintentos que respetan el Retry-After del origen.

      1. 01
        Valida y limita

        Comprueba coordenadas y formato de parámetros, y aplica el rate limiting combinado por IP y por dispositivo antes de tocar nada.

      2. 02
        Busca la parada

        Prefiltra por bounding box y afina con Haversine sobre las 967 paradas cargadas en SQLite, sin salir a la red.

      3. 03
        Sirve desde cache

        Si hay tiempos de menos de 60 segundos, responde al instante. El origen solo se consulta cuando la cache expira.

      4. 04
        Consulta con single-flight

        Cien clientes preguntando por la misma parada generan una única petición saliente; el resto espera su resultado.

      5. 05
        Resiste y responde

        Reintenta ante 429/5xx, cae a la última respuesta buena si el origen falla, y devuelve JSON o GeoJSON señalizando el estado.

      Fiabilidad

      El origen falla.
      La API responde.

      reddelineas.tussam.es devuelve 429 con facilidad y a veces cambia el formato de la respuesta. Cada defensa está pensada para que el cliente final nunca herede esos problemas.

      El origen hace La API responde
      Rate limit agresivo

      Bloquea peticiones frecuentes con HTTP 429.

      Cache con TTL de 60 s

      Los tiempos se sirven desde SQLite; el origen solo se consulta al expirar.

      Se satura con ráfagas

      Muchas llamadas iguales a la vez lo tumban.

      Single-flight por parada

      Las peticiones concurrentes a una parada comparten una sola llamada saliente.

      Caídas intermitentes

      Responde 5xx o deja de contestar sin avisar.

      Cache stale marcada

      Sirve la última respuesta válida con stale: true y cached_at.

      Formato propietario

      Coordenadas en E6 y contrato sin documentar.

      Normalización estable

      Grados decimales, GeoJSON opcional y tiempos_status por parada.

      Superficie pública

      Endpoints que resuelven casos reales

      Desde «¿qué bus me viene?» hasta pintar la red entera en un mapa. Todo en JSON limpio, con coordenadas en grados decimales y direcciones postales completas.

      • GET /paradas Las 967 paradas con coordenadas, calle, número y código postal. público
      • GET /paradas/{codigo}/tiempos Buses en camino a una parada: línea, destino, minutos y vehículo. público
      • GET /lineas Líneas con su color oficial, horarios y recorrido por sentido. público
      • GET /health Estado de la API y la base de datos para Docker y balanceadores. público
      • POST /sync/* Sincronización de paradas, líneas y geocodificación bajo API key. api key

      Ver la referencia completa en la documentación →

      Integración

      Un endpoint. Cualquier cliente.

      • HTTP JSON con curl, apps o cualquier backend
      • Web fetch desde el navegador gracias a CORS
      • Mapas formato=geojson a Leaflet o MapLibre
      • Docker ghcr.io/686f6c61/api-tussam con base de datos precargada
      terminal

      Código abierto · uso no comercial

      Sevilla en movimiento.
      Tu app también.