fastapi-mariadb / main.py
Moibe's picture
Actions es action_call
09dd636
"""
Aplicación FastAPI - Endpoints
"""
import logging
from fastapi import FastAPI, HTTPException, Query
from fastapi.responses import JSONResponse
from models import RegistroRequest, RegistroResponse, CalificacionRequest, ActionRequest, ActionResponse, FunelCompraRequest, FunelCompraResponse
from funciones import crear_registro, obtener_registros, actualizar_calificacion, crear_o_actualizar_action, obtener_action, obtener_todas_acciones, crear_evento_funel, obtener_eventos_funel, obtener_todos_eventos_funel
from datetime import datetime
# Configurar logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
app = FastAPI(
title="API Imagen Log",
description="API para gestionar registro de usuarios",
version="1.0.0"
)
@app.get("/", tags=["General"])
async def root():
"""Endpoint raíz de bienvenida"""
logger.info("📍 Llamado a endpoint raíz /")
return {
"mensaje": "Bienvenido a la API de Imagen Log",
"version": "1.0.0",
"documentacion": "/docs"
}
@app.get("/health", tags=["General"])
async def health():
"""Verifica el estado de la API"""
logger.info("✅ Health check")
return {
"status": "healthy",
"timestamp": datetime.now().isoformat()
}
@app.post("/registrar", response_model=dict, tags=["Registros"])
async def registrar(datos: RegistroRequest):
"""
Crea un nuevo registro de usuario.
**Parámetros requeridos:**
- uid: UID de Firestore
- display_name: Nombre a mostrar del usuario
- pais: País del usuario
- correo: Email del usuario
**Parámetros opcionales:**
- fecha_registro: Fecha de registro (default: ahora)
- usos: Cantidad de usos (default: 0)
- prompt: Prompt utilizado
- prompt_type: Tipo de prompt
- prompt_eval: Evaluación del prompt procesado
- estilo: Estilo para la generación
- estilo_agregado: Estilo adicional
- calificacion: Calificación numérica
- proveedor: Proveedor del servicio
- seed: Seed para generación
**Respuesta:** Retorna los datos del registro creado con su ID único
"""
logger.info(f"📝 Nuevo registro - UID: {datos.uid}, Email: {datos.correo}, Prompt: {datos.prompt}, Tipo: {datos.prompt_type}, Eval: {datos.prompt_eval}, Estilo: {datos.estilo}, Estilo Agregado: {datos.estilo_agregado}, Calificación: {datos.calificacion}")
resultado = crear_registro(datos)
if resultado["success"]:
logger.info(f"✅ Registro creado exitosamente - ID: {resultado['data']['id']}, UID: {datos.uid}")
return {
"success": True,
"message": "Registro creado exitosamente",
"data": resultado["data"]
}
else:
logger.error(f"❌ Error al crear registro: {resultado['error']}")
raise HTTPException(
status_code=400,
detail=resultado["error"]
)
@app.get("/registros", tags=["Registros"])
async def obtener_todos_registros(
limit: int = Query(10, ge=1, le=100, description="Máximo registros a retornar"),
offset: int = Query(0, ge=0, description="Desplazamiento para paginación")
):
"""
Obtiene todos los registros con paginación.
**Parámetros:**
- limit: Cantidad máxima de registros (1-100, default 10)
- offset: Desplazamiento para paginación (default 0)
**Respuesta:** Lista de registros con información de paginación
"""
logger.info(f"📚 Obteniendo registros - Limit: {limit}, Offset: {offset}")
resultado = obtener_registros(limit, offset)
if resultado["success"]:
logger.info(f"✅ Se obtuvieron {len(resultado['data'])} registros (Total: {resultado['total']})")
return {
"success": True,
"data": resultado["data"],
"pagination": {
"total": resultado["total"],
"limit": resultado["limit"],
"offset": resultado["offset"],
"page": (resultado["offset"] // resultado["limit"]) + 1
}
}
else:
logger.error(f"❌ Error al obtener registros: {resultado['error']}")
raise HTTPException(
status_code=500,
detail=resultado["error"]
)
@app.post("/guardar-calificacion", tags=["Registros"])
async def guardar_calificacion(datos: CalificacionRequest):
"""
Actualiza la calificación de un registro existente.
**Parámetros requeridos:**
- id: ID del registro a calificar
- calificacion: Calificación numérica a asignar
**Respuesta:** Retorna los datos del registro actualizado
"""
logger.info(f"⭐ Guardando calificación - ID: {datos.id}, Calificación: {datos.calificacion}")
resultado = actualizar_calificacion(datos.id, datos.calificacion)
if resultado["success"]:
logger.info(f"✅ Calificación guardada exitosamente - ID: {datos.id}")
return {
"success": True,
"message": "Calificación guardada exitosamente",
"data": resultado["data"]
}
else:
logger.error(f"❌ Error al guardar calificación: {resultado['error']}")
raise HTTPException(
status_code=400,
detail=resultado["error"]
)
@app.post("/action", response_model=dict, tags=["Actions"])
async def crear_actualizar_action(datos: ActionRequest):
"""
Crea o actualiza un registro de usuario en la tabla action_call.
**Parámetros requeridos:**
- usuario: Nombre de usuario único
**Parámetros opcionales:**
- uid: UID de Firestore
- displayName: Nombre a mostrar
- email: Email del usuario
- action_call: Llamada a acción (boolean)
- country_header: País del header
- country_ip: País de la IP
- creditos: Créditos disponibles
- esta_hora: Usos esta hora
- explicit_counter: Contador explícito
- fecha_registro: Fecha de registro
- gaClient: Cliente de Google Analytics
- open_use: Uso abierto (boolean)
- ritmo: Ritmo de uso
- streak: Racha de usos
- ultima_generacion_hora: Última generación esta hora
- ultimo_uso: Último uso
- usos: Total de usos
**Respuesta:** Retorna los datos del action creado/actualizado
"""
logger.info(f"👤 Guardando action - Usuario: {datos.usuario}, UID: {datos.uid}, Email: {datos.email}")
logger.info(f"📊 Datos: Action_Call: {datos.action_call}, Trigger: {datos.trigger_action}, Country: {datos.country_header}, Créditos: {datos.creditos}, Usos: {datos.usos}, Ritmo: {datos.ritmo}, Streak: {datos.streak}")
resultado = crear_o_actualizar_action(datos)
if resultado["success"]:
logger.info(f"✅ Action guardado exitosamente - Usuario: {datos.usuario}, ID generado/actualizado")
return {
"success": True,
"message": "Action guardado exitosamente",
"data": resultado["data"]
}
else:
logger.error(f"❌ Error al guardar action: {resultado['error']}")
raise HTTPException(
status_code=400,
detail=resultado["error"]
)
@app.get("/action/{usuario}", response_model=dict, tags=["Actions"])
async def obtener_action_endpoint(usuario: str):
"""
Obtiene un registro de usuario específico de la tabla action_call.
**Parámetros:**
- usuario: Nombre de usuario a buscar
**Respuesta:** Retorna los datos del action
"""
logger.info(f"🔍 Buscando action - Usuario: {usuario}")
resultado = obtener_action(usuario)
if resultado["success"]:
logger.info(f"✅ Action encontrado - Usuario: {usuario}, Email: {resultado['data'].get('email')}, Usos: {resultado['data'].get('usos')}, Créditos: {resultado['data'].get('creditos')}")
return {
"success": True,
"data": resultado["data"]
}
else:
logger.error(f"❌ Action no encontrado: {resultado['error']}")
raise HTTPException(
status_code=404,
detail=resultado["error"]
)
@app.get("/actions", tags=["Actions"])
async def obtener_acciones(
limit: int = Query(10, ge=1, le=100, description="Máximo registros a retornar"),
offset: int = Query(0, ge=0, description="Desplazamiento para paginación")
):
"""
Obtiene todos los registros de la tabla action_call con paginación.
**Parámetros:**
- limit: Cantidad máxima de registros (1-100, default 10)
- offset: Desplazamiento para paginación (default 0)
**Respuesta:** Lista de acciones con información de paginación
"""
logger.info(f"📚 Obteniendo actions - Limit: {limit}, Offset: {offset}, Página: {(offset // limit) + 1}")
resultado = obtener_todas_acciones(limit, offset)
if resultado["success"]:
logger.info(f"✅ Se obtuvieron {len(resultado['data'])} actions (Total en BD: {resultado['total']})")
return {
"success": True,
"data": resultado["data"],
"pagination": {
"total": resultado["total"],
"limit": resultado["limit"],
"offset": resultado["offset"],
"page": (resultado["offset"] // resultado["limit"]) + 1
}
}
else:
logger.error(f"❌ Error al obtener actions: {resultado['error']}")
raise HTTPException(
status_code=500,
detail=resultado["error"]
)
@app.post("/funel-compra", response_model=dict, tags=["Funel Compra"])
async def registrar_funel_compra(datos: FunelCompraRequest):
"""
Registra un evento en el funel de compra.
Acciones típicas: inicio, visualizacion, intento_compra, compra_exitosa, abandono
"""
logger.info(f"📊 POST /funel-compra - Usuario: {datos.usuario}, Mail: {datos.mail}, Acción: {datos.accion}")
resultado = crear_evento_funel(datos)
if resultado["success"]:
logger.info(f"✅ Evento registrado: {resultado['data']}")
return {
"success": True,
"data": resultado["data"]
}
else:
logger.error(f"❌ Error al registrar evento: {resultado['error']}")
raise HTTPException(
status_code=400,
detail=resultado["error"]
)
@app.get("/funel-compra/{usuario}", response_model=dict, tags=["Funel Compra"])
async def obtener_funel_usuario(usuario: str):
"""
Obtiene todos los eventos del funel de compra para un usuario específico.
"""
logger.info(f"🔍 GET /funel-compra/{usuario}")
resultado = obtener_eventos_funel(usuario)
if resultado["success"]:
logger.info(f"✅ Se obtuvieron {resultado['total']} eventos para {usuario}")
return {
"success": True,
"data": resultado["data"],
"total": resultado["total"]
}
else:
logger.error(f"❌ Error al obtener eventos: {resultado['error']}")
raise HTTPException(
status_code=500,
detail=resultado["error"]
)
@app.get("/funel-compra", response_model=dict, tags=["Funel Compra"])
async def listar_funel_compra(limit: int = Query(10, ge=1, le=100), offset: int = Query(0, ge=0)):
"""
Obtiene todos los eventos del funel de compra con paginación.
"""
logger.info(f"📚 GET /funel-compra - Limit: {limit}, Offset: {offset}")
resultado = obtener_todos_eventos_funel(limit, offset)
if resultado["success"]:
logger.info(f"✅ Se obtuvieron {len(resultado['data'])} eventos (Total: {resultado['total']})")
return {
"success": True,
"data": resultado["data"],
"pagination": {
"total": resultado["total"],
"limit": limit,
"offset": offset,
"pages": (resultado["total"] + limit - 1) // limit
}
}
else:
logger.error(f"❌ Error al obtener eventos: {resultado['error']}")
raise HTTPException(
status_code=500,
detail=resultado["error"]
)
if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)