jcalbornoz commited on
Commit
a1e2abe
·
verified ·
1 Parent(s): a3d10ff

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -14
app.py CHANGED
@@ -66,17 +66,13 @@ def upload_to_sharepoint(file_path):
66
  except Exception as e:
67
  return f"Error Sharepoint (Verificar credenciales Azure/HF): {str(e)}"
68
 
69
- # NUEVO: Módulo de Integración con Entidades Públicas (SARLAFT)
70
  def check_antecedentes_publicos(cedula):
71
  """
72
  Estructura preparada para conectar con el proveedor de APIs del Estado.
73
  Actualmente simula la validación mientras se conecta el servicio definitivo.
74
  """
75
- # TODO: Reemplazar con request a API de proveedor (ej. TusDatos)
76
  print(f"Consultando antecedentes para la cédula: {cedula}")
77
- time.sleep(1) # Simulando latencia de red
78
-
79
- # Estructura de respuesta de las listas restrictivas
80
  reporte = {
81
  "Procuraduria": "Sin antecedentes",
82
  "Policia_Nacional": "Sin requerimientos",
@@ -91,15 +87,25 @@ def run_full_onboarding(video, doc_img, full_name):
91
  if not video or not doc_img or not full_name:
92
  return None, {"Estatus": "ERROR", "Detalle": "Campos incompletos."}
93
 
94
- # 1. Extracción de cédula documental
95
  try:
96
  img_pil = Image.open(doc_img)
97
- res_ai = ai_model.generate_content(["Extrae solo el numero de cedula colombiana. Responde únicamente con los dígitos.", img_pil])
98
- ocr_res = res_ai.text.strip()
 
 
 
 
 
 
 
 
 
 
99
  except Exception as e:
100
- return None, {"Estatus": "ERROR", "Detalle": f"Fallo en extracción IA: {str(e)}"}
101
 
102
- # 2. Validación de Listas Restrictivas (Interna + Pública)
103
  df_bn = pd.read_csv(LISTA_NEGRA_FILE)
104
  if ocr_res in df_bn['cedula'].astype(str).values:
105
  return None, {"Estatus": "BLOQUEADO", "Motivo": "Cédula detectada en Lista Negra Interna."}
@@ -148,7 +154,7 @@ def run_full_onboarding(video, doc_img, full_name):
148
  if not (blink and motion):
149
  return None, {"Estatus": "RECHAZADO", "Detalle": "Prueba de vida fallida (Faltó parpadeo o giro frontal)."}
150
 
151
- # 4. Match Biométrico (AJUSTADO PARA CÉDULAS COLOMBIANAS)
152
  try:
153
  doc_bytes = face_recognition.load_image_file(doc_img)
154
  doc_encodings = face_recognition.face_encodings(doc_bytes)
@@ -157,7 +163,6 @@ def run_full_onboarding(video, doc_img, full_name):
157
  if not doc_encodings or not live_encodings:
158
  return None, {"Estatus": "ERROR", "Detalle": "No se pudo mapear la geometría facial de la imagen o del video."}
159
 
160
- # Tolerancia ajustada a 0.6 para compensar los hologramas del documento físico
161
  match = bool(face_recognition.compare_faces([doc_encodings[0]], live_encodings[0], tolerance=0.6)[0])
162
  except Exception as e:
163
  return None, {"Estatus": "ERROR", "Detalle": f"Error del motor C++: {str(e)}"}
@@ -166,6 +171,7 @@ def run_full_onboarding(video, doc_img, full_name):
166
  res = {
167
  "Estatus": "APROBADO" if match else "RECHAZADO",
168
  "Cédula_Extraída": ocr_res,
 
169
  "Coincidencia_Facial": match,
170
  "Validación_Antecedentes": "Completada (Sin reportes)",
171
  "Timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@@ -184,7 +190,9 @@ def run_full_onboarding(video, doc_img, full_name):
184
  # Título
185
  pdf.set_text_color(0, 51, 102)
186
  pdf.set_font("Arial", "B", 16)
187
- pdf.cell(200, 10, f"Certificado de Seguridad y SARLAFT - {full_name}", ln=True, align='C')
 
 
188
 
189
  # Contenido
190
  pdf.set_text_color(0, 0, 0)
@@ -197,7 +205,7 @@ def run_full_onboarding(video, doc_img, full_name):
197
  pdf.output(path_pdf)
198
  res["Auditoría_SharePoint"] = upload_to_sharepoint(path_pdf)
199
 
200
- if match: send_teams_alert(f"✅ ONBOARDING EXITOSO: {full_name} | ID: {ocr_res}")
201
  else: send_teams_alert(f"🚨 FRAUDE DETECTADO: El rostro de la cédula y el video no coinciden.", "ALERTA")
202
 
203
  return path_pdf, res
 
66
  except Exception as e:
67
  return f"Error Sharepoint (Verificar credenciales Azure/HF): {str(e)}"
68
 
 
69
  def check_antecedentes_publicos(cedula):
70
  """
71
  Estructura preparada para conectar con el proveedor de APIs del Estado.
72
  Actualmente simula la validación mientras se conecta el servicio definitivo.
73
  """
 
74
  print(f"Consultando antecedentes para la cédula: {cedula}")
75
+ time.sleep(1)
 
 
76
  reporte = {
77
  "Procuraduria": "Sin antecedentes",
78
  "Policia_Nacional": "Sin requerimientos",
 
87
  if not video or not doc_img or not full_name:
88
  return None, {"Estatus": "ERROR", "Detalle": "Campos incompletos."}
89
 
90
+ # 1. Extracción INTELIGENTE de cédula, nombres y apellidos
91
  try:
92
  img_pil = Image.open(doc_img)
93
+ prompt_ocr = """Extrae de esta cédula colombiana la siguiente información.
94
+ Retorna ESTRICTAMENTE un JSON con las llaves: 'cedula' (solo números sin puntos), 'apellidos' y 'nombres'."""
95
+
96
+ res_ai = ai_model.generate_content([prompt_ocr, img_pil])
97
+ raw_ai = res_ai.text.replace('```json', '').replace('```', '').strip()
98
+ datos_cedula = json.loads(raw_ai)
99
+
100
+ ocr_res = str(datos_cedula.get("cedula", "")).strip()
101
+ nombres_doc = datos_cedula.get("nombres", "").strip()
102
+ apellidos_doc = datos_cedula.get("apellidos", "").strip()
103
+ nombre_completo_doc = f"{nombres_doc} {apellidos_doc}"
104
+
105
  except Exception as e:
106
+ return None, {"Estatus": "ERROR", "Detalle": f"Fallo en extracción IA documental: {str(e)}"}
107
 
108
+ # 2. Validación de Listas Restrictivas
109
  df_bn = pd.read_csv(LISTA_NEGRA_FILE)
110
  if ocr_res in df_bn['cedula'].astype(str).values:
111
  return None, {"Estatus": "BLOQUEADO", "Motivo": "Cédula detectada en Lista Negra Interna."}
 
154
  if not (blink and motion):
155
  return None, {"Estatus": "RECHAZADO", "Detalle": "Prueba de vida fallida (Faltó parpadeo o giro frontal)."}
156
 
157
+ # 4. Match Biométrico
158
  try:
159
  doc_bytes = face_recognition.load_image_file(doc_img)
160
  doc_encodings = face_recognition.face_encodings(doc_bytes)
 
163
  if not doc_encodings or not live_encodings:
164
  return None, {"Estatus": "ERROR", "Detalle": "No se pudo mapear la geometría facial de la imagen o del video."}
165
 
 
166
  match = bool(face_recognition.compare_faces([doc_encodings[0]], live_encodings[0], tolerance=0.6)[0])
167
  except Exception as e:
168
  return None, {"Estatus": "ERROR", "Detalle": f"Error del motor C++: {str(e)}"}
 
171
  res = {
172
  "Estatus": "APROBADO" if match else "RECHAZADO",
173
  "Cédula_Extraída": ocr_res,
174
+ "Nombre_en_Cédula": nombre_completo_doc,
175
  "Coincidencia_Facial": match,
176
  "Validación_Antecedentes": "Completada (Sin reportes)",
177
  "Timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 
190
  # Título
191
  pdf.set_text_color(0, 51, 102)
192
  pdf.set_font("Arial", "B", 16)
193
+ pdf.cell(200, 10, f"Certificado de Seguridad y SARLAFT", ln=True, align='C')
194
+ pdf.set_font("Arial", "B", 12)
195
+ pdf.cell(200, 10, f"Usuario Registrado: {full_name}", ln=True, align='C')
196
 
197
  # Contenido
198
  pdf.set_text_color(0, 0, 0)
 
205
  pdf.output(path_pdf)
206
  res["Auditoría_SharePoint"] = upload_to_sharepoint(path_pdf)
207
 
208
+ if match: send_teams_alert(f"✅ ONBOARDING EXITOSO: {full_name} ({nombre_completo_doc}) | ID: {ocr_res}")
209
  else: send_teams_alert(f"🚨 FRAUDE DETECTADO: El rostro de la cédula y el video no coinciden.", "ALERTA")
210
 
211
  return path_pdf, res