Spaces:
Sleeping
Sleeping
| """ | |
| 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" | |
| ) | |
| 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" | |
| } | |
| async def health(): | |
| """Verifica el estado de la API""" | |
| logger.info("✅ Health check") | |
| return { | |
| "status": "healthy", | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| 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"] | |
| ) | |
| 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"] | |
| ) | |
| 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"] | |
| ) | |
| 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"] | |
| ) | |
| 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"] | |
| ) | |
| 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"] | |
| ) | |
| 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"] | |
| ) | |
| 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"] | |
| ) | |
| 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) | |