Saltar al contenido principal

Configuración del API Gateway

Configuración Principal

Variables de Entorno

# Configuración de servicios
API_GATEWAY_PORT=8000
API_GATEWAY_HOST=0.0.0.0

# URLs de microservicios
IMAGE_PROCESSOR_URL=http://localhost:8001
ML_EMBEDDINGS_URL=http://localhost:8002
ML_CLASSIFIER_URL=http://localhost:8003
OCR_EXTRACTOR_URL=http://localhost:8004

# Configuración JWT
JWT_SECRET_KEY=your-super-secret-jwt-key-here
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7

# Configuración de base de datos
DATABASE_URL=postgresql://user:password@localhost:5432/iris_db
REDIS_URL=redis://localhost:6379/0

# Configuración de seguridad
CORS_ORIGINS=["http://localhost:3000", "https://iris.example.com"]
ALLOWED_HOSTS=["localhost", "iris.example.com"]

Configuración de Servicios

# config/services.py
SERVICES_CONFIG = {
"image_processor": {
"url": "http://localhost:8001",
"timeout": 30.0,
"max_retries": 3,
"retry_delay": 1.0,
"health_endpoint": "/health",
"circuit_breaker": {
"failure_threshold": 5,
"recovery_timeout": 30,
"expected_exception": RequestException
}
},
"ml_embeddings": {
"url": "http://localhost:8002",
"timeout": 60.0,
"max_retries": 2,
"retry_delay": 2.0,
"health_endpoint": "/health",
"circuit_breaker": {
"failure_threshold": 3,
"recovery_timeout": 60,
"expected_exception": RequestException
}
},
"ml_classifier": {
"url": "http://localhost:8003",
"timeout": 45.0,
"max_retries": 3,
"retry_delay": 1.5,
"health_endpoint": "/health",
"circuit_breaker": {
"failure_threshold": 4,
"recovery_timeout": 45,
"expected_exception": RequestException
}
},
"ocr_extractor": {
"url": "http://localhost:8004",
"timeout": 90.0,
"max_retries": 2,
"retry_delay": 3.0,
"health_endpoint": "/health",
"circuit_breaker": {
"failure_threshold": 3,
"recovery_timeout": 90,
"expected_exception": RequestException
}
}
}

Configuración de Seguridad

CORS (Cross-Origin Resource Sharing)

# config/cors.py
CORS_CONFIG = {
"allow_origins": [
"http://localhost:3000",
"https://iris.example.com",
"https://admin.iris.example.com"
],
"allow_credentials": True,
"allow_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
"allow_headers": [
"Authorization",
"Content-Type",
"X-Request-ID",
"X-API-Key"
],
"expose_headers": [
"X-Request-ID",
"X-Processing-Time",
"X-Rate-Limit-Remaining"
],
"max_age": 86400 # 24 horas
}

Rate Limiting

# config/rate_limiting.py
RATE_LIMIT_CONFIG = {
"default": {
"limit": "100/hour",
"key_func": "ip_address"
},
"authenticated": {
"limit": "1000/hour",
"key_func": "user_id"
},
"admin": {
"limit": "10000/hour",
"key_func": "user_id"
},
"processing": {
"limit": "50/hour",
"key_func": "user_id"
}
}

Headers de Seguridad

# config/security.py
SECURITY_HEADERS = {
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
"X-XSS-Protection": "1; mode=block",
"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
"Content-Security-Policy": "default-src 'self'; img-src 'self' data:; script-src 'self'",
"Referrer-Policy": "strict-origin-when-cross-origin",
"Permissions-Policy": "geolocation=(), microphone=(), camera=()"
}

Configuración de Logging

Estructura de Logs

# config/logging.py
LOGGING_CONFIG = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"detailed": {
"format": "[{asctime}] {levelname} [{name}:{lineno}] {message}",
"style": "{",
"datefmt": "%Y-%m-%d %H:%M:%S"
},
"json": {
"()": "pythonjsonlogger.jsonlogger.JsonFormatter",
"format": "%(asctime)s %(name)s %(levelname)s %(message)s"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "INFO",
"formatter": "detailed",
"stream": "ext://sys.stdout"
},
"file": {
"class": "logging.handlers.RotatingFileHandler",
"level": "DEBUG",
"formatter": "json",
"filename": "/var/log/iris/api-gateway.log",
"maxBytes": 10485760, # 10MB
"backupCount": 5
},
"error_file": {
"class": "logging.handlers.RotatingFileHandler",
"level": "ERROR",
"formatter": "json",
"filename": "/var/log/iris/api-gateway-errors.log",
"maxBytes": 10485760,
"backupCount": 3
}
},
"loggers": {
"iris.api_gateway": {
"level": "DEBUG",
"handlers": ["console", "file", "error_file"],
"propagate": False
},
"uvicorn": {
"level": "INFO",
"handlers": ["console", "file"],
"propagate": False
}
},
"root": {
"level": "INFO",
"handlers": ["console"]
}
}

Configuración de Cache

Redis Configuration

# config/cache.py
CACHE_CONFIG = {
"redis": {
"host": "localhost",
"port": 6379,
"db": 0,
"password": None,
"socket_timeout": 5.0,
"socket_connect_timeout": 5.0,
"socket_keepalive": True,
"socket_keepalive_options": {},
"connection_pool_kwargs": {
"max_connections": 20,
"retry_on_timeout": True
}
},
"default_ttl": 3600, # 1 hora
"key_prefix": "iris:api_gateway:",
"serializer": "json",
"cache_strategies": {
"processing_results": {
"ttl": 86400, # 24 horas
"key_pattern": "result:{processing_id}"
},
"user_sessions": {
"ttl": 1800, # 30 minutos
"key_pattern": "session:{user_id}"
},
"service_health": {
"ttl": 60, # 1 minuto
"key_pattern": "health:{service_name}"
}
}
}

Configuración de Monitoreo

Métricas de Prometheus

# config/monitoring.py
MONITORING_CONFIG = {
"prometheus": {
"enabled": True,
"port": 9090,
"path": "/metrics",
"custom_metrics": {
"requests_total": {
"type": "counter",
"description": "Total number of requests",
"labels": ["method", "endpoint", "status_code"]
},
"request_duration_seconds": {
"type": "histogram",
"description": "Request duration in seconds",
"labels": ["method", "endpoint"],
"buckets": [0.1, 0.5, 1.0, 2.5, 5.0, 10.0]
},
"active_connections": {
"type": "gauge",
"description": "Number of active connections"
},
"processing_queue_size": {
"type": "gauge",
"description": "Number of items in processing queue"
}
}
},
"health_checks": {
"interval": 30, # segundos
"timeout": 10, # segundos
"services": [
"image_processor",
"ml_embeddings",
"ml_classifier",
"ocr_extractor"
]
}
}

Alertas

# config/alerts.yml
alerts:
- name: high_error_rate
condition: error_rate > 0.05
duration: 5m
severity: warning
message: "High error rate detected: {{ $value }}%"

- name: service_down
condition: service_health == 0
duration: 1m
severity: critical
message: "Service {{ $labels.service }} is down"

- name: high_latency
condition: avg_response_time > 10s
duration: 2m
severity: warning
message: "High response time: {{ $value }}s"

- name: queue_backlog
condition: processing_queue_size > 100
duration: 3m
severity: warning
message: "Processing queue backlog: {{ $value }} items"

Configuración de Docker

Dockerfile

FROM python:3.11-slim

WORKDIR /app

# Instalar dependencias del sistema
RUN apt-get update && apt-get install -y \
curl \
&& rm -rf /var/lib/apt/lists/*

# Copiar archivos de dependencias
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copiar código fuente
COPY . .

# Configurar usuario no-root
RUN useradd --create-home --shell /bin/bash iris
USER iris

# Exponer puerto
EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1

# Comando por defecto
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

Docker Compose

# docker-compose.yml
version: '3.8'

services:
api-gateway:
build: .
ports:
- "8000:8000"
environment:
- API_GATEWAY_PORT=8000
- JWT_SECRET_KEY=${JWT_SECRET_KEY}
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=redis://redis:6379/0
depends_on:
- redis
- postgres
volumes:
- ./logs:/var/log/iris
restart: unless-stopped

redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
restart: unless-stopped

postgres:
image: postgres:15-alpine
environment:
- POSTGRES_DB=iris_db
- POSTGRES_USER=iris
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped

volumes:
redis_data:
postgres_data:

Configuración de Desarrollo vs Producción

Desarrollo

# config/development.py
DEBUG = True
TESTING = False
LOG_LEVEL = "DEBUG"
RELOAD = True

# Servicios locales
SERVICE_URLS = {
"image_processor": "http://localhost:8001",
"ml_embeddings": "http://localhost:8002",
"ml_classifier": "http://localhost:8003",
"ocr_extractor": "http://localhost:8004"
}

# CORS permisivo para desarrollo
CORS_ORIGINS = ["*"]

Producción

# config/production.py
DEBUG = False
TESTING = False
LOG_LEVEL = "INFO"
RELOAD = False

# Servicios en cluster
SERVICE_URLS = {
"image_processor": "http://image-processor:8001",
"ml_embeddings": "http://ml-embeddings:8002",
"ml_classifier": "http://ml-classifier:8003",
"ocr_extractor": "http://ocr-extractor:8004"
}

# CORS restrictivo
CORS_ORIGINS = [
"https://iris.example.com",
"https://admin.iris.example.com"
]