API FastAPI para gestión de comunicaciones de dispositivos GPS (Suntech y Queclink).
- ✅ FastAPI con async/await
- ✅ PostgreSQL con SQLAlchemy async
- ✅ Autenticación JWT
- ✅ Server-Sent Events (SSE) para streaming
- ✅ Integración Kafka/Redpanda para eventos en tiempo real
- ✅ Pool de conexiones optimizado
- ✅ Health checks
- ✅ CORS configurable
- ✅ Docker y Docker Compose
- ✅ CI/CD con GitHub Actions
- ✅ Métricas StatsD con aio-statsd para Telegraf/InfluxDB
- Python 3.11+
- PostgreSQL 12+
- Docker y Docker Compose (para deployment)
git clone https://github.com/tu-usuario/siscom-api.git
cd siscom-api
./scripts/setup_dev.shgit clone https://github.com/tu-usuario/siscom-api.git
cd siscom-apipython -m venv venv
source venv/bin/activate # En Windows: venv\Scripts\activate# Dependencias básicas
pip install -r requirements.txt
# O con Make
make installCrea un archivo .env en la raíz del proyecto:
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=tu_password
DB_DATABASE=siscom
DB_MIN_CONNECTIONS=10
DB_MAX_CONNECTIONS=20
DB_CONNECTION_TIMEOUT_SECS=30
DB_IDLE_TIMEOUT_SECS=300
JWT_SECRET_KEY=tu_secret_key_super_seguro
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=60
ALLOWED_ORIGINS=*
# Métricas StatsD (opcional)
STATSD_HOST=localhost
STATSD_PORT=8126
STATSD_PREFIX=siscom_api
# Kafka/Redpanda Configuration
KAFKA_BOOTSTRAP_SERVERS=localhost:9092
KAFKA_TOPIC=tracking/data
KAFKA_GROUP_ID=siscom-api-consumer
KAFKA_AUTO_OFFSET_RESET=latest
KAFKA_USERNAME=kafka_user
KAFKA_PASSWORD=kafka_passworduvicorn app.main:app --reload --host 0.0.0.0 --port 8000La API estará disponible en:
- API: http://localhost:8000
- Documentación: http://localhost:8000/api/docs
- ReDoc: http://localhost:8000/api/redoc
Este proyecto usa herramientas modernas de linting y formateo para mantener la calidad del código:
pip install ruff black mypyRuff es un linter de Python extremadamente rápido que reemplaza a flake8, isort, y más.
# Verificar código
ruff check app/
# Auto-corregir problemas
ruff check app/ --fix
# Verificar un archivo específico
ruff check app/main.pyBlack formatea automáticamente tu código siguiendo PEP 8.
# Verificar formato (sin modificar)
black --check app/
# Formatear código automáticamente
black app/
# Formatear un archivo específico
black app/main.pyMyPy verifica los tipos de datos en tu código Python.
# Verificar tipos
mypy app/ --ignore-missing-imports
# Verificar con más detalle
mypy app/ --strict# Opción 1: Manualmente
ruff check app/ && black --check app/ && mypy app/ --ignore-missing-imports
# Opción 2: Usando Makefile (recomendado)
make check-all # Verificar todo
make fix-all # Auto-corregir y formatearmake help # Ver todos los comandos disponibles
make install # Instalar dependencias
make lint # Ejecutar Ruff
make lint-fix # Auto-corregir con Ruff
make format # Formatear con Black
make format-check # Verificar formato
make type-check # Verificar tipos con MyPy
make test # Ejecutar tests
make dev # Ejecutar servidor en desarrollo
make docker-build # Construir imagen Docker
make docker-up # Levantar con Docker ComposeVSCode - Instala estas extensiones:
- Ruff (charliermarsh.ruff)
- Black Formatter (ms-python.black-formatter)
- Pylance para MyPy (ms-python.vscode-pylance)
Agrega a .vscode/settings.json:
{
"[python]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
},
"ruff.enable": true
}Para ejecutar linters automáticamente antes de cada commit:
pip install pre-commit
# Crear archivo .pre-commit-config.yaml
cat > .pre-commit-config.yaml << 'EOF'
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.6
hooks:
- id: ruff
args: [--fix]
- repo: https://github.com/psf/black
rev: 23.11.0
hooks:
- id: black
EOF
# Instalar hooks
pre-commit installLos linters se ejecutan automáticamente en cada push a través de GitHub Actions. Si el código no pasa los linters, el deploy se detiene automáticamente.
docker build -t siscom-api:latest .docker network create siscom-network
docker compose up -d| Documento | Descripción |
|---|---|
| 📘 API REST Guide | Documentación completa de todos los endpoints |
| 📮 Ejemplos de Uso | Ejemplos con cURL, Postman, JavaScript, Python, Svelte |
| 📊 Métricas | Sistema de métricas StatsD/Telegraf/InfluxDB |
| 📈 Queries Grafana | Dashboards y queries para visualizar métricas |
| 🚀 Deployment | Guía de despliegue en EC2 con GitHub Actions |
| 🔌 Kafka Integration | Integración con Kafka/Redpanda para streaming en tiempo real |
| 📖 Swagger UI | Documentación interactiva (servidor corriendo) |
GET /healthGET /api/v1/communications?device_ids=867564050638581&device_ids=DEVICE123
Authorization: Bearer {token}GET /api/v1/devices/{device_id}/communications
Authorization: Bearer {token}Endpoint de streaming que consume mensajes de Mosquitto y los transmite vía Server-Sent Events:
# Todos los dispositivos
GET /api/v1/stream
Accept: text/event-stream
# Filtrar por device_ids
GET /api/v1/stream?device_ids=0848086072,0848086073
Accept: text/event-streamEjemplo con curl:
curl -N "http://localhost:8000/api/v1/stream?device_ids=0848086072"Ver KAFKA_INTEGRATION.md para más detalles sobre la integración Kafka/Redpanda.
| Endpoint | Método | Auth | Descripción |
|---|---|---|---|
GET /health |
GET | ❌ No | Health check del servicio |
GET /api/v1/communications |
GET | ✅ JWT | Histórico de múltiples dispositivos |
GET /api/v1/devices/{device_id}/communications |
GET | ✅ JWT | Histórico de un solo dispositivo |
GET /api/v1/stream |
GET | ❌ No | Stream SSE con mensajes Kafka/Redpanda |
GET /api/v1/stream?device_ids={ids} |
GET | ❌ No | Stream SSE filtrado por dispositivos |
siscom-api/
├── app/
│ ├── api/
│ │ └── routes/ # Endpoints de la API
│ ├── core/
│ │ ├── config.py # Configuración
│ │ ├── database.py # Conexión a DB
│ │ ├── middleware.py # Middleware de métricas
│ │ └── security.py # JWT y autenticación
│ ├── models/ # Modelos SQLAlchemy
│ ├── schemas/ # Schemas Pydantic
│ ├── services/
│ │ ├── kafka_client.py # Cliente Kafka/Redpanda
│ │ ├── repository.py # Repositorio de datos
│ │ └── sse.py # Lógica SSE (opcional)
│ ├── utils/
│ │ ├── exceptions.py # Excepciones personalizadas
│ │ ├── logger.py # Logging
│ │ └── metrics.py # Cliente aio-statsd
│ └── main.py # Aplicación principal
├── docs/ # 📚 Documentación
│ ├── API_REST_GUIDE.md # 📘 Guía completa del API
│ ├── POSTMAN_EXAMPLES.md # 📮 Ejemplos de uso
│ ├── METRICS.md # 📊 Sistema de métricas
│ ├── GRAFANA_QUERIES.md # 📈 Queries y dashboards
│ ├── DEPLOYMENT.md # 🚀 Guía de deployment
│ └── KAFKA_INTEGRATION.md # 🔌 Integración Kafka/Redpanda
├── test/ # Tests unitarios e integración
├── scripts/ # Scripts de utilidad
├── .github/
│ └── workflows/
│ └── deploy.yml # CI/CD pipeline
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── README.md
- Autenticación JWT para endpoints protegidos
- Contenedor corre con usuario no privilegiado
- Secrets manejados con variables de entorno
- Pool de conexiones con límites configurados
- Health checks implementados
Ver documentación completa de despliegue en DEPLOYMENT.md:
- Instrucciones detalladas de despliegue en EC2 con GitHub Actions
- Configuración de variables de entorno en GitHub (incluye STATSD_*)
- Health checks y verificación de deployment
Tablas separadas para cada fabricante, compartiendo la misma estructura base:
device_id: Identificador del dispositivolatitude,longitude: Coordenadas GPSspeed,course: Velocidad y direccióngps_datetime: Timestamp del GPSmain_battery_voltage,backup_battery_voltage: Voltajesodometer,trip_distance,total_distance: Distancias- Y más campos...
El proyecto incluye una suite completa de tests unitarios y de integración con más de 50 tests y ~95% de cobertura.
# Opción 1: Script interactivo (recomendado)
./run_unit_tests.sh
# Opción 2: pytest directo
pytest # Todos los tests
pytest -v # Verbose
pytest --cov=app # Con cobertura
# Opción 3: Make commands
make test # Todos los tests
make test-unit # Solo unitarios
make test-integration # Solo integración
make test-cov # Con cobertura HTML
make test-auth # Solo autenticación
make test-fast # Excluir tests lentospytest -m unit # Tests unitarios (rápidos)
pytest -m integration # Tests de integración
pytest -m auth # Tests de autenticación
pytest -m database # Tests de base de datos
pytest -m "not slow" # Excluir tests lentos# Un archivo específico
pytest test/test_health.py
# Una clase específica
pytest test/test_security.py::TestJWTToken
# Un test específico
pytest test/test_health.py::TestHealthEndpoint::test_health_check_returns_200# Generar reporte de cobertura
pytest --cov=app --cov-report=html
# Ver reporte en navegador
xdg-open htmlcov/index.html # Linux
open htmlcov/index.html # macOStest/test_health.py- Tests del health check endpointtest/test_security.py- Tests de JWT y autenticacióntest/test_communications.py- Tests de endpoints de comunicacionestest/test_repository.py- Tests del servicio de repositoriotest/test_schemas.py- Tests de schemas Pydantictest/test_models.py- Tests de modelos SQLAlchemytest/test_config.py- Tests de configuracióntest/conftest.py- Fixtures compartidas
Ver documentación completa en test/README.md
La API envía métricas automáticamente a Telegraf usando el protocolo StatsD con aio-statsd (librería asíncrona optimizada para FastAPI).
-
Peticiones por minuto (
siscom_api.requests)- Contador de todas las peticiones HTTP
- Tag:
app=siscom-api
-
Latencia del endpoint /stream (
siscom_api.latency.stream)- Tiempo de respuesta en milisegundos
- Genera percentiles (p50, p90, p95, p99) y media
- Tag:
app=siscom-api
-
Conexiones SSE activas (
siscom_api.sse.active_connections)- Número actual de conexiones Server-Sent Events
- Tag:
app=siscom-api
Agrega estas variables a tu .env:
STATSD_HOST=localhost
STATSD_PORT=8126
STATSD_PREFIX=siscom_api-
Copia el archivo de configuración de ejemplo:
cp telegraf-statsd.conf /path/to/telegraf/telegraf.conf
-
Configura las variables de InfluxDB en Telegraf
-
Inicia Telegraf:
docker run -d --name telegraf \ -p 8125:8125/udp \ -v $(pwd)/telegraf-statsd.conf:/etc/telegraf/telegraf.conf:ro \ telegraf:latest -
Prueba las métricas:
python test_metrics.py
- ✅ Asíncrono: Completamente integrado con FastAPI y asyncio
- ✅ Sin bloqueo: No afecta el rendimiento del event loop
- ✅ Automático: Conexión y desconexión manejadas en el lifecycle de la app
- ✅ Tags nativos: Formato InfluxDB optimizado
- ✅ Robusto: Maneja errores de red sin impactar la aplicación
Ver documentación completa en METRICS.md
- ✅ Pool de conexiones optimizado
- ✅ Health check endpoint
- ✅ CORS configurado
- ✅ Docker multi-stage build
- ✅ GitHub Actions CI/CD
- ✅ Variables de entorno bien estructuradas
- ✅ Suite completa de tests con pytest (50+ tests, ~95% coverage)
- ✅ Métricas StatsD con aio-statsd para Telegraf/InfluxDB
- ✅ Integración MQTT con Mosquitto para streaming en tiempo real
⚠️ Logging estructurado con Loguru (archivos utils vacíos)⚠️ Manejo de excepciones personalizado⚠️ Rate limiting⚠️ Caché (Redis) para consultas frecuentes⚠️ Documentación de esquemas con Pydantic⚠️ Migraciones de base de datos (Alembic)⚠️ Índices de base de datos optimizados
- Fork el proyecto
- Crea una rama feature (
git checkout -b feature/AmazingFeature) - Commit tus cambios (
git commit -m 'Add some AmazingFeature') - Push a la rama (
git push origin feature/AmazingFeature) - Abre un Pull Request
[Tu licencia aquí]
[Tu nombre/equipo aquí]
[Tu contacto aquí]