Moibe commited on
Commit
421e233
·
1 Parent(s): 114b23a

Logs y estadísticas

Browse files
agregaEstadisticas.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import conexion_firebase
2
+
3
+ servicio = "app"
4
+
5
+ conexion_firebase.incrementar_campo_numerico('estadisticas', 'imagenes', 'endpoint-' + servicio, amount=1)
6
+ conexion_firebase.incrementar_campo_numerico('estadisticas', 'imagenes', servicio, amount=1)
app.py CHANGED
@@ -1,7 +1,7 @@
1
  import herramientas
2
  from io import BytesIO
3
  import funciones, globales
4
- from fastapi import FastAPI, Form
5
  from fastapi import FastAPI, File, UploadFile
6
  from fastapi.responses import StreamingResponse, FileResponse, JSONResponse
7
 
@@ -30,7 +30,10 @@ async def echo_image(image: UploadFile = File(...)):
30
  return StreamingResponse(BytesIO(contents), media_type=image.content_type)
31
 
32
  @app.post("/genera-imagen/")
33
- async def genera_imagen(platillo: str = Form(...)):
 
 
 
34
 
35
  seconds_available = herramientas.obtenSegundosDisponibles()
36
  print(herramientas.imprimeTimeNow())
@@ -46,7 +49,7 @@ async def genera_imagen(platillo: str = Form(...)):
46
 
47
  print("Usando Inference ✨.")
48
  resultado = funciones.genera_platillo_inference(platillo)
49
- print("El resultado de inference es: ", resultado)
50
  if type(resultado) is str:
51
  return resultado
52
  else:
 
1
  import herramientas
2
  from io import BytesIO
3
  import funciones, globales
4
+ from fastapi import FastAPI, Form, Request
5
  from fastapi import FastAPI, File, UploadFile
6
  from fastapi.responses import StreamingResponse, FileResponse, JSONResponse
7
 
 
30
  return StreamingResponse(BytesIO(contents), media_type=image.content_type)
31
 
32
  @app.post("/genera-imagen/")
33
+ async def genera_imagen(request: Request, platillo: str = Form(...)):
34
+
35
+ print("Client host:", request.client.host)
36
+ herramientas.despliegaInfoCliente(request)
37
 
38
  seconds_available = herramientas.obtenSegundosDisponibles()
39
  print(herramientas.imprimeTimeNow())
 
49
 
50
  print("Usando Inference ✨.")
51
  resultado = funciones.genera_platillo_inference(platillo)
52
+ #print("El resultado de inference es: ", resultado)
53
  if type(resultado) is str:
54
  return resultado
55
  else:
archivos/last_timestamp.txt DELETED
@@ -1 +0,0 @@
1
- 1747156891
 
 
archivos/modelo_actual.txt DELETED
@@ -1 +0,0 @@
1
- black-forest-labs/FLUX.1-dev
 
 
archivos/modelo_principal.txt DELETED
@@ -1 +0,0 @@
1
- black-forest-labs/FLUX.1-dev
 
 
archivos/seconds_available.txt DELETED
@@ -1 +0,0 @@
1
- 294
 
 
autenticacion.py CHANGED
@@ -18,12 +18,15 @@ def defineAmbiente():
18
  print("Entorno Local...")
19
  import bridges
20
  llave = bridges.llave #Acceso a HF
21
- servidor = "sosa" #o "sosa" Sosa Jhons, depende de donde deduciras el tiempo de gpu cuando pruebas en local.
22
  hora_renovacion = 17
 
23
  else:
24
  print("Entorno remoto listo...")
25
  llave = os.getenv("llave") #Acceso a HF
26
  servidor = os.getenv("servidor")
27
  print("El servidor remoto es: ", servidor)
28
  hora_renovacion = os.getenv("hora_renovacion")
29
- return llave, servidor, hora_renovacion
 
 
 
18
  print("Entorno Local...")
19
  import bridges
20
  llave = bridges.llave #Acceso a HF
21
+ servidor = "sosa" #o "sosa", depende de donde deduciras el tiempo de gpu cuando pruebas en local.
22
  hora_renovacion = 17
23
+ servicio = "desarrollo"
24
  else:
25
  print("Entorno remoto listo...")
26
  llave = os.getenv("llave") #Acceso a HF
27
  servidor = os.getenv("servidor")
28
  print("El servidor remoto es: ", servidor)
29
  hora_renovacion = os.getenv("hora_renovacion")
30
+ servicio = os.getenv("servicio")
31
+
32
+ return llave, servidor, hora_renovacion, servicio
buscaLog.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import conexion_firebase
2
+
3
+ #conexion_firebase.buscar_log_por_prompt("Ensalada de pollo")
4
+
5
+ # --- Ejemplo de cómo usar la función (sin cambios aquí) ---
6
+ if __name__ == "__main__":
7
+ # Asegúrate de tener al menos un log con el prompt "Ensalada de pollo"
8
+ documentos_encontrados = conexion_firebase.buscar_log_por_prompt("Ensalada de pollo")
9
+
10
+ if documentos_encontrados:
11
+ print(f"✔️ Se encontraron {len(documentos_encontrados)} documentos:")
12
+ for log in documentos_encontrados:
13
+ print(f" ID del Documento: {log['id']}")
14
+ print(f" Datos: {log}")
15
+ else:
16
+ print("❌ Búsqueda finalizada sin resultados.")
17
+
18
+ print("\n--- Probando una búsqueda que no debería encontrar nada ---")
19
+ conexion_firebase.buscar_log_por_prompt("Prompt que no existe")
conexion_firebase.py CHANGED
@@ -1,9 +1,8 @@
1
  import firebase_admin
2
- from firebase_admin import firestore
3
  from firebase_admin import auth
 
4
  from firebase_admin import credentials
5
- import time
6
-
7
 
8
  firebase_cred = credentials.Certificate('config.json')
9
  firebase_admin.initialize_app(firebase_cred)
@@ -41,4 +40,111 @@ def creaDato(coleccion, dato, info, contenido):
41
 
42
  doc_ref.set({
43
  info: contenido,
44
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import firebase_admin
2
+ from datetime import datetime
3
  from firebase_admin import auth
4
+ from firebase_admin import firestore
5
  from firebase_admin import credentials
 
 
6
 
7
  firebase_cred = credentials.Certificate('config.json')
8
  firebase_admin.initialize_app(firebase_cred)
 
40
 
41
  doc_ref.set({
42
  info: contenido,
43
+ })
44
+
45
+ def registraLog(servidor_val, prompt_val, modelo_val, seed_val):
46
+ """
47
+ Agrega un nuevo documento a la colección 'logs'.
48
+ El ID del documento es la fecha y hora actual en formato string.
49
+ Los campos del documento son 'servidor', 'prompt', 'modelo' y 'seed'.
50
+
51
+ Args:
52
+ servidor_val (str): El nombre o ID del servidor.
53
+ prompt_val (str): El valor del campo 'prompt'.
54
+ modelo_val (str): El valor del campo 'modelo'.
55
+ seed_val (int): El valor del campo 'seed'.
56
+ """
57
+ try:
58
+ # 1. Generar el ID del documento (fecha y hora actual formateada)
59
+ # Es importante usar una zona horaria si tus logs vienen de diferentes lugares
60
+ # o si quieres que el timestamp refleje una hora local específica.
61
+ # Por defecto, datetime.now() usa la hora local de tu sistema.
62
+ # Si prefieres UTC (recomendado para consistencia global), puedes usar datetime.now(pytz.utc).
63
+
64
+ # Obtenemos la hora actual del sistema
65
+ now = datetime.now()
66
+ # Formateamos la hora para que sea el ID del documento
67
+ document_id_fecha_hora = now.strftime("%Y-%m-%d %H:%M:%S")
68
+
69
+ nombre_final = servidor_val + " - " + document_id_fecha_hora
70
+
71
+ # 2. Definir la referencia al documento específico con el ID de fecha y hora
72
+ doc_ref = db.collection('logs').document(nombre_final)
73
+
74
+ # 3. Definir los datos del log
75
+ datos_log = {
76
+ 'servidor': servidor_val,
77
+ 'prompt': prompt_val,
78
+ 'modelo': modelo_val,
79
+ 'seed': seed_val,
80
+ # Opcional: También puedes guardar el timestamp como un campo Timestamp
81
+ # esto facilita consultas de rango si la fecha/hora del ID no es perfecta
82
+ # o si necesitas ordenar por milisegundos.
83
+ 'timestamp_creacion': firestore.SERVER_TIMESTAMP
84
+ }
85
+
86
+ # 4. Guardar los datos en el documento
87
+ # Usamos .set(). Si un log ya existe para ese EXACTO segundo, se sobrescribirá.
88
+ # Si esto es una preocupación (dos logs en el mismo segundo), podríamos añadir
89
+ # milisegundos al ID o usar un ID automático y un campo de timestamp.
90
+ doc_ref.set(datos_log)
91
+
92
+ print(f"✔️ Log agregado exitosamente en 'logs/{document_id_fecha_hora}'.")
93
+ print(f" Datos: Servidor='{servidor_val}', Prompt='{prompt_val}'...")
94
+
95
+ except Exception as e:
96
+ print(f"❌ Error al agregar log a Firestore: {e}")
97
+ # Considera registrar el error o manejarlo de forma más robusta.
98
+
99
+
100
+ def buscar_log_por_prompt(valor_prompt):
101
+ """
102
+ Busca documentos en la colección 'logs' donde el campo 'prompt' coincide
103
+ con el valor_prompt especificado.
104
+
105
+ Args:
106
+ valor_prompt (str): El valor exacto del prompt a buscar.
107
+
108
+ Returns:
109
+ list: Una lista de diccionarios, donde cada diccionario representa un documento
110
+ que coincide con la búsqueda. Incluye el ID del documento.
111
+ """
112
+ print(f"\n--- Buscando logs con prompt: '{valor_prompt}' ---")
113
+
114
+ # --- CAMBIO AQUÍ: Usando firestore.FieldFilter en lugar de .where() directamente ---
115
+ query_results = db.collection('logs').where(
116
+ filter=firestore.FieldFilter('prompt', '==', valor_prompt)
117
+ ).get()
118
+
119
+ logs_encontrados = []
120
+ if not query_results:
121
+ print(f"No se encontraron documentos con el prompt '{valor_prompt}'.")
122
+ return []
123
+
124
+ for doc in query_results:
125
+ log_data = doc.to_dict()
126
+ log_data['id'] = doc.id # Añade el ID del documento al diccionario de datos
127
+ logs_encontrados.append(log_data)
128
+
129
+ return logs_encontrados
130
+
131
+ def incrementar_campo_numerico(collection_name, document_id, field_name, amount=1):
132
+ """
133
+ Incrementa un campo numérico en un documento de Firestore de forma atómica.
134
+
135
+ Args:
136
+ collection_name (str): El nombre de la colección.
137
+ document_id (str): El ID del documento.
138
+ field_name (str): El nombre del campo numérico a incrementar.
139
+ amount (int/float): La cantidad por la cual incrementar (puede ser negativo para decrementar).
140
+ """
141
+ doc_ref = db.collection(collection_name).document(document_id)
142
+
143
+ try:
144
+ # Usa firestore.Increment(cantidad) para un incremento atómico
145
+ doc_ref.update({
146
+ field_name: firestore.Increment(amount)
147
+ })
148
+ print(f"✔️ Campo '{field_name}' en el documento '{document_id}' incrementado en {amount}.")
149
+ except Exception as e:
150
+ print(f"❌ Error al incrementar campo '{field_name}' en '{document_id}': {e}")
creaLog.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ import conexion_firebase
2
+
3
+
4
+ conexion_firebase.registraLog("sosa", "Ensalada de pollo", "Flux-Dev", 42)
5
+
funciones.py CHANGED
@@ -8,15 +8,14 @@ import conexion_firebase
8
  from fastapi import HTTPException, status
9
  from huggingface_hub import InferenceClient
10
 
11
-
12
  servidor = globales.servidor
 
13
 
14
  def genera_platillo_gpu(platillo):
15
 
16
  prompt = globales.previo + platillo
17
 
18
  try:
19
-
20
  dict_espacios = conexion_firebase.obtenDato('nowme', servidor, 'espacios')
21
 
22
  espacios_habilitados = [
@@ -28,15 +27,13 @@ def genera_platillo_gpu(platillo):
28
 
29
  espacio_aleatorio_elegido = random.choice(espacios_habilitados)
30
  configuracion_espacio = dict_espacios[espacio_aleatorio_elegido]
31
- print(f"La configuración completa para '{espacio_aleatorio_elegido}' es: {configuracion_espacio}")
32
-
33
  client = gradio_client.Client(configuracion_espacio['ruta'], hf_token=globales.llave)
34
 
35
  result = client.predict(
36
  #**kwargs,
37
  prompt=prompt,
38
  #negative_prompt="live animals",
39
- seed=43,
40
  randomize_seed=False,
41
  width=786,
42
  height=568,
@@ -49,12 +46,15 @@ def genera_platillo_gpu(platillo):
49
  herramientas.restaSegundosGPU(globales.work_cost)
50
 
51
  print("Platillo generado:", platillo)
 
 
 
 
 
52
  return result[0]
53
 
54
  except Exception as e:
55
- print("Excepción: ", e)
56
- # Opción para regresar imagen genérica. (ya no porque se envía desde backend.)
57
- # return "default.png"
58
  raise HTTPException(
59
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
60
  detail=e
@@ -62,8 +62,7 @@ def genera_platillo_gpu(platillo):
62
 
63
  def genera_platillo_inference(platillo):
64
 
65
- dict_modelos = conexion_firebase.obtenDato('nowme', servidor, 'modelos')
66
-
67
  modelos_habilitados = [
68
  nombre for nombre, config in dict_modelos.items()
69
  if config.get("habilitado", False) # Usamos .get() para evitar KeyError si 'habilitado' no existe
@@ -72,9 +71,7 @@ def genera_platillo_inference(platillo):
72
  print(f"Modelos habilitados: {modelos_habilitados}")
73
 
74
  modelo_aleatorio_elegido = random.choice(modelos_habilitados)
75
- configuracion_modelo = dict_modelos[modelo_aleatorio_elegido]
76
- print(f"La configuración completa para '{modelo_aleatorio_elegido}' es: {configuracion_modelo}")
77
-
78
 
79
  creditos_restantes_inference = conexion_firebase.obtenDato('nowme', servidor, 'inferencias')
80
 
@@ -121,4 +118,8 @@ def genera_platillo_inference(platillo):
121
  image.save(img_io, "PNG")
122
  img_io.seek(0)
123
  print("Platillo generado:", platillo)
 
 
 
 
124
  return img_io
 
8
  from fastapi import HTTPException, status
9
  from huggingface_hub import InferenceClient
10
 
 
11
  servidor = globales.servidor
12
+ servicio = globales.servicio
13
 
14
  def genera_platillo_gpu(platillo):
15
 
16
  prompt = globales.previo + platillo
17
 
18
  try:
 
19
  dict_espacios = conexion_firebase.obtenDato('nowme', servidor, 'espacios')
20
 
21
  espacios_habilitados = [
 
27
 
28
  espacio_aleatorio_elegido = random.choice(espacios_habilitados)
29
  configuracion_espacio = dict_espacios[espacio_aleatorio_elegido]
 
 
30
  client = gradio_client.Client(configuracion_espacio['ruta'], hf_token=globales.llave)
31
 
32
  result = client.predict(
33
  #**kwargs,
34
  prompt=prompt,
35
  #negative_prompt="live animals",
36
+ seed=42,
37
  randomize_seed=False,
38
  width=786,
39
  height=568,
 
46
  herramientas.restaSegundosGPU(globales.work_cost)
47
 
48
  print("Platillo generado:", platillo)
49
+ conexion_firebase.registraLog(servidor, platillo, espacio_aleatorio_elegido, 42)
50
+ conexion_firebase.incrementar_campo_numerico('estadisticas', 'imagenes', 'imagenes_totales', amount=1)
51
+ conexion_firebase.incrementar_campo_numerico('estadisticas', 'imagenes', 'endpoint-' + servicio, amount=1)
52
+ conexion_firebase.incrementar_campo_numerico('estadisticas', 'imagenes', 'imagenes_gpu', amount=1)
53
+
54
  return result[0]
55
 
56
  except Exception as e:
57
+ print("Excepción: ", e)
 
 
58
  raise HTTPException(
59
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
60
  detail=e
 
62
 
63
  def genera_platillo_inference(platillo):
64
 
65
+ dict_modelos = conexion_firebase.obtenDato('nowme', servidor, 'modelos')
 
66
  modelos_habilitados = [
67
  nombre for nombre, config in dict_modelos.items()
68
  if config.get("habilitado", False) # Usamos .get() para evitar KeyError si 'habilitado' no existe
 
71
  print(f"Modelos habilitados: {modelos_habilitados}")
72
 
73
  modelo_aleatorio_elegido = random.choice(modelos_habilitados)
74
+ configuracion_modelo = dict_modelos[modelo_aleatorio_elegido]
 
 
75
 
76
  creditos_restantes_inference = conexion_firebase.obtenDato('nowme', servidor, 'inferencias')
77
 
 
118
  image.save(img_io, "PNG")
119
  img_io.seek(0)
120
  print("Platillo generado:", platillo)
121
+ conexion_firebase.registraLog(servidor, platillo, modelo_aleatorio_elegido, 42)
122
+ conexion_firebase.incrementar_campo_numerico('estadisticas', 'imagenes', 'imagenes_totales', amount=1)
123
+ conexion_firebase.incrementar_campo_numerico('estadisticas', 'imagenes', 'endpoint-' + servicio, amount=1)
124
+ conexion_firebase.incrementar_campo_numerico('estadisticas', 'imagenes', 'imagenes_inference', amount=1)
125
  return img_io
globales.py CHANGED
@@ -3,9 +3,8 @@ import autenticacion
3
  #previo = "Una fotografía de un plato blanco con "
4
  #previo = "A photograph of a white plate with a visually appealing culinary dish of "
5
  previo = "A pic of a white plate with just "
6
- llave, servidor, hora_renovacion = autenticacion.defineAmbiente()
7
 
8
- #espacio = "black-forest-labs/FLUX.1-dev"
9
  inferencia = "black-forest-labs/FLUX.1-dev"
10
  inferencia_backup = "black-forest-labs/FLUX.1-schnell"
11
  proveedor = "hf-inference" #falai
 
3
  #previo = "Una fotografía de un plato blanco con "
4
  #previo = "A photograph of a white plate with a visually appealing culinary dish of "
5
  previo = "A pic of a white plate with just "
6
+ llave, servidor, hora_renovacion, servicio = autenticacion.defineAmbiente()
7
 
 
8
  inferencia = "black-forest-labs/FLUX.1-dev"
9
  inferencia_backup = "black-forest-labs/FLUX.1-schnell"
10
  proveedor = "hf-inference" #falai
herramientas.py CHANGED
@@ -1,11 +1,7 @@
1
- import time
2
  import pytz
3
- import random
4
  import globales
5
  import conexion_firebase
6
  from datetime import datetime
7
- import time
8
-
9
 
10
  servidor = globales.servidor
11
 
@@ -134,4 +130,34 @@ def siEsDiaSiguienteRenueva():
134
  else:
135
  print("Aún no hay renovación de capa de procesamiento.")
136
 
137
- return resultado
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import pytz
 
2
  import globales
3
  import conexion_firebase
4
  from datetime import datetime
 
 
5
 
6
  servidor = globales.servidor
7
 
 
130
  else:
131
  print("Aún no hay renovación de capa de procesamiento.")
132
 
133
+ return resultado
134
+
135
+ def despliegaInfoCliente(request):
136
+ # 1. Obtener la IP del cliente (priorizando X-Forwarded-For)
137
+ client_ip = request.headers.get("x-forwarded-for") or \
138
+ request.headers.get("x-real-ip") or \
139
+ (request.client.host if request.client else "unknown")
140
+
141
+ # Si X-Forwarded-For es una lista de IPs separadas por coma
142
+ if client_ip and "," in client_ip:
143
+ client_ip = client_ip.split(",")[0].strip() # Tomamos la primera IP (la original)
144
+
145
+ # 2. Obtener el User-Agent
146
+ user_agent = request.headers.get("user-agent", "unknown")
147
+
148
+ # 3. Información de autenticación (si aplica)
149
+ auth_header = request.headers.get("authorization")
150
+ user_id = "unauthenticated"
151
+ if auth_header and auth_header.startswith("Bearer "):
152
+ token = auth_header.split(" ")[1]
153
+ # Aquí normalmente decodificarías el token JWT para obtener el user_id
154
+ # Ejemplo simulado:
155
+ if token == "mysecrettoken123":
156
+ user_id = "user123_authenticated"
157
+ else:
158
+ user_id = "invalid_token"
159
+ # O podrías lanzar un HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
160
+
161
+ print(f"Petición desde: {client_ip}")
162
+ print(f"User-Agent: {user_agent}")
163
+ print(f"Usuario (Auth): {user_id}")