Data Engineer
14-06-2025
Completado
Python
Apache Airflow
dbt
SODA
BigQuery
Astronomer Cosmos
Google Cloud Platform
OpenSky API
SQL
README.md

✈️ Pipeline de Datos de Vuelos: Arquitectura ELT con Procesamiento por Lotes

Un pipeline de datos que ingesta información de vuelos actuales desde OpenSky Network API utilizando procesamiento por lotes, implementando patrones modernos de Data Engineering con Airflow, dbt, SODA y BigQuery.

🎯 Filosofía del Proyecto: Decisiones de Arquitectura que Importan

Por qué ELT en lugar de ETL tradicional?

Decisión estratégica: Utilizar las capacidades de BigQuery para almacenamiento y consultas, mientras mantenemos las transformaciones locales con dbt.

# ❌ Enfoque ETL tradicional (evitado)
# 1. Extract → Pandas transformations → Load
# Problemas: Memory bottlenecks, escalabilidad limitada

# ✅ Enfoque ELT implementado
# 1. Extract → Load raw → Transform locally with dbt → Load transformed
# Beneficios: Separación clara de responsabilidades, BigQuery para storage optimizado

El procesamiento se realiza localmente usando dbt, pero aprovechamos BigQuery como almacén final optimizado para consultas analíticas.

Procesamiento por Lotes vs Streaming: Control de Costos

Principio: Procesamiento batch para optimizar costos, obteniendo datos actuales de la API pero procesándolos de forma controlada.

Aunque la API proporciona datos del momento actual, la estrategia de lotes permite:

  • Control preciso de costos de BigQuery
  • Procesamiento eficiente de volúmenes pequeños (promedio 11 vuelos en Perú)
  • Evitar over-engineering para el contexto específico del país

Ventana Deslizante de 24 horas: Data Freshness Strategy

DELETE FROM `fly.current_flights_staging`
WHERE extracted_at < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 24 HOUR)

Rationale: Los datos de vuelos pierden relevancia rápidamente. Esta estrategia:

  • Mantiene el dataset ágil y relevante
  • Controla costos de almacenamiento
  • Optimiza performance de queries

🔍 Validaciones Inteligentes:

Validación Geoespacial Contextual

# SODA check con contexto aeronáutico real
- invalid_count(baro_altitude) = 0:
    valid_format: number_between -500 15000
    name: "Altitud barométrica realista (-500m a 15000m)"

Por qué -500m a 15000m?

  • -500m: Aeropuertos bajo el nivel del mar (Ej: región del Mar Muerto)
  • 15000m: Límite práctico para aviación comercial (FL450)
  • Esta validación no solo verifica el tipo de dato, sino también su coherencia operacional.

Freshness Crítico para Datos de Vuelo

- freshness(extracted_at) < 2h
- invalid_count(minutes_since_contact) = 0:
    valid_format: number_between 0 120

Insight: En aviación, datos > 2 horas pierden relevancia operacional. Esta validación asegura que mantenemos información útil para análisis.

🚀 Transformaciones que Agregan Valor de Negocio

Enriquecimiento Inteligente: Flight Phase Detection

El modelo dbt no solo limpia datos, sino que infiere fases de vuelo:

-- Lógica de inferencia de fase de vuelo (simplificada)
CASE 
  WHEN on_ground THEN 'GROUND'
  WHEN baro_altitude IS NULL THEN 'UNKNOWN_ALTITUDE'
  WHEN baro_altitude < 1000 AND velocity > 50 THEN 'TAXI_TAKEOFF_LANDING'
  WHEN vertical_rate > 500 THEN 'CLIMBING'
  WHEN vertical_rate < -500 THEN 'DESCENDING'
  WHEN baro_altitude > 10000 THEN 'CRUISE'
  ELSE 'IN_FLIGHT'
END as flight_phase

Valor para el análisis: Permite análisis operacional como:

  • Distribución de aeronaves por fase de vuelo
  • Identificación de patrones de tráfico en tiempo real
  • Alertas operacionales basadas en fase de vuelo

Composite Keys para Deduplicación Inteligente

- duplicate_count(flight_record_key) = 0

flight_record_key combina icao24 + extracted_at, permitiendo:

  • Múltiples registros del mismo vuelo en diferentes timestamps
  • Deduplicación dentro de la misma extracción
  • Trazabilidad temporal por aeronave

🏗️ Stack Tecnológico: Decisiones Justificadas

Astronomer Cosmos: dbt + Airflow Native Integration

from cosmos.config import ProfileConfig, ProjectConfig

DBT_CONFIG = ProfileConfig(
    profile_name='fly_data_load',
    target_name='dev',
    profiles_yml_filepath=Path('/usr/local/airflow/include/dbt/profiles.yml')
)

Por qué Cosmos?

  • Renderiza modelos dbt como tasks nativos de Airflow
  • Dependency management automático
  • Observabilidad unificada (logs, lineage, failures)

SODA para Validación Multi-Layer

Staged Validation Strategy:

  1. Source Layer: Validaciones de esquema y freshness
  2. Transform Layer: Validaciones de lógica de negocio post-dbt
# Source validation (technical)
- schema:
    fail:
      when required column missing: [icao24, callsign, ...]

# Transform validation (business logic)  
- invalid_count(flight_phase) = 0:
    valid_values: ['GROUND', 'CLIMBING', 'CRUISE', ...]

📊 Rendimiento del Pipeline

Prueba realizada: Pipeline procesando 8 vuelos completado en 1 minuto 29 segundos end-to-end.

Esto incluye:

  • Extracción desde OpenSky API
  • Carga a staging en BigQuery
  • Validaciones con SODA
  • Transformaciones con dbt
  • Carga final

Contexto peruano: El promedio de vuelos simultáneos en Perú es de ~11 vuelos, comparado con países como España donde solo Madrid puede tener +300 vuelos. Esta diferencia justifica la estrategia de procesamiento por lotes y optimización de costos.

🎨 Configuración Rápida

Variables de Entorno Críticas

# OpenSky API (token temporal de 30min)
OPENSKY_TOKEN="your_token"
OPENSKY_CLIENT_ID="client_id"
OPENSKY_CLIENT_SECRET="j2Zfp78hJYR7aYI..."

# GCP Service Account path
GCP_SERVICE_ACCOUNT_PATH="/usr/local/airflow/include/gcp/service-account.json"

Stack Dependencies

# Core pipeline
astronomer-cosmos[dbt-bigquery]==1.0.3
soda-core-bigquery==3.0.45
protobuf==3.20.0

# API integration
requests
python-dotenv

🔧 Testing y Debugging

Comando de Testing Individual

# Test task específico sin afectar el scheduler
airflow tasks test fly create_fly_dataset 2025-06-07

# Test conexión SODA
soda test-connection -d fly -c include/soda/configuration.yml

# Test transformación dbt
dbt run --select current_flights --profiles-dir /usr/local/airflow/include/dbt/

📊 Métricas del Pipeline

  • Latencia: ~1.5 minutos para 8 vuelos (end-to-end)
  • Precisión: Validaciones SODA en múltiples capas
  • Disponibilidad: Datos actuales (< 2 horas) garantizados
  • Contexto: Optimizado para volumen peruano (~11 vuelos promedio)

Este proyecto demuestra cómo implementar un pipeline de datos moderno que no solo mueve datos, sino que agrega valor analítico real. La combinación de patrones ELT, validación multi-capa y enriquecimiento inteligente crea una base sólida para análisis avanzados.

Contenido sincronizado automáticamente desde GitHub