angelsg213 commited on
Commit
4bbc0ce
verified
1 Parent(s): 9e4ee14

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +13 -78
app.py CHANGED
@@ -1,52 +1,21 @@
1
- import gradio as gr
2
- import PyPDF2
3
- import requests
4
- import json
5
- import re
6
- import os # Necesario para leer los secretos
7
-
8
- # ==========================================
9
- # CONFIGURACI脫N SEGURA (SECRETS)
10
- # ==========================================
11
- # Busca una variable llamada "HF_TOKEN" en la configuraci贸n del Space
12
- HF_TOKEN = os.getenv("aa")
13
-
14
- # Verificaci贸n de seguridad
15
- if not HF_TOKEN:
16
- print("鈿狅笍 ADVERTENCIA: No se encontr贸 el HF_TOKEN. Config煤ralo en Settings -> Secrets.")
17
-
18
  # ==========================================
19
- # 1. EXTRACCI脫N DE TEXTO (PDF -> String)
20
- # ==========================================
21
- def extraer_texto_pdf(pdf_file):
22
- if not pdf_file:
23
- return "No se subi贸 ning煤n archivo."
24
- try:
25
- pdf_reader = PyPDF2.PdfReader(pdf_file)
26
- texto_completo = ""
27
- for pagina in pdf_reader.pages:
28
- texto_completo += pagina.extract_text() + "\n"
29
- return texto_completo
30
- except Exception as e:
31
- return f"Error al leer PDF: {str(e)}"
32
-
33
- # ==========================================
34
- # 2. CONSULTA AL LLM (API Hugging Face)
35
  # ==========================================
36
  def consultar_llm(texto_factura):
37
- # Si no hay token, devolver error inmediato
38
- if not HF_TOKEN:
 
 
39
  return {"error": "Falta configurar HF_TOKEN en Settings -> Secrets"}
40
 
41
- # Recortar texto para no exceder tokens
42
  texto_limpio = texto_factura[:6000]
43
 
44
- # URL del modelo (Usamos Mistral v0.3 que es excelente siguiendo instrucciones)
45
- API_URL = "https://router.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.3"
46
 
47
  headers = {
48
  "Content-Type": "application/json",
49
- "Authorization": f"Bearer {HF_TOKEN}"
50
  }
51
 
52
  prompt = f"""
@@ -78,8 +47,11 @@ def consultar_llm(texto_factura):
78
  "inputs": prompt,
79
  "parameters": {
80
  "max_new_tokens": 1500,
81
- "temperature": 0.1, # Bajo para precisi贸n
82
  "return_full_text": False
 
 
 
83
  }
84
  }
85
 
@@ -91,14 +63,12 @@ def consultar_llm(texto_factura):
91
 
92
  resultado = response.json()
93
 
94
- # Obtener el texto generado (maneja si devuelve lista o dict)
95
  texto_generado = ""
96
  if isinstance(resultado, list) and len(resultado) > 0:
97
  texto_generado = resultado[0].get('generated_text', '')
98
  elif isinstance(resultado, dict):
99
  texto_generado = resultado.get('generated_text', '')
100
 
101
- # Buscar el bloque JSON dentro de la respuesta (por si el modelo a帽ade texto extra)
102
  match = re.search(r'\{.*\}', texto_generado, re.DOTALL)
103
  if match:
104
  return json.loads(match.group(0))
@@ -106,39 +76,4 @@ def consultar_llm(texto_factura):
106
  return {"error": "El modelo no gener贸 un JSON v谩lido", "respuesta_cruda": texto_generado}
107
 
108
  except Exception as e:
109
- return {"error": f"Error interno: {str(e)}"}
110
-
111
- # ==========================================
112
- # 3. INTERFAZ GR脕FICA (Gradio)
113
- # ==========================================
114
- def procesar_factura(pdf_file):
115
- # 1. Extraer
116
- texto = extraer_texto_pdf(pdf_file)
117
- if texto.startswith("Error"):
118
- return texto, {"error": "Fallo al leer PDF"}
119
-
120
- # 2. Consultar IA
121
- datos_json = consultar_llm(texto)
122
-
123
- # 3. Mostrar bonito
124
- return texto, json.dumps(datos_json, indent=4, ensure_ascii=False)
125
-
126
- # Dise帽o de la interfaz
127
- with gr.Blocks(title="Extractor Facturas AI") as demo:
128
- gr.Markdown("# 馃 Extractor de Facturas Seguro")
129
- gr.Markdown("Este espacio usa tu token de forma privada para extraer datos de facturas PDF.")
130
-
131
- with gr.Row():
132
- with gr.Column(scale=1):
133
- input_pdf = gr.File(label="Sube tu Factura (PDF)", file_types=[".pdf"])
134
- btn = gr.Button("Extraer Datos", variant="primary")
135
-
136
- with gr.Column(scale=2):
137
- output_json = gr.Code(label="Datos Extra铆dos (JSON)", language="json")
138
- with gr.Accordion("Ver texto crudo extra铆do del PDF", open=False):
139
- output_text = gr.Textbox(label="Texto Original", lines=10)
140
-
141
- btn.click(fn=procesar_factura, inputs=input_pdf, outputs=[output_text, output_json])
142
-
143
- if __name__ == "__main__":
144
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # ==========================================
2
+ # 2. CONSULTA AL LLM (CORREGIDO)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  # ==========================================
4
  def consultar_llm(texto_factura):
5
+ # CORRECCI脫N 1: Aseg煤rate de que esto coincida con el nombre en tus Secrets
6
+ token = os.getenv("aa")
7
+
8
+ if not token:
9
  return {"error": "Falta configurar HF_TOKEN en Settings -> Secrets"}
10
 
 
11
  texto_limpio = texto_factura[:6000]
12
 
13
+ # CORRECCI脫N 2: Usamos la URL est谩ndar y la versi贸n v0.2 que es m谩s estable
14
+ API_URL = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2"
15
 
16
  headers = {
17
  "Content-Type": "application/json",
18
+ "Authorization": f"Bearer {token}"
19
  }
20
 
21
  prompt = f"""
 
47
  "inputs": prompt,
48
  "parameters": {
49
  "max_new_tokens": 1500,
50
+ "temperature": 0.1,
51
  "return_full_text": False
52
+ },
53
+ "options": {
54
+ "wait_for_model": True # Esperar si el modelo est谩 cargando
55
  }
56
  }
57
 
 
63
 
64
  resultado = response.json()
65
 
 
66
  texto_generado = ""
67
  if isinstance(resultado, list) and len(resultado) > 0:
68
  texto_generado = resultado[0].get('generated_text', '')
69
  elif isinstance(resultado, dict):
70
  texto_generado = resultado.get('generated_text', '')
71
 
 
72
  match = re.search(r'\{.*\}', texto_generado, re.DOTALL)
73
  if match:
74
  return json.loads(match.group(0))
 
76
  return {"error": "El modelo no gener贸 un JSON v谩lido", "respuesta_cruda": texto_generado}
77
 
78
  except Exception as e:
79
+ return {"error": f"Error interno: {str(e)}"}