Moibe commited on
Commit
d56556d
·
1 Parent(s): d35e97b

Nuevos campos DNI: fecha nacimiento y sexo

Browse files
__pycache__/app.cpython-311.pyc CHANGED
Binary files a/__pycache__/app.cpython-311.pyc and b/__pycache__/app.cpython-311.pyc differ
 
__pycache__/funciones.cpython-311.pyc CHANGED
Binary files a/__pycache__/funciones.cpython-311.pyc and b/__pycache__/funciones.cpython-311.pyc differ
 
app.py CHANGED
@@ -19,6 +19,7 @@ async def health_check():
19
  return JSONResponse(content={"status": "ok"}, status_code=200)
20
 
21
  @app.post("/echo-image/",
 
22
  description="Test endpoint que recibe y regresa la misma imagen, para probar envío, recepción y problemas con api o red.",
23
  summary="Summary"
24
  )
@@ -29,7 +30,8 @@ async def echo_image(image: UploadFile = File(...)):
29
  return StreamingResponse(BytesIO(contents), media_type=image.content_type)
30
 
31
  @app.post(
32
- "/procesa_dni/",
 
33
  summary="Procesamiento de DNI")
34
  async def procesa_dni(image: UploadFile = File(...)):
35
  if not image.content_type.startswith("image/"):
@@ -37,7 +39,8 @@ async def procesa_dni(image: UploadFile = File(...)):
37
  return await funciones.procesa_dni(image)
38
 
39
  @app.post(
40
- "/procesa_pasaporte/",
 
41
  summary="Procesamiento de DNI")
42
  async def procesa_pasaporte(image: UploadFile = File(...)):
43
  if not image.content_type.startswith("image/"):
 
19
  return JSONResponse(content={"status": "ok"}, status_code=200)
20
 
21
  @app.post("/echo-image/",
22
+ tags=["Health Check"],
23
  description="Test endpoint que recibe y regresa la misma imagen, para probar envío, recepción y problemas con api o red.",
24
  summary="Summary"
25
  )
 
30
  return StreamingResponse(BytesIO(contents), media_type=image.content_type)
31
 
32
  @app.post(
33
+ "/procesa_dni/",
34
+ tags=["Rapicash"],
35
  summary="Procesamiento de DNI")
36
  async def procesa_dni(image: UploadFile = File(...)):
37
  if not image.content_type.startswith("image/"):
 
39
  return await funciones.procesa_dni(image)
40
 
41
  @app.post(
42
+ "/procesa_pasaporte/",
43
+ tags=["Rapicash"],
44
  summary="Procesamiento de DNI")
45
  async def procesa_pasaporte(image: UploadFile = File(...)):
46
  if not image.content_type.startswith("image/"):
documentos.py CHANGED
@@ -2,18 +2,20 @@ import obtenCampo
2
 
3
  async def dni(textos_extraidos):
4
  textos_extraidos_simplificados = [texto.lower().replace(" ", "") for texto in textos_extraidos]
 
 
5
 
6
  #Campos Buscados
7
  nombre, apellido = obtenCampo.Nombre(textos_extraidos, textos_extraidos_simplificados)
8
  identificacion = obtenCampo.Identificacion(textos_extraidos, textos_extraidos_simplificados)
 
 
9
 
10
- return nombre, apellido, identificacion
11
 
12
  async def pasaporte(textos_extraidos):
13
  textos_extraidos_simplificados = [texto.lower().replace(" ", "") for texto in textos_extraidos]
14
-
15
  #Campos Buscados
16
  nombre, apellido = obtenCampo.Nombre(textos_extraidos, textos_extraidos_simplificados)
17
  identificacion = obtenCampo.Identificacion(textos_extraidos, textos_extraidos_simplificados)
18
-
19
  return nombre, apellido, identificacion
 
2
 
3
  async def dni(textos_extraidos):
4
  textos_extraidos_simplificados = [texto.lower().replace(" ", "") for texto in textos_extraidos]
5
+ print("Textos extraídos simplificados:")
6
+ print(textos_extraidos_simplificados)
7
 
8
  #Campos Buscados
9
  nombre, apellido = obtenCampo.Nombre(textos_extraidos, textos_extraidos_simplificados)
10
  identificacion = obtenCampo.Identificacion(textos_extraidos, textos_extraidos_simplificados)
11
+ fecha_nacimiento = obtenCampo.Fecha_Nacimiento(textos_extraidos, textos_extraidos_simplificados)
12
+ sexo = obtenCampo.Sexo(textos_extraidos, textos_extraidos_simplificados)
13
 
14
+ return nombre, apellido, identificacion, fecha_nacimiento, sexo
15
 
16
  async def pasaporte(textos_extraidos):
17
  textos_extraidos_simplificados = [texto.lower().replace(" ", "") for texto in textos_extraidos]
 
18
  #Campos Buscados
19
  nombre, apellido = obtenCampo.Nombre(textos_extraidos, textos_extraidos_simplificados)
20
  identificacion = obtenCampo.Identificacion(textos_extraidos, textos_extraidos_simplificados)
 
21
  return nombre, apellido, identificacion
funciones.py CHANGED
@@ -8,12 +8,14 @@ async def procesa_dni(image):
8
  textos_extraidos = await herramientas.procesaImagen(image)
9
 
10
  #Campos DNI Panamá.
11
- nombre, apellido, identificacion = await documentos.dni(textos_extraidos)
12
 
13
  return {
14
  "nombre": nombre,
15
  "apellido": apellido,
16
- "identificacion": identificacion
 
 
17
  }
18
 
19
  async def procesa_pasaporte(image):
 
8
  textos_extraidos = await herramientas.procesaImagen(image)
9
 
10
  #Campos DNI Panamá.
11
+ nombre, apellido, identificacion, fecha_nacimiento, sexo = await documentos.dni(textos_extraidos)
12
 
13
  return {
14
  "nombre": nombre,
15
  "apellido": apellido,
16
+ "identificacion": identificacion,
17
+ "fecha_nacimiento": fecha_nacimiento,
18
+ "sexo": sexo
19
  }
20
 
21
  async def procesa_pasaporte(image):
herramientas.py CHANGED
@@ -1,10 +1,9 @@
1
  import tempfile
2
  import time
3
- import herramientas
4
  from gradio_client import Client, handle_file
 
5
 
6
  async def imageToTemp(image):
7
- print("Estoy en imageToTemp...")
8
 
9
  try:
10
  with tempfile.NamedTemporaryFile(delete=False, suffix=f"_{image.filename}") as tmp_file:
@@ -37,10 +36,49 @@ def listaTextosExtraidos(dict_recibido):
37
 
38
  def buscaIndexPalabra(arreglo, palabra):
39
  palabra_limpia = palabra.lower().replace(" ", "")
40
- for i, texto_limpio in enumerate(arreglo):
41
  if palabra_limpia in texto_limpio:
42
  return i
43
- return 'error'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  def buscarPatronCedula(lista_textos):
46
  for i, texto in enumerate(lista_textos):
@@ -52,7 +90,7 @@ async def procesaImagen(image):
52
 
53
  temp_image = await imageToTemp(image)
54
 
55
- client = Client("Moibe/api_rapicash")
56
  dict_recibido = client.predict(
57
  img=handle_file(temp_image),
58
  lang="en",
@@ -60,4 +98,49 @@ async def procesaImagen(image):
60
  )
61
  #Aquí es donde personalizo el proceso:
62
  textos_extraidos = listaTextosExtraidos(dict_recibido)
63
- return textos_extraidos
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import tempfile
2
  import time
 
3
  from gradio_client import Client, handle_file
4
+ import re
5
 
6
  async def imageToTemp(image):
 
7
 
8
  try:
9
  with tempfile.NamedTemporaryFile(delete=False, suffix=f"_{image.filename}") as tmp_file:
 
36
 
37
  def buscaIndexPalabra(arreglo, palabra):
38
  palabra_limpia = palabra.lower().replace(" ", "")
39
+ for i, texto_limpio in enumerate(arreglo):
40
  if palabra_limpia in texto_limpio:
41
  return i
42
+ return None # Cambiado de 'error' a None
43
+
44
+ def buscaIndexMultiplesPalabras(arreglo, palabras_requeridas):
45
+ """
46
+ Busca el índice de la primera línea en un arreglo de textos
47
+ que contenga TODAS las palabras especificadas en palabras_requeridas.
48
+
49
+ Args:
50
+ arreglo (list): Una lista de strings (los textos limpios).
51
+ palabras_requeridas (list): Una lista de strings, donde cada string
52
+ es una palabra que debe estar presente en la línea.
53
+ La búsqueda es insensible a mayúsculas/minúsculas
54
+ y limpia espacios en las palabras requeridas.
55
+
56
+ Returns:
57
+ int: El índice de la primera línea que contiene todas las palabras,
58
+ o None si ninguna línea las contiene.
59
+ """
60
+
61
+ print("Estoy en busca palabras múltiples.")
62
+
63
+
64
+ # Limpiar y normalizar todas las palabras requeridas de una vez
65
+ palabras_requeridas_limpias = [p.lower().replace(" ", "") for p in palabras_requeridas]
66
+
67
+ print("Las palabras requeridas límpias son: ", palabras_requeridas_limpias)
68
+
69
+ for i, texto_linea in enumerate(arreglo):
70
+ # Convertir la línea actual a minúsculas para una comparación insensible a mayúsculas/minúsculas
71
+ texto_linea_lower = texto_linea.lower()
72
+
73
+ print("La línea que estoy analizando es: ", texto_linea_lower)
74
+
75
+ # Verificar si TODAS las palabras requeridas están en la línea actual
76
+ # Usamos 'all()' para asegurarnos de que CADA palabra_limpia esté en texto_linea_lower
77
+ if all(palabra_limpia in texto_linea_lower for palabra_limpia in palabras_requeridas_limpias):
78
+ print(f"Todas las palabras están en la línea {i}")
79
+ return i # Retorna el índice de la primera línea que cumple la condición
80
+
81
+ return None # Si ninguna línea contiene todas las palabras
82
 
83
  def buscarPatronCedula(lista_textos):
84
  for i, texto in enumerate(lista_textos):
 
90
 
91
  temp_image = await imageToTemp(image)
92
 
93
+ client = Client("BuzzwordMx/ai_ocr")
94
  dict_recibido = client.predict(
95
  img=handle_file(temp_image),
96
  lang="en",
 
98
  )
99
  #Aquí es donde personalizo el proceso:
100
  textos_extraidos = listaTextosExtraidos(dict_recibido)
101
+ return textos_extraidos
102
+
103
+ def obtener_fecha(texto):
104
+ # El patrón busca:
105
+ # - "FECHADENACIMIENTO" (insensible a mayúsculas/minúsculas)
106
+ # - Seguido opcionalmente de CERO o MÁS caracteres que NO SEAN UN DÍGITO (lo que inicia la fecha).
107
+ # Esto cubrirá ':', '.', espacios, o cualquier otro carácter de separación.
108
+ # - Captura el patrón de fecha: \d{1,2}-[A-Za-z0-9]{3}-\d{4}
109
+ patron = r"FECHADENACIMIENTO[^\d]*(\d{1,2}-[A-Za-z0-9]{3}-\d{4})"
110
+
111
+ match = re.search(patron, texto, re.IGNORECASE)
112
+
113
+ fecha_encontrada = None
114
+ if match:
115
+ fecha_encontrada = match.group(1)
116
+
117
+ if fecha_encontrada:
118
+ partes_fecha = fecha_encontrada.split('-')
119
+ if len(partes_fecha) == 3:
120
+ dia = partes_fecha[0]
121
+ mes = partes_fecha[1].lower() # Convierte el mes a minúsculas
122
+ año = partes_fecha[2]
123
+ return f"{dia}-{mes}-{año}"
124
+ else:
125
+ # Esto se ejecutaría si el formato de la fecha extraída no es el esperado (ej. 2 partes)
126
+ return fecha_encontrada
127
+
128
+ return None # Si no se encontró el patrón de fecha
129
+
130
+ def obtener_sexo(texto):
131
+ # El patrón ahora busca "Sexo" O "Seno" (insensible a mayúsculas/minúsculas)
132
+ # Seguido opcionalmente de un ":"
133
+ # Seguido opcionalmente de espacios en blanco
134
+ # Captura la siguiente letra
135
+ patron = r"(Sexo|Seno):?\s*([A-Za-z])"
136
+
137
+ # re.search busca la primera ocurrencia del patrón en el texto
138
+ # re.IGNORECASE hace que la búsqueda sea insensible a mayúsculas/minúsculas para "Sexo" y "Seno"
139
+ match = re.search(patron, texto, re.IGNORECASE)
140
+
141
+ if match:
142
+ # match.group(2) devuelve lo que se capturó en el SEGUNDO grupo de paréntesis,
143
+ # que es la letra del sexo/seno. match.group(1) sería "Sexo" o "Seno".
144
+ return match.group(2)
145
+ else:
146
+ return None
obtenCampo.py CHANGED
@@ -4,7 +4,6 @@ import herramientas
4
  #Campos para DNI.
5
  def Nombre(textos_extraidos, textos_extraidos_limpios):
6
  indice = herramientas.buscaIndexPalabra(textos_extraidos_limpios, 'usual')
7
- print(f"Indice es: {indice} y es del tipo {type(indice)}...")
8
  nombre = textos_extraidos[indice-2]
9
  apellido = textos_extraidos[indice-1]
10
  return nombre, apellido
@@ -12,4 +11,30 @@ def Nombre(textos_extraidos, textos_extraidos_limpios):
12
  def Identificacion(textos_extraidos, textos_extraidos_limpios):
13
  indice = herramientas.buscarPatronCedula(textos_extraidos_limpios)
14
  identificacion = textos_extraidos[indice]
15
- return identificacion
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  #Campos para DNI.
5
  def Nombre(textos_extraidos, textos_extraidos_limpios):
6
  indice = herramientas.buscaIndexPalabra(textos_extraidos_limpios, 'usual')
 
7
  nombre = textos_extraidos[indice-2]
8
  apellido = textos_extraidos[indice-1]
9
  return nombre, apellido
 
11
  def Identificacion(textos_extraidos, textos_extraidos_limpios):
12
  indice = herramientas.buscarPatronCedula(textos_extraidos_limpios)
13
  identificacion = textos_extraidos[indice]
14
+ return identificacion
15
+
16
+ def Fecha_Nacimiento(textos_extraidos, textos_extraidos_limpios):
17
+ indice = herramientas.buscaIndexMultiplesPalabras(textos_extraidos_limpios, ['fecha', 'nacimiento'])
18
+ print("El índice de la fecha de nacimiento es: ", indice)
19
+ texto_fecha_nacimiento = textos_extraidos_limpios[indice] #En ésta ocasión estoy usando el texto limpio para que el patrón lo identifique más fácilmente.
20
+ print("Y su correspondiente texto es: " , texto_fecha_nacimiento)
21
+ fecha_nacimiento = herramientas.obtener_fecha(texto_fecha_nacimiento)
22
+ return fecha_nacimiento
23
+
24
+ def Sexo(textos_extraidos, textos_extraidos_limpios):
25
+
26
+ indice = herramientas.buscaIndexPalabra(textos_extraidos_limpios, 'sexo')
27
+
28
+ if indice is None: # Comprobamos si el resultado es None (no encontrado)
29
+ indice = herramientas.buscaIndexPalabra(textos_extraidos_limpios, 'seno')
30
+ if indice is not None:
31
+ print(f"Se encontró una variación de sexo en el índice: {indice}")
32
+ else:
33
+ print("No se encontró ninguna forma de la palabra sexo.")
34
+ return None
35
+ else:
36
+ print(f"Se encontró palabra directamente.")
37
+
38
+ texto_campo_sexo = textos_extraidos[indice]
39
+ sexo = herramientas.obtener_sexo(texto_campo_sexo)
40
+ return sexo