fastapi-mariadb / funciones.py
Moibe's picture
Actions es action_call
09dd636
"""Funciones de lógica de negocio"""
import logging
from datetime import datetime
from connection import get_connection
from models import RegistroRequest, RegistroResponse, ActionRequest
# Configurar logging
logger = logging.getLogger(__name__)
def crear_registro(datos: RegistroRequest) -> dict:
"""
Crea un nuevo registro en la base de datos.
Args:
datos: Objeto RegistroRequest con los datos del usuario
Returns:
dict: Información del registro creado o error
"""
conn = get_connection()
if not conn:
logger.error("❌ No se pudo conectar a la base de datos")
return {
"success": False,
"error": "No se pudo conectar a la base de datos"
}
try:
logger.info(f"🔗 Conexión establecida a BD")
# Preparar datos
uid = datos.uid
display_name = datos.display_name
pais = datos.pais
correo = datos.correo
fecha_registro = datos.fecha_registro or datetime.now()
usos = datos.usos or 0
prompt = datos.prompt
prompt_type = datos.prompt_type
prompt_eval = datos.prompt_eval
estilo = datos.estilo
estilo_agregado = datos.estilo_agregado
calificacion = datos.calificacion
proveedor = datos.proveedor
seed = datos.seed
logger.info(f"📊 Datos a insertar - UID: {uid}, Usuario: {display_name}, País: {pais}, Email: {correo}, Prompt: {prompt}, Tipo: {prompt_type}, Eval: {prompt_eval}, Estilo: {estilo}, Estilo Agregado: {estilo_agregado}, Calificación: {calificacion}, Proveedor: {proveedor}")
# Insertar en la BD
cursor = conn.cursor()
sql = """
INSERT INTO `creacion`
(uid, display_name, pais, correo, fecha_registro, usos, prompt, prompt_type, prompt_eval, estilo, estilo_agregado, calificacion, proveedor, seed)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
valores = (
uid, display_name, pais, correo, fecha_registro,
usos, prompt, prompt_type, prompt_eval, estilo, estilo_agregado, calificacion, proveedor, seed
)
cursor.execute(sql, valores)
conn.commit()
logger.info(f"✅ Registro insertado en BD")
# Obtener el ID del registro recién creado
nuevo_id = cursor.lastrowid
logger.info(f"🔑 ID generado: {nuevo_id}")
# Recuperar el registro creado
cursor.execute(
"""
SELECT id, uid, display_name, pais, correo, fecha_registro,
usos, prompt, prompt_type, prompt_eval, estilo, estilo_agregado, calificacion, proveedor, seed, created_at
FROM `creacion`
WHERE id = %s
""",
(nuevo_id,)
)
registro = cursor.fetchone()
cursor.close()
conn.close()
if registro:
logger.info(f"✅ Registro recuperado exitosamente - ID: {registro[0]}")
return {
"success": True,
"data": {
"id": registro[0],
"uid": registro[1],
"display_name": registro[2],
"pais": registro[3],
"correo": registro[4],
"fecha_registro": registro[5],
"usos": registro[6],
"prompt": registro[7],
"prompt_type": registro[8],
"prompt_eval": registro[9],
"estilo": registro[10],
"estilo_agregado": registro[11],
"calificacion": registro[12],
"proveedor": registro[13],
"seed": registro[14],
"created_at": registro[15]
}
}
else:
logger.error("❌ No se pudo recuperar el registro creado")
return {
"success": False,
"error": "No se pudo recuperar el registro creado"
}
except Exception as e:
logger.error(f"❌ Error al crear registro: {str(e)}")
return {
"success": False,
"error": f"Error al crear registro: {str(e)}"
}
def obtener_registros(limit: int = 10, offset: int = 0) -> dict:
"""
Obtiene registros de la base de datos con paginación.
Args:
limit: Cantidad máxima de registros
offset: Desplazamiento para paginación
Returns:
dict: Lista de registros o error
"""
conn = get_connection()
if not conn:
logger.error("❌ No se pudo conectar a la base de datos")
return {
"success": False,
"error": "No se pudo conectar a la base de datos"
}
try:
logger.info(f"🔗 Obteniendo registros - Limit: {limit}, Offset: {offset}")
cursor = conn.cursor()
# Obtener total de registros
cursor.execute("SELECT COUNT(*) FROM `creacion`")
total = cursor.fetchone()[0]
logger.info(f"📊 Total de registros en BD: {total}")
# Obtener registros con paginación
cursor.execute(
"""
SELECT id, uid, display_name, pais, correo, fecha_registro,
usos, prompt, prompt_type, prompt_eval, estilo, estilo_agregado, calificacion, proveedor, seed, created_at
FROM `creacion`
ORDER BY created_at DESC
LIMIT %s OFFSET %s
""",
(limit, offset)
)
registros = cursor.fetchall()
logger.info(f"✅ Se obtuvieron {len(registros)} registros de la BD")
cursor.close()
conn.close()
# Convertir resultados
datos = []
for reg in registros:
datos.append({
"id": reg[0],
"uid": reg[1],
"display_name": reg[2],
"pais": reg[3],
"correo": reg[4],
"fecha_registro": reg[5],
"usos": reg[6],
"prompt": reg[7],
"prompt_type": reg[8],
"prompt_eval": reg[9],
"estilo": reg[10],
"estilo_agregado": reg[11],
"calificacion": reg[12],
"proveedor": reg[13],
"seed": reg[14],
"created_at": reg[15]
})
logger.info(f"📈 Retornando {len(datos)} registros")
return {
"success": True,
"data": datos,
"total": total,
"limit": limit,
"offset": offset
}
except Exception as e:
logger.error(f"❌ Error al obtener registros: {str(e)}")
return {
"success": False,
"error": f"Error al obtener registros: {str(e)}"
}
def actualizar_calificacion(id_registro: int, calificacion: int) -> dict:
"""
Actualiza la calificación de un registro existente.
Args:
id_registro: ID del registro a actualizar
calificacion: Nueva calificación
Returns:
dict: Información del registro actualizado o error
"""
conn = get_connection()
if not conn:
logger.error("❌ No se pudo conectar a la base de datos")
return {
"success": False,
"error": "No se pudo conectar a la base de datos"
}
try:
logger.info(f"🔗 Actualizando calificación - ID: {id_registro}, Calificación: {calificacion}")
cursor = conn.cursor()
# Actualizar la calificación
cursor.execute(
"UPDATE `creacion` SET calificacion = %s WHERE id = %s",
(calificacion, id_registro)
)
conn.commit()
if cursor.rowcount == 0:
logger.error(f"❌ No se encontró registro con ID: {id_registro}")
cursor.close()
conn.close()
return {
"success": False,
"error": f"No se encontró registro con ID: {id_registro}"
}
logger.info(f"✅ Calificación actualizada para ID: {id_registro}")
# Recuperar el registro actualizado
cursor.execute(
"""
SELECT id, uid, display_name, pais, correo, fecha_registro,
usos, prompt, prompt_type, prompt_eval, estilo, estilo_agregado, calificacion, proveedor, seed, created_at
FROM `creacion`
WHERE id = %s
""",
(id_registro,)
)
registro = cursor.fetchone()
cursor.close()
conn.close()
if registro:
logger.info(f"✅ Registro recuperado - ID: {registro[0]}")
return {
"success": True,
"data": {
"id": registro[0],
"uid": registro[1],
"display_name": registro[2],
"pais": registro[3],
"correo": registro[4],
"fecha_registro": registro[5],
"usos": registro[6],
"prompt": registro[7],
"prompt_type": registro[8],
"prompt_eval": registro[9],
"estilo": registro[10],
"estilo_agregado": registro[11],
"calificacion": registro[12],
"proveedor": registro[13],
"seed": registro[14],
"created_at": registro[15]
}
}
else:
logger.error("❌ No se pudo recuperar el registro actualizado")
return {
"success": False,
"error": "No se pudo recuperar el registro actualizado"
}
except Exception as e:
logger.error(f"❌ Error al actualizar calificación: {str(e)}")
return {
"success": False,
"error": f"Error al actualizar calificación: {str(e)}"
}
def crear_o_actualizar_action(datos: ActionRequest) -> dict:
"""
Crea o actualiza un registro en la tabla action_call.
Args:
datos: Objeto ActionRequest con los datos del usuario
Returns:
dict: Información del action creado/actualizado o error
"""
conn = get_connection()
if not conn:
logger.error("❌ No se pudo conectar a la base de datos")
return {
"success": False,
"error": "No se pudo conectar a la base de datos"
}
try:
logger.info(f"🔗 Conexión establecida a BD")
cursor = conn.cursor()
# Preparar los valores
valores = (
datos.usuario, datos.uid, datos.displayName, datos.email,
datos.action_call, datos.trigger_action, datos.country_header, datos.country_ip,
datos.creditos, datos.esta_hora, datos.explicit_counter,
datos.fecha_registro, datos.gaClient, datos.open_use,
datos.ritmo, datos.streak, datos.ultima_generacion_hora,
datos.ultimo_uso, datos.usos
)
logger.info(f"📊 Datos a insertar/actualizar - Usuario: {datos.usuario}, Email: {datos.email}, Usos: {datos.usos}")
# Usar INSERT ... ON DUPLICATE KEY UPDATE para crear o actualizar
sql = """
INSERT INTO `action_call`
(usuario, uid, displayName, email, action_call, trigger_action, country_header, country_ip,
creditos, esta_hora, explicit_counter, fecha_registro, gaClient, open_use,
ritmo, streak, ultima_generacion_hora, ultimo_uso, usos)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
ON DUPLICATE KEY UPDATE
uid = VALUES(uid),
displayName = VALUES(displayName),
email = VALUES(email),
action_call = VALUES(action_call),
trigger_action = VALUES(trigger_action),
country_header = VALUES(country_header),
country_ip = VALUES(country_ip),
creditos = VALUES(creditos),
esta_hora = VALUES(esta_hora),
explicit_counter = VALUES(explicit_counter),
fecha_registro = VALUES(fecha_registro),
gaClient = VALUES(gaClient),
open_use = VALUES(open_use),
ritmo = VALUES(ritmo),
streak = VALUES(streak),
ultima_generacion_hora = VALUES(ultima_generacion_hora),
ultimo_uso = VALUES(ultimo_uso),
usos = VALUES(usos)
"""
cursor.execute(sql, valores)
conn.commit()
logger.info(f"✅ Action insertado/actualizado en BD")
# Recuperar el action
cursor.execute(
"SELECT * FROM `action_call` WHERE usuario = %s",
(datos.usuario,)
)
action = cursor.fetchone()
cursor.close()
conn.close()
if action:
logger.info(f"✅ Action recuperado - Usuario: {action[1]}")
return {
"success": True,
"data": {
"id": action[0],
"usuario": action[1],
"uid": action[2],
"displayName": action[3],
"email": action[4],
"action_call": action[5],
"trigger_action": action[6],
"country_header": action[7],
"country_ip": action[8],
"creditos": action[9],
"esta_hora": action[10],
"explicit_counter": action[11],
"fecha_registro": action[12],
"gaClient": action[13],
"open_use": action[14],
"ritmo": action[15],
"streak": action[16],
"ultima_generacion_hora": action[17],
"ultimo_uso": action[18],
"usos": action[19],
"created_at": action[20],
"updated_at": action[21]
}
}
else:
logger.error("❌ No se pudo recuperar el action")
return {
"success": False,
"error": "No se pudo recuperar el action"
}
except Exception as e:
logger.error(f"❌ Error al crear/actualizar action: {str(e)}")
return {
"success": False,
"error": f"Error al crear/actualizar action: {str(e)}"
}
def obtener_action(usuario: str) -> dict:
"""
Obtiene un action específico por usuario.
Args:
usuario: Nombre de usuario
Returns:
dict: Información del action o error
"""
conn = get_connection()
if not conn:
logger.error("❌ No se pudo conectar a la base de datos")
return {
"success": False,
"error": "No se pudo conectar a la base de datos"
}
try:
logger.info(f"🔍 Buscando action - Usuario: {usuario}")
cursor = conn.cursor()
cursor.execute(
"SELECT * FROM `action_call` WHERE usuario = %s",
(usuario,)
)
action = cursor.fetchone()
cursor.close()
conn.close()
if action:
logger.info(f"✅ Action encontrado - Usuario: {usuario}")
return {
"success": True,
"data": {
"id": action[0],
"usuario": action[1],
"uid": action[2],
"displayName": action[3],
"email": action[4],
"action_call": action[5],
"trigger_action": action[6],
"country_header": action[7],
"country_ip": action[8],
"creditos": action[9],
"esta_hora": action[10],
"explicit_counter": action[11],
"fecha_registro": action[12],
"gaClient": action[13],
"open_use": action[14],
"ritmo": action[15],
"streak": action[16],
"ultima_generacion_hora": action[17],
"ultimo_uso": action[18],
"usos": action[19],
"created_at": action[20],
"updated_at": action[21]
}
}
else:
logger.error(f"❌ No se encontró action - Usuario: {usuario}")
return {
"success": False,
"error": f"No se encontró action para el usuario: {usuario}"
}
except Exception as e:
logger.error(f"❌ Error al obtener action: {str(e)}")
return {
"success": False,
"error": f"Error al obtener action: {str(e)}"
}
def obtener_todas_acciones(limit: int = 10, offset: int = 0) -> dict:
"""
Obtiene todas las acciones con paginación.
Args:
limit: Cantidad máxima de registros
offset: Desplazamiento para paginación
Returns:
dict: Lista de acciones o error
"""
conn = get_connection()
if not conn:
logger.error("❌ No se pudo conectar a la base de datos")
return {
"success": False,
"error": "No se pudo conectar a la base de datos"
}
try:
logger.info(f"📚 Obteniendo todas las acciones - Limit: {limit}, Offset: {offset}")
cursor = conn.cursor()
# Obtener total
cursor.execute("SELECT COUNT(*) FROM `action_call`")
total = cursor.fetchone()[0]
logger.info(f"📊 Total de acciones: {total}")
# Obtener con paginación
cursor.execute(
"SELECT * FROM `action_call` ORDER BY updated_at DESC LIMIT %s OFFSET %s",
(limit, offset)
)
acciones = cursor.fetchall()
logger.info(f"✅ Se obtuvieron {len(acciones)} acciones")
cursor.close()
conn.close()
datos = []
for action in acciones:
datos.append({
"id": action[0],
"usuario": action[1],
"uid": action[2],
"displayName": action[3],
"email": action[4],
"action_call": action[5],
"trigger_action": action[6],
"country_header": action[7],
"country_ip": action[8],
"creditos": action[9],
"esta_hora": action[10],
"explicit_counter": action[11],
"fecha_registro": action[12],
"gaClient": action[13],
"open_use": action[14],
"ritmo": action[15],
"streak": action[16],
"ultima_generacion_hora": action[17],
"ultimo_uso": action[18],
"usos": action[19],
"created_at": action[20],
"updated_at": action[21]
})
return {
"success": True,
"data": datos,
"total": total,
"limit": limit,
"offset": offset
}
except Exception as e:
logger.error(f"❌ Error al obtener acciones: {str(e)}")
return {
"success": False,
"error": f"Error al obtener acciones: {str(e)}"
}
def crear_evento_funel(datos) -> dict:
"""
Crea un evento en el funel de compra.
Args:
datos: Object FunelCompraRequest con usuario, mail, accion
Returns:
dict: Evento creado o error
"""
conn = get_connection()
if not conn:
logger.error("❌ No se pudo conectar a la base de datos")
return {
"success": False,
"error": "No se pudo conectar a la base de datos"
}
try:
logger.info(f"📊 Registrando evento funel - Usuario: {datos.usuario}, Mail: {datos.mail}, Acción: {datos.accion}")
cursor = conn.cursor()
sql = """
INSERT INTO `funel_compra`
(usuario, mail, accion)
VALUES (%s, %s, %s)
"""
valores = (datos.usuario, datos.mail, datos.accion)
cursor.execute(sql, valores)
conn.commit()
logger.info(f"✅ Evento funel registrado en BD - Usuario: {datos.usuario}")
# Recuperar el evento creado
cursor.execute(
"SELECT * FROM `funel_compra` WHERE usuario = %s AND mail = %s AND accion = %s ORDER BY created_at DESC LIMIT 1",
(datos.usuario, datos.mail, datos.accion)
)
evento = cursor.fetchone()
cursor.close()
conn.close()
if evento:
logger.info(f"✅ Evento recuperado - ID: {evento[0]}")
return {
"success": True,
"data": {
"id": evento[0],
"usuario": evento[1],
"mail": evento[2],
"accion": evento[3],
"created_at": evento[4]
}
}
else:
logger.error("❌ No se pudo recuperar el evento creado")
return {
"success": False,
"error": "No se pudo recuperar el evento"
}
except Exception as e:
logger.error(f"❌ Error al crear evento funel: {str(e)}")
return {
"success": False,
"error": f"Error al crear evento: {str(e)}"
}
def obtener_eventos_funel(usuario: str) -> dict:
"""
Obtiene todos los eventos de funel para un usuario.
Args:
usuario: Nombre del usuario
Returns:
dict: Lista de eventos o error
"""
conn = get_connection()
if not conn:
logger.error("❌ No se pudo conectar a la base de datos")
return {
"success": False,
"error": "No se pudo conectar a la base de datos"
}
try:
logger.info(f"🔍 Buscando eventos funel - Usuario: {usuario}")
cursor = conn.cursor()
cursor.execute(
"SELECT * FROM `funel_compra` WHERE usuario = %s ORDER BY created_at DESC",
(usuario,)
)
eventos = cursor.fetchall()
cursor.close()
conn.close()
datos = []
for evento in eventos:
datos.append({
"id": evento[0],
"usuario": evento[1],
"mail": evento[2],
"accion": evento[3],
"created_at": evento[4]
})
logger.info(f"✅ Se obtuvieron {len(datos)} eventos para el usuario: {usuario}")
return {
"success": True,
"data": datos,
"total": len(datos)
}
except Exception as e:
logger.error(f"❌ Error al obtener eventos funel: {str(e)}")
return {
"success": False,
"error": f"Error al obtener eventos: {str(e)}"
}
def obtener_todos_eventos_funel(limit: int = 10, offset: int = 0) -> dict:
"""
Obtiene todos los eventos del funel con paginación.
Args:
limit: Cantidad máxima de registros
offset: Desplazamiento para paginación
Returns:
dict: Lista de eventos paginada o error
"""
conn = get_connection()
if not conn:
logger.error("❌ No se pudo conectar a la base de datos")
return {
"success": False,
"error": "No se pudo conectar a la base de datos"
}
try:
logger.info(f"📚 Obteniendo todos los eventos funel - Limit: {limit}, Offset: {offset}")
cursor = conn.cursor()
# Obtener total
cursor.execute("SELECT COUNT(*) FROM `funel_compra`")
total = cursor.fetchone()[0]
logger.info(f"📊 Total de eventos: {total}")
# Obtener con paginación
cursor.execute(
"SELECT * FROM `funel_compra` ORDER BY created_at DESC LIMIT %s OFFSET %s",
(limit, offset)
)
eventos = cursor.fetchall()
logger.info(f"✅ Se obtuvieron {len(eventos)} eventos")
cursor.close()
conn.close()
datos = []
for evento in eventos:
datos.append({
"id": evento[0],
"usuario": evento[1],
"mail": evento[2],
"accion": evento[3],
"created_at": evento[4]
})
return {
"success": True,
"data": datos,
"total": total,
"limit": limit,
"offset": offset
}
except Exception as e:
logger.error(f"❌ Error al obtener eventos funel: {str(e)}")
return {
"success": False,
"error": f"Error al obtener eventos: {str(e)}"
}