La solución implementa una arquitectura de microservicios distribuida en Azure con los siguientes componentes:
Componente | Tecnología | Propósito |
---|---|---|
Data Pipeline | Azure Data Factory | ETL desde Kaggle → Azure SQL Database |
API Backend | FastAPI + Python | Endpoints REST con autenticación |
Caché Layer | Redis | Optimización de consultas dinámicas |
Authentication | Firebase Auth | JWT tokens y gestión de usuarios |
Monitoring | Application Insights | Telemetría y métricas de performance |
Deployment | Docker + Azure Container Apps | Containerización y orquestación |
{
"series_title": "The Shawshank Redemption",
"released_year": 1994,
"certificate": "A",
"runtime": "142 min",
"genre": "Drama",
"imdb_rating": 9.3,
"overview": "Two imprisoned...",
"meta_score": 80,
"director": "Frank Darabont",
"star1": "Tim Robbins",
"star2": "Morgan Freeman",
"star3": "Bob Gunton",
"star4": "William Sadler",
"no_of_votes": 2343110,
"gross": "16,000,000"
}
graph LR
A[Kaggle Dataset] --> B[Azure Blob Storage]
B --> C[Azure Data Factory]
C --> D[Data Transformation]
D --> E[Azure SQL Database]
E --> F[FastAPI Application]
from pydantic import BaseModel, Field
from typing import Optional, List
class MovieCatalog(BaseModel):
id: Optional[int] = None
poster_link: Optional[str] = None
series_title: str
released_year: int
certificate: Optional[str] = None
runtime: Optional[str] = None
genre: str
imdb_rating: float
overview: Optional[str] = None
meta_score: Optional[int] = None
director: str
stars: List[str] = Field(default_factory=list)
no_of_votes: Optional[int] = None
gross: Optional[str] = None
Método | Endpoint | Autenticación | Descripción |
---|---|---|---|
POST | /signup | ❌ | Registro de usuarios en Firebase |
POST | /login | ❌ | Autenticación y JWT |
GET | /catalog | ✅ | Catálogo con filtros dinámicos |
POST | /catalog | ✅ (Admin) | Creación de nuevas películas |
GET | /health | ❌ | Health check del servicio |
@validateadmin
async def create_new_movie(request: Request, movie_data: MovieCatalog):
new_movie = await create_movie(movie_data)
return new_movie
cache_key = "movies:catalog"
if genre:
cache_key += f":genre={genre.lower()}"
if year:
cache_key += f":year={year}"
if director:
cache_key += f":director={director.lower()}"
if min_rating:
cache_key += f":min_rating={min_rating}"
Ejemplos de claves generadas:
movies:catalog:genre=action:year=2020
movies:catalog:director=christopher nolan:min_rating=8.0
Escenario | Sin Caché | Con Caché | Mejora |
---|---|---|---|
Consulta general | ~800ms | ~15ms | 98.1% |
Filtro por género | ~650ms | ~12ms | 98.2% |
Filtro complejo | ~1200ms | ~18ms | 98.5% |
async def create_movie(movie_data: MovieCatalog):
await execute_query_json(insert_query, params)
keys_to_delete = ["movies:catalog"]
for genre in movie_data.genre.split(", "):
keys_to_delete.append(f"movies:catalog:genre={genre.lower()}")
keys_to_delete.extend([
f"movies:catalog:year={movie_data.released_year}",
f"movies:catalog:director={movie_data.director.lower()}"
])
for key in set(keys_to_delete):
delete_cache(redis_client, key)
def setup_simple_telemetry():
connection_string = os.getenv("APPLICATIONINSIGHTS_CONNECTION_STRING")
if connection_string:
configure_azure_monitor(connection_string=connection_string)
return True
return False
instrument_fastapi_app(app)
FROM python:3.12-slim
WORKDIR /app
RUN apt-get update && \
apt-get install -y curl gcc g++ && \
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - && \
ACCEPT_EULA=Y apt-get install -y msodbcsql17 unixodbc-dev && \
apt-get clean
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
graph TB
A[Azure Container Registry] --> B[Azure Container Apps]
B --> C[Azure SQL Database]
B --> D[Redis Cache]
B --> E[Application Insights]
F[Azure Front Door] --> B
G[Firebase Auth] --> B
Métrica | Resultado |
---|---|
Throughput | 2,500 req/sec |
Latencia Media | 45ms |
Cache Hit Rate | 94.2% |
Error Rate | 0.01% |
CPU Usage | 65% promedio |
/health
cada 30sFastAPI
, Pydantic
, SQLAlchemy
, Redis
Azure Data Factory
, Azure SQL Database
, Azure Container Apps
, Application Insights
Docker
, Firebase Auth
, Azure Key Vault
, GitHub Actions
GET /catalog?genre=Action&year=2020&min_rating=7.5
Authorization: Bearer <jwt_token>
POST /catalog
Authorization: Bearer <admin_jwt_token>
Content-Type: application/json
{
"series_title": "New Blockbuster",
"released_year": 2024,
"genre": "Action, Sci-Fi",
"imdb_rating": 8.2,
"director": "Christopher Nolan"
}
Al crear una nueva película de género "Action"
en 2024, el sistema automáticamente invalida:
movies:catalog
movies:catalog:genre=action
movies:catalog:year=2024
Este proyecto demuestra la implementación de una arquitectura de microservicios moderna y escalable, integrando:
La solución está preparada para escalar horizontalmente y manejar millones de requests diarios manteniendo alta disponibilidad y performance optimizada.