Spaces:
				
			
			
	
			
			
		Runtime error
		
	
	
	
			
			
	
	
	
	
		
		
		Runtime error
		
	DNI Panamá Listo
Browse files- app.py +11 -59
- cloudfunction.py +0 -64
- conexion_firebase.py +0 -44
- config.json +0 -13
- default.png +0 -0
- documentos.py +10 -0
- espacios.py +0 -41
- funciones.py +57 -0
- herramientas.py +26 -197
- ia.py +96 -0
- obtenCampo.py +12 -0
- requirements.txt +6 -1
    	
        app.py
    CHANGED
    
    | @@ -1,15 +1,13 @@ | |
| 1 | 
            -
            import  | 
| 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 |  | 
| 8 | 
             
            app = FastAPI()
         | 
| 9 |  | 
| 10 | 
            -
            # Nuevo endpoint para Health Check
         | 
| 11 | 
             
            @app.get("/health",
         | 
| 12 | 
            -
                     tags=[" | 
| 13 | 
             
                     description="Verifica el estado de salud de la API.",
         | 
| 14 | 
             
                     summary="Health Check"
         | 
| 15 | 
             
                     )
         | 
| @@ -20,8 +18,9 @@ async def health_check(): | |
| 20 | 
             
                return JSONResponse(content={"status": "ok"}, status_code=200)
         | 
| 21 |  | 
| 22 | 
             
            @app.post("/echo-image/",
         | 
| 23 | 
            -
                       | 
| 24 | 
            -
                       | 
|  | |
| 25 | 
             
                      )
         | 
| 26 | 
             
            async def echo_image(image: UploadFile = File(...)):
         | 
| 27 | 
             
                if not image.content_type.startswith("image/"):
         | 
| @@ -30,60 +29,13 @@ async def echo_image(image: UploadFile = File(...)): | |
| 30 | 
             
                return StreamingResponse(BytesIO(contents), media_type=image.content_type)
         | 
| 31 |  | 
| 32 | 
             
            @app.post("/procesa-dni/",
         | 
| 33 | 
            -
                       | 
| 34 | 
            -
                       | 
|  | |
| 35 | 
             
                      )
         | 
| 36 | 
             
            async def echo_image(image: UploadFile = File(...)):
         | 
| 37 | 
             
                if not image.content_type.startswith("image/"):
         | 
| 38 | 
             
                    return {"error": "El archivo no es una imagen"}
         | 
| 39 | 
            -
                contents = await image.read()
         | 
| 40 | 
            -
                return StreamingResponse(BytesIO(contents), media_type=image.content_type)
         | 
| 41 | 
            -
             | 
| 42 | 
            -
            @app.post("/genera-imagen/")
         | 
| 43 | 
            -
            async def genera_imagen(platillo: str = Form(...)):
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                seconds_available = herramientas.obtenSegundosDisponibles() #Ahora los segundos disponible son independientes. Por server no hay diferencia, pero si por cuenta (y ahora tenemos 3 PRO), es importante que no quede ese distintivo en código para que la sincronización sea fácil y rápida. Local es Moibe, las demás su respectivo server. Todos manejados en bridges y en hf variables.
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                print(herramientas.imprimeTimeNow())
         | 
| 48 | 
            -
                
         | 
| 49 | 
            -
                if seconds_available > globales.work_cost:
         | 
| 50 | 
            -
                    print("Usando GPU (capa gratuita)...")
         | 
| 51 | 
            -
                    resultado = funciones.genera_platillo_gpu(platillo)
         | 
| 52 | 
            -
                    if "Error" in resultado:
         | 
| 53 | 
            -
                        return resultado
         | 
| 54 | 
            -
                    else:
         | 
| 55 | 
            -
                        return FileResponse(resultado, media_type="image/png", filename="imagen.png")
         | 
| 56 | 
            -
                else: 
         | 
| 57 | 
            -
                    
         | 
| 58 | 
            -
                    print("Usando Inference...")
         | 
| 59 | 
            -
                    resultado = funciones.genera_platillo_inference(platillo)
         | 
| 60 | 
            -
                    print("El resultado de inference es: ", resultado)
         | 
| 61 | 
            -
                    if type(resultado) is str:
         | 
| 62 | 
            -
                        return resultado
         | 
| 63 | 
            -
                    else:
         | 
| 64 | 
            -
                        return StreamingResponse(content=resultado, media_type="image/png")    
         | 
| 65 | 
            -
             | 
| 66 | 
            -
            # @app.post("/procesador-lotes/")
         | 
| 67 | 
            -
            # async def procesa_lote(platillo: str = Form(...)):
         | 
| 68 | 
            -
             | 
| 69 | 
            -
            #     print("Servicio Secundario de Procesamiento de Lotes")    
         | 
| 70 | 
            -
            #     seconds_available = herramientas.obtenSegundosDisponibles()
         | 
| 71 | 
            -
            #     #seconds_available = 0 
         | 
| 72 | 
            -
            #     print(herramientas.imprimeTimeNow())
         | 
| 73 | 
            -
                
         | 
| 74 | 
            -
            #     if seconds_available > globales.work_cost:
         | 
| 75 | 
            -
            #         print("Usando GPU (capa gratuita)...")
         | 
| 76 | 
            -
            #         resultado = funciones.genera_platillo_gpu(platillo)
         | 
| 77 | 
            -
            #         if "Error" in resultado:
         | 
| 78 | 
            -
            #             return resultado
         | 
| 79 | 
            -
            #         else:
         | 
| 80 | 
            -
            #             return FileResponse(resultado, media_type="image/png", filename="imagen.png")
         | 
| 81 | 
            -
            #     else: 
         | 
| 82 | 
            -
                    
         | 
| 83 | 
            -
            #         print("Usando Inference...")
         | 
| 84 | 
            -
            #         resultado = funciones.genera_platillo_inference(platillo)
         | 
| 85 | 
            -
            #         print("El resultado de inference es: ", resultado)
         | 
| 86 | 
            -
            #         if type(resultado) is str:
         | 
| 87 | 
            -
            #             return resultado
         | 
| 88 | 
            -
            #         else:
         | 
| 89 | 
            -
            #             return StreamingResponse(content=resultado, media_type="image/png")                
         | 
|  | |
| 1 | 
            +
            import ia
         | 
| 2 | 
             
            from io import BytesIO
         | 
|  | |
| 3 | 
             
            from fastapi import FastAPI, Form
         | 
| 4 | 
             
            from fastapi import FastAPI, File, UploadFile
         | 
| 5 | 
             
            from fastapi.responses import StreamingResponse, FileResponse, JSONResponse
         | 
| 6 |  | 
| 7 | 
             
            app = FastAPI()
         | 
| 8 |  | 
|  | |
| 9 | 
             
            @app.get("/health",
         | 
| 10 | 
            +
                     tags=["Monitoreo Server"],
         | 
| 11 | 
             
                     description="Verifica el estado de salud de la API.",
         | 
| 12 | 
             
                     summary="Health Check"
         | 
| 13 | 
             
                     )
         | 
|  | |
| 18 | 
             
                return JSONResponse(content={"status": "ok"}, status_code=200)
         | 
| 19 |  | 
| 20 | 
             
            @app.post("/echo-image/",
         | 
| 21 | 
            +
                      tags=["Monitoreo Server"],
         | 
| 22 | 
            +
                      description="Test endpoint para prueba de envío de imagenes.",
         | 
| 23 | 
            +
                      summary="Mirror test para envío de imagenes"
         | 
| 24 | 
             
                      )
         | 
| 25 | 
             
            async def echo_image(image: UploadFile = File(...)):
         | 
| 26 | 
             
                if not image.content_type.startswith("image/"):
         | 
|  | |
| 29 | 
             
                return StreamingResponse(BytesIO(contents), media_type=image.content_type)
         | 
| 30 |  | 
| 31 | 
             
            @app.post("/procesa-dni/",
         | 
| 32 | 
            +
                      tags=["Rapicash"],
         | 
| 33 | 
            +
                      description="Procesa DNI de Panamá obteniendo los datos deseados.",
         | 
| 34 | 
            +
                      summary="Identificación de DNI con IA"
         | 
| 35 | 
             
                      )
         | 
| 36 | 
             
            async def echo_image(image: UploadFile = File(...)):
         | 
| 37 | 
             
                if not image.content_type.startswith("image/"):
         | 
| 38 | 
             
                    return {"error": "El archivo no es una imagen"}
         | 
| 39 | 
            +
                contents = await image.read()    
         | 
| 40 | 
            +
                # return StreamingResponse(BytesIO(contents), media_type=image.content_type)
         | 
| 41 | 
            +
                return ia.inference(contents, 'en')
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
    	
        cloudfunction.py
    DELETED
    
    | @@ -1,64 +0,0 @@ | |
| 1 | 
            -
            # main.py o donde definas tus funciones
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            import firebase_admin
         | 
| 4 | 
            -
            from firebase_functions import pubsub_fn, options
         | 
| 5 | 
            -
            from firebase_admin import firestore, exceptions # Import exceptions for better error handling
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            # Inicializa Firebase Admin si no lo has hecho ya en tu proyecto
         | 
| 8 | 
            -
            # Esto generalmente se hace una vez en el punto de entrada de tus funciones (ej. en __init__.py o al inicio de tu main.py)
         | 
| 9 | 
            -
            # Puedes usar un bloque try/except para evitar reinicializar si ya está inicializado.
         | 
| 10 | 
            -
            # try:
         | 
| 11 | 
            -
            #     firebase_admin.get_app()
         | 
| 12 | 
            -
            # except ValueError:
         | 
| 13 | 
            -
            #     firebase_admin.initialize_app()
         | 
| 14 | 
            -
             | 
| 15 | 
            -
            # Obtén una referencia a la base de datos de Firestore con el nombre 'nowme'
         | 
| 16 | 
            -
            # Asegúrate de que firebase_admin.initializeApp() se haya ejecutado antes de obtener esta referencia.
         | 
| 17 | 
            -
            # firestore.client() obtiene el cliente para la app por defecto,
         | 
| 18 | 
            -
            # y luego .instance('nowme') especifica la base de datos con nombre.
         | 
| 19 | 
            -
            db = firestore.client().instance('nowme')
         | 
| 20 | 
            -
             | 
| 21 | 
            -
            @pubsub_fn.on_message_published(
         | 
| 22 | 
            -
                # Puedes dar un nombre lógico al trabajo programado (Cloud Scheduler job) si quieres
         | 
| 23 | 
            -
                # topic="increment-segundos-job", # Este parámetro no es necesario para schedule, Firebase lo gestiona
         | 
| 24 | 
            -
                schedule="every 24 hours at 16:00",
         | 
| 25 | 
            -
                timezone="America/Mexico_City", # Establece la zona horaria a Ciudad de México
         | 
| 26 | 
            -
                # Opcional: puedes añadir opciones de runtime aquí si lo necesitas
         | 
| 27 | 
            -
                # memory=options.MemoryOption.GB_1, # Ejemplo: 1 GB de memoria
         | 
| 28 | 
            -
                # timeout_sec=300, # Ejemplo: 5 minutos de timeout
         | 
| 29 | 
            -
            )
         | 
| 30 | 
            -
            def incrementar_segundos_python(event: pubsub_fn.CloudEvent) -> None:
         | 
| 31 | 
            -
                """
         | 
| 32 | 
            -
                Cloud Function en Python activada por un programador
         | 
| 33 | 
            -
                para incrementar el campo 'segundos' en un documento de Firestore.
         | 
| 34 | 
            -
                """
         | 
| 35 | 
            -
                print(f"Function incrementar_segundos_python activada a las {event.time} por mensaje ID: {event.id}")
         | 
| 36 | 
            -
                # Para este caso, no necesitamos los datos específicos del evento Pub/Sub
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                # Referencia al documento específico: colección 'nowme', documento 'sosa'
         | 
| 39 | 
            -
                doc_ref = db.collection('nowme').document('sosa')
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                try:
         | 
| 42 | 
            -
                    # Usa update con FieldValue.increment para una actualización atómica segura
         | 
| 43 | 
            -
                    # Esto es especialmente bueno para valores numéricos que pueden ser
         | 
| 44 | 
            -
                    # modificados por múltiples fuentes al mismo tiempo.
         | 
| 45 | 
            -
                    doc_ref.update({
         | 
| 46 | 
            -
                        "segundos": firestore.FieldValue.increment(1500)
         | 
| 47 | 
            -
                    })
         | 
| 48 | 
            -
                    print("Campo 'segundos' actualizado con éxito (+1500) en el documento 'nowme/sosa'.")
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                except exceptions.NotFound:
         | 
| 51 | 
            -
                    print("Error: Documento nowme/sosa no encontrado. No se pudo actualizar.")
         | 
| 52 | 
            -
                    # Puedes decidir si quieres crear el documento si no existe,
         | 
| 53 | 
            -
                    # pero update() solo funciona si el documento ya existe.
         | 
| 54 | 
            -
                    # Si quieres crearlo si no existe, usarías set(..., merge=True).
         | 
| 55 | 
            -
                    # doc_ref.set({"segundos": 1500}, merge=True) # Ejemplo de cómo crear/actualizar
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                except Exception as e:
         | 
| 58 | 
            -
                    print(f"Error al actualizar el documento nowme/sosa: {e}")
         | 
| 59 | 
            -
                    # Puedes lanzar la excepción si quieres que Cloud Functions lo reporte como un fallo.
         | 
| 60 | 
            -
                    # raise e
         | 
| 61 | 
            -
                    pass # O simplemente pasar para que la Function no se marque como fallo en este caso
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                print("Fin de la ejecución de la Function.")
         | 
| 64 | 
            -
             | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
    	
        conexion_firebase.py
    DELETED
    
    | @@ -1,44 +0,0 @@ | |
| 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)
         | 
| 10 | 
            -
             | 
| 11 | 
            -
            db = firestore.client(database_id='nowme')
         | 
| 12 | 
            -
            #dato es el dato que traes  como el nombre del user. 
         | 
| 13 | 
            -
            #info es la info de ese dato que estás buscando, como token.
         | 
| 14 | 
            -
            def obtenDato(coleccion, dato, info):
         | 
| 15 | 
            -
                #Future: Tentativamente ésta parte podría solo hacerse una vez y vivir en la app para ser reutilizado.
         | 
| 16 | 
            -
                
         | 
| 17 | 
            -
                #Primero debemos definir la referencia al documento, o sea a la hoja de usuario.
         | 
| 18 | 
            -
                doc_ref = db.collection(coleccion).document(dato)    
         | 
| 19 | 
            -
                #Éste es el documento que tiene los datos de ella.
         | 
| 20 | 
            -
                documento = doc_ref.get()
         | 
| 21 | 
            -
                
         | 
| 22 | 
            -
                #Recuerda la conversión a diccionario.
         | 
| 23 | 
            -
                documento = doc_ref.get() 
         | 
| 24 | 
            -
                diccionario = documento.to_dict()
         | 
| 25 | 
            -
                return diccionario.get(info)
         | 
| 26 | 
            -
             | 
| 27 | 
            -
            def editaDato(coleccion, dato, info, contenido):
         | 
| 28 | 
            -
                    
         | 
| 29 | 
            -
                #Primero debemos definir la referencia al documento, o sea a la hoja de usuario.
         | 
| 30 | 
            -
                doc_ref = db.collection(coleccion).document(dato)
         | 
| 31 | 
            -
                    
         | 
| 32 | 
            -
                doc_ref.update({
         | 
| 33 | 
            -
                    # 'quote': quote,
         | 
| 34 | 
            -
                    info: contenido,
         | 
| 35 | 
            -
                })
         | 
| 36 | 
            -
             | 
| 37 | 
            -
            def creaDato(coleccion, dato, info, contenido):
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                #Primero debemos definir la referencia al documento, o sea a la hoja de usuario.
         | 
| 40 | 
            -
                doc_ref = db.collection(coleccion).document(dato)
         | 
| 41 | 
            -
                
         | 
| 42 | 
            -
                doc_ref.set({
         | 
| 43 | 
            -
                    info: contenido,
         | 
| 44 | 
            -
                })
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
    	
        config.json
    DELETED
    
    | @@ -1,13 +0,0 @@ | |
| 1 | 
            -
            {
         | 
| 2 | 
            -
              "type": "service_account",
         | 
| 3 | 
            -
              "project_id": "nowme-images-dea8a",
         | 
| 4 | 
            -
              "private_key_id": "5b80469ffe674a059beba453312ed588c2e6406f",
         | 
| 5 | 
            -
              "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC8WoI+b+BJ1Lo5\nIxiNJ/q7Za1nKaHaScxTvEM12Qa2+roVJnTxJqh0wBeoF+ylWWUdVckSKPwTOC40\nLm1ezb71Wl+EAav+5RRXdiaQbx2PGBGDjn+4pLFvzm/22cH3Sn2N9JzgHvjOgBCP\nTuXm8lSrvE2AeKrJupwXUzebin0/2W7lG2j5aKaWd5AOrOORTU2FHtBsS7mxs+IF\nsY9S29YKxtGZ/yzhG3c/6zprEZPUJXlwjr3otOZJfFObMv7VNmvR9d1D9IgN7CjN\nL3jkcbX9z7+VVMfEEybdQrr05mSoe3Shvo3EwtYIW8Gt7jSCpsZcHRRy8WnGjCHC\nqf/NB4QJAgMBAAECggEAEnfN5jUWQOr7pOtO5pVFUX9NVqyHdwWuJAY1MVgRn1qb\naQQ7qmL72LG2iBfrb0WCA3O0OsR7vd8v8ZQdS3LBPuGg9KqszHn16gL20kng1DVc\nD0IHPimgz7mGMyYkDX0XbTYvNQ74XpgCN6j45BF98ZZNo5OBTHUQhb12Ofkk4YAD\nAEYX0anGgThA5AlBMG6NaztVP1oufxv4k18gMJfA1qRQJLx984VBoqlCOuVRXmT9\npilyFQLnR9a/ucXDhKzVO1/1mjLhZhTCIok9V4LICeE/TXvb+PhsHJoS/eFlty6f\nKHSIB5i/jfhBsdx8jpqN3DmjpBWu42JUi79ZHwOo0QKBgQD6RUbKLjNOQijXEZYd\naa93feLAyafjSQKGE1BqF/DRvympFo/FIssiYTkbbdaLKmcbevwmaFwZQvcNTYFk\nSmhH7ZqVrWWlTgUx1D56+lIji/449DZJOzT4NkKNpO5oeBufUTFERAYLvWUqrfVn\n+jYLHdS4katxLwpe+7SFXWjIUQKBgQDAql0799RGmKGF/4nKPummh2gGL6SLtFA5\nd61whFu/rpUskzS8JYxRWPId3hbvKF4Hn0mlnvlAIWLEPQ0tRDYrGDbZDHeWBr6Y\nJN+vy5ycC1nunqSE59uqBIKcZSR8gcqsNnb85cDAzW7tPxlx+v9tCxRmOqs/aGdQ\nyPHyorPKOQKBgGmZs5350pIx3lOpSwMMJgqwZm5caGfB1bvHCIZLpcSK+cQsDevr\nm3TdOyB0vzMnaCwzP5PhMwNBu0a0rmUn9EptWm3PpXUTr6Nv4BE58FCpcFKN0R4j\nSl11X62uqx4Pl/AobTZV0YtAliBlGIiQDh+wraJXbNSsOZ8MbAZd/KmRAoGAP5o+\nKyTWU/PhJr5EO5rnQU1kHt6tgF0nOsFyZTmcnDvDDTMPbqkqmFQ3oXqGsa7u069W\n/bDscapT05qf9fiVtUZKHP8Ln2BcnRdXLM6Xxb/NkYOXpjRwhMD2aTDOibfDM3TL\ndRNXvY5T90gkW0dT+Sh2NIVbsRQDP10G2mWx2qkCgYBnLTMhcyuh/7HBHyKQsiZz\nzVaLnjf9pOiKdLE6ETERQH0q/LpOxY68iPRkvpTUDdHb8Y5/AK2aYeJ6MKBhE4S1\n4RlIwm80xS7G//GA47FZHFiHI+XEN+gnNzZcHR6vmg1707VkXLTF+I+01+A+mKdf\ncBgEwYp4liDawuNjz8tgSw==\n-----END PRIVATE KEY-----\n",
         | 
| 6 | 
            -
              "client_email": "firebase-adminsdk-fbsvc@nowme-images-dea8a.iam.gserviceaccount.com",
         | 
| 7 | 
            -
              "client_id": "107709451350786325129",
         | 
| 8 | 
            -
              "auth_uri": "https://accounts.google.com/o/oauth2/auth",
         | 
| 9 | 
            -
              "token_uri": "https://oauth2.googleapis.com/token",
         | 
| 10 | 
            -
              "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
         | 
| 11 | 
            -
              "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40nowme-images-dea8a.iam.gserviceaccount.com",
         | 
| 12 | 
            -
              "universe_domain": "googleapis.com"
         | 
| 13 | 
            -
            }
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
    	
        default.png
    DELETED
    
    | Binary file (62.5 kB) | 
|  | 
    	
        documentos.py
    ADDED
    
    | @@ -0,0 +1,10 @@ | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 1 | 
            +
            import obtenCampo
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            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
         | 
    	
        espacios.py
    DELETED
    
    | @@ -1,41 +0,0 @@ | |
| 1 | 
            -
            import herramientas
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            # server =  herramientas.getFluxServer()
         | 
| 4 | 
            -
            # print("Server elegido: ", server)
         | 
| 5 | 
            -
            # print("El type es: ", type(server))
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            espacio = [
         | 
| 8 | 
            -
                {
         | 
| 9 | 
            -
                    "id": "black-forest-labs/FLUX.1-dev",
         | 
| 10 | 
            -
                    "static_kwargs": { 
         | 
| 11 | 
            -
                        "api_name": "/infer",
         | 
| 12 | 
            -
                    }
         | 
| 13 | 
            -
                },
         | 
| 14 | 
            -
                # { 
         | 
| 15 | 
            -
                #     "id": "black-forest-labs/FLUX.1-schnell",
         | 
| 16 | 
            -
                #     "static_kwargs": {
         | 
| 17 | 
            -
                #         "api_name": "/infer",
         | 
| 18 | 
            -
                #     }
         | 
| 19 | 
            -
                # },
         | 
| 20 | 
            -
                # {
         | 
| 21 | 
            -
                #     "id": "NihalGazi/FLUX-Pro-Unlimited",
         | 
| 22 | 
            -
                #     "static_kwargs": {
         | 
| 23 | 
            -
                #         "api_name": "/generate_image", 
         | 
| 24 | 
            -
                #         "server_choice": server,
         | 
| 25 | 
            -
                #     }
         | 
| 26 | 
            -
                # },
         | 
| 27 | 
            -
                # { 
         | 
| 28 | 
            -
                #     "id": "HiDream-ai/HiDream-I1-Dev",
         | 
| 29 | 
            -
                #     "static_kwargs": {
         | 
| 30 | 
            -
                #         "api_name": "/infer",
         | 
| 31 | 
            -
                #      
         | 
| 32 | 
            -
                #     }
         | 
| 33 | 
            -
                # },
         | 
| 34 | 
            -
                # { 
         | 
| 35 | 
            -
                #     "id": "stabilityai/stable-diffusion",
         | 
| 36 | 
            -
                #     "static_kwargs": {
         | 
| 37 | 
            -
                #         "api_name": "/generate",
         | 
| 38 | 
            -
                #         
         | 
| 39 | 
            -
                #     }
         | 
| 40 | 
            -
                # }
         | 
| 41 | 
            -
            ]
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
    	
        funciones.py
    CHANGED
    
    | @@ -11,6 +11,63 @@ from huggingface_hub import InferenceClient | |
| 11 |  | 
| 12 | 
             
            servidor = globales.servidor
         | 
| 13 |  | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 14 | 
             
            def genera_platillo_gpu(platillo):
         | 
| 15 |  | 
| 16 | 
             
                prompt = globales.previo + platillo
         | 
|  | |
| 11 |  | 
| 12 | 
             
            servidor = globales.servidor
         | 
| 13 |  | 
| 14 | 
            +
            def procesa_dni(platillo):
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                print("Estoy en procesa DNI...")
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                print("Y esto es contents: ", platillo)
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                time.sleep(18)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                prompt = globales.previo + platillo
         | 
| 23 | 
            +
                print("Platillo enviado:", platillo) 
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                try:
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    dict_espacios = conexion_firebase.obtenDato('nowme', servidor, 'espacios')
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    espacios_habilitados = [
         | 
| 30 | 
            +
                    nombre for nombre, config in dict_espacios.items()
         | 
| 31 | 
            +
                    if config.get("habilitado", False) # Usamos .get() para evitar KeyError si 'habilitado' no existe
         | 
| 32 | 
            +
                    ]
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    print(f"Espacios habilitados: {espacios_habilitados}")
         | 
| 35 | 
            +
                    
         | 
| 36 | 
            +
                    espacio_aleatorio_elegido = random.choice(espacios_habilitados)
         | 
| 37 | 
            +
                    configuracion_espacio = dict_espacios[espacio_aleatorio_elegido]
         | 
| 38 | 
            +
                    print(f"La configuración completa para '{espacio_aleatorio_elegido}' es: {configuracion_espacio}")
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                    client = gradio_client.Client(configuracion_espacio['ruta'], hf_token=globales.llave)
         | 
| 41 | 
            +
                    #kwargs = selected_space_config['static_kwargs']
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    result = client.predict(
         | 
| 44 | 
            +
                    #**kwargs,
         | 
| 45 | 
            +
                    prompt=prompt,
         | 
| 46 | 
            +
                    #negative_prompt="live animals",
         | 
| 47 | 
            +
                    # seed=42,
         | 
| 48 | 
            +
                    # randomize_seed=True,
         | 
| 49 | 
            +
                    width=786,
         | 
| 50 | 
            +
                    height=568,
         | 
| 51 | 
            +
                    # guidance_scale=3.5,
         | 
| 52 | 
            +
                    # num_inference_steps=28,
         | 
| 53 | 
            +
                    api_name=configuracion_espacio['api_name']       
         | 
| 54 | 
            +
                    )
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    #Cuando es GPU, debe de restar segundos disponibles de HF 
         | 
| 57 | 
            +
                    herramientas.restaSegundosGPU(globales.work_cost)
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    print("Platillo generado:", platillo)
         | 
| 60 | 
            +
                    return result[0]
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                except Exception as e:     
         | 
| 63 | 
            +
                    print("Excepción: ", e)        
         | 
| 64 | 
            +
                    # Opción para regresar imagen genérica. (ya no porque se envía desde backend.)
         | 
| 65 | 
            +
                    # return "default.png"
         | 
| 66 | 
            +
                    raise HTTPException(
         | 
| 67 | 
            +
                        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
         | 
| 68 | 
            +
                        detail=e
         | 
| 69 | 
            +
                    )
         | 
| 70 | 
            +
             | 
| 71 | 
             
            def genera_platillo_gpu(platillo):
         | 
| 72 |  | 
| 73 | 
             
                prompt = globales.previo + platillo
         | 
    	
        herramientas.py
    CHANGED
    
    | @@ -1,197 +1,26 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
                 | 
| 17 | 
            -
                
         | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
                     | 
| 25 | 
            -
             | 
| 26 | 
            -
                 | 
| 27 | 
            -
                return conexion_firebase.obtenDato('nowme', servidor, 'segundos')
         | 
| 28 | 
            -
             | 
| 29 | 
            -
            def obtenSegundosDisponiblesInference(): 
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                # if esDiaSiguiente() == True:
         | 
| 32 | 
            -
                #     renuevaSegundosDisponibles()
         | 
| 33 | 
            -
                #     renuevaModeloPrincipal()
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                #Finalmente obten los segundos disponibles después de las operaciones.
         | 
| 36 | 
            -
                return conexion_firebase.obtenDato('nowme', servidor, 'inferencias')
         | 
| 37 | 
            -
                
         | 
| 38 | 
            -
                
         | 
| 39 | 
            -
            def renuevaSegundosDisponibles():
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                #Segundos de cuota total gratuita disponibles al momento.
         | 
| 42 | 
            -
                conexion_firebase.editaDato('nowme', servidor, 'segundos', globales.quota)
         | 
| 43 | 
            -
                renuevaTimestampActual()
         | 
| 44 | 
            -
             | 
| 45 | 
            -
            def renuevaTimestampActual(): 
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                timestamp_actual = imprimeTimeNowFixed16h()
         | 
| 48 | 
            -
                print("Ésto es el timestamp now de la renovación...: ", timestamp_actual)
         | 
| 49 | 
            -
                conexion_firebase.editaDato('nowme', servidor, 'timestamp', timestamp_actual)    
         | 
| 50 | 
            -
             | 
| 51 | 
            -
            def restaSegundosGPU(cuantos_segundos):
         | 
| 52 | 
            -
                """
         | 
| 53 | 
            -
                Lee el número de segundos disponibles,
         | 
| 54 | 
            -
                resta los segundos dados como parámetro y guarda el nuevo valor en el archivo.
         | 
| 55 | 
            -
                """
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                segundos_disponibles = obtenSegundosDisponibles()    
         | 
| 58 | 
            -
                print("Segundos disponibles: ", segundos_disponibles)
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                # Restar los segundos
         | 
| 61 | 
            -
                nuevos_segundos_disponibles = segundos_disponibles - cuantos_segundos
         | 
| 62 | 
            -
                print("Segundos disponibles ahora: ", nuevos_segundos_disponibles)
         | 
| 63 | 
            -
                conexion_firebase.editaDato('nowme', servidor, 'segundos', nuevos_segundos_disponibles)
         | 
| 64 | 
            -
             | 
| 65 | 
            -
            def restaSegundosInference(cuantos_segundos):
         | 
| 66 | 
            -
                """
         | 
| 67 | 
            -
                Lee el número de segundos disponibles desde seconds_available.txt,
         | 
| 68 | 
            -
                resta los segundos dados como parámetro y guarda el nuevo valor en el archivo.
         | 
| 69 | 
            -
                """
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                segundos_disponibles = obtenSegundosDisponiblesInference()    
         | 
| 72 | 
            -
                print("Segundos disponibles Inference: ", segundos_disponibles)
         | 
| 73 | 
            -
                
         | 
| 74 | 
            -
                # Restar los segundos
         | 
| 75 | 
            -
                nuevos_segundos_disponibles = segundos_disponibles - cuantos_segundos
         | 
| 76 | 
            -
                print("Segundos disponibles ahora en restaSegundosInference: ", nuevos_segundos_disponibles)
         | 
| 77 | 
            -
                conexion_firebase.editaDato('nowme', servidor, 'inferencias', nuevos_segundos_disponibles)    
         | 
| 78 | 
            -
             | 
| 79 | 
            -
            def modificaModeloActual(nuevo_modelo):
         | 
| 80 | 
            -
                """
         | 
| 81 | 
            -
                Actualiza el archivo archivos/modelo_actual.txt con el modelo funcional en caso de
         | 
| 82 | 
            -
                problemas con el actual.
         | 
| 83 | 
            -
                """
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                modelo_actual = conexion_firebase.obtenDato('nowme', servidor, 'modelo_actual')
         | 
| 86 | 
            -
                conexion_firebase.editaDato('nowme', servidor, 'modelo_actual', nuevo_modelo)
         | 
| 87 | 
            -
                print(f"Se actualizó el modelo actual: {modelo_actual} por {nuevo_modelo}.")
         | 
| 88 | 
            -
             | 
| 89 | 
            -
            def renuevaModeloPrincipal():
         | 
| 90 | 
            -
                #Obten el modelo principal (default).   
         | 
| 91 | 
            -
                modelo_principal = conexion_firebase.obtenDato('nowme', servidor, 'modelo_principal')
         | 
| 92 | 
            -
                #Asignalo como modelo actual.
         | 
| 93 | 
            -
                conexion_firebase.editaDato('nowme', servidor, 'modelo_actual', modelo_principal)
         | 
| 94 | 
            -
             | 
| 95 | 
            -
            def imprimeTimeNow(): 
         | 
| 96 | 
            -
                """
         | 
| 97 | 
            -
                Devuelve la fecha y hora actual en la zona horaria de la Ciudad de México (GMT-6).
         | 
| 98 | 
            -
                """
         | 
| 99 | 
            -
                # 1. Definir la zona horaria de la Ciudad de México
         | 
| 100 | 
            -
                # Puedes usar 'America/Mexico_City' para que pytz maneje el horario de verano automáticamente.
         | 
| 101 | 
            -
                mexico_city_tz = pytz.timezone('America/Mexico_City')
         | 
| 102 | 
            -
             | 
| 103 | 
            -
                # 2. Obtener la hora actual en UTC
         | 
| 104 | 
            -
                utc_now = datetime.now(pytz.utc)
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                # 3. Convertir la hora UTC a la zona horaria deseada
         | 
| 107 | 
            -
                mexico_city_now = utc_now.astimezone(mexico_city_tz)
         | 
| 108 | 
            -
             | 
| 109 | 
            -
                # 4. Formatear la fecha y hora
         | 
| 110 | 
            -
                # El formato que deseas es "YYYY-MM-DD HH:MM:SS"
         | 
| 111 | 
            -
                formatted_time = mexico_city_now.strftime("%Y-%m-%d %H:%M:%S")
         | 
| 112 | 
            -
             | 
| 113 | 
            -
                return formatted_time
         | 
| 114 | 
            -
             | 
| 115 | 
            -
            def imprimeTimeNowFixed16h():
         | 
| 116 | 
            -
                """
         | 
| 117 | 
            -
                Devuelve la fecha actual con la hora fijada a las 16:00:00 (4 PM)
         | 
| 118 | 
            -
                en la zona horaria de la Ciudad de México (GMT-6).
         | 
| 119 | 
            -
                """
         | 
| 120 | 
            -
                # 1. Definir la zona horaria de la Ciudad de México
         | 
| 121 | 
            -
                mexico_city_tz = pytz.timezone('America/Mexico_City')
         | 
| 122 | 
            -
             | 
| 123 | 
            -
                # 2. Obtener la fecha y hora actual en UTC
         | 
| 124 | 
            -
                utc_now = datetime.now(pytz.utc)
         | 
| 125 | 
            -
             | 
| 126 | 
            -
                # 3. Convertir la hora UTC a la zona horaria de la Ciudad de México
         | 
| 127 | 
            -
                #    Esto nos da la fecha correcta (año, mes, día) para esa zona.
         | 
| 128 | 
            -
                mexico_city_aware_dt = utc_now.astimezone(mexico_city_tz)
         | 
| 129 | 
            -
             | 
| 130 | 
            -
                # 4. Crear un nuevo objeto datetime con la fecha obtenida
         | 
| 131 | 
            -
                #    pero con la hora fijada a las 16:00:00
         | 
| 132 | 
            -
                fixed_time_dt = mexico_city_tz.localize(
         | 
| 133 | 
            -
                    datetime(
         | 
| 134 | 
            -
                        mexico_city_aware_dt.year,
         | 
| 135 | 
            -
                        mexico_city_aware_dt.month,
         | 
| 136 | 
            -
                        mexico_city_aware_dt.day,
         | 
| 137 | 
            -
                        16,  # Hora fijada a las 16 (4 PM)
         | 
| 138 | 
            -
                        0,   # Minutos fijados a 0
         | 
| 139 | 
            -
                        0    # Segundos fijados a 0
         | 
| 140 | 
            -
                    )
         | 
| 141 | 
            -
                )
         | 
| 142 | 
            -
                
         | 
| 143 | 
            -
                # 5. Formatear la fecha y hora
         | 
| 144 | 
            -
                formatted_time = fixed_time_dt.strftime("%Y-%m-%d %H:%M:%S")
         | 
| 145 | 
            -
             | 
| 146 | 
            -
                return formatted_time
         | 
| 147 | 
            -
             | 
| 148 | 
            -
            def esDiaSiguiente(): 
         | 
| 149 | 
            -
                """
         | 
| 150 | 
            -
                Compara dos timestamps Unix y devuelve True si el día de timestamp_actual
         | 
| 151 | 
            -
                es diferente al día de timestamp_registro.
         | 
| 152 | 
            -
             | 
| 153 | 
            -
                Args:
         | 
| 154 | 
            -
                    timestamp_registro (int): Timestamp Unix del registro original (en segundos).
         | 
| 155 | 
            -
                    timestamp_actual (int): Timestamp Unix actual (en segundos).
         | 
| 156 | 
            -
             | 
| 157 | 
            -
                Returns:
         | 
| 158 | 
            -
                    bool: True si el día de timestamp_actual es diferente al día de
         | 
| 159 | 
            -
                          timestamp_registro, False si es el mismo día.
         | 
| 160 | 
            -
                """
         | 
| 161 | 
            -
             | 
| 162 | 
            -
                #Obtiene el último registro de fecha de la base de firestore.
         | 
| 163 | 
            -
                fecha_registro_dt = obtenUltimoTimestamp()   
         | 
| 164 | 
            -
                
         | 
| 165 | 
            -
                print("Primero, el último timestamp obtenido de base es: ", fecha_registro_dt)
         | 
| 166 | 
            -
                print("Y su tipo es: ", type(fecha_registro_dt))
         | 
| 167 | 
            -
               
         | 
| 168 | 
            -
                #Timestamp actual
         | 
| 169 | 
            -
                fecha_actual_dt = imprimeTimeNow()
         | 
| 170 | 
            -
                print("Segundo, la fecha_actual_dt quedó como: ", fecha_actual_dt)
         | 
| 171 | 
            -
                print("Y su tipo es: ", type(fecha_actual_dt))
         | 
| 172 | 
            -
                
         | 
| 173 | 
            -
             | 
| 174 | 
            -
                formato = "%Y-%m-%d %H:%M:%S"
         | 
| 175 | 
            -
                datetime_obj_1 = datetime.strptime(fecha_registro_dt, formato)
         | 
| 176 | 
            -
                datetime_obj_2 = datetime.strptime(fecha_actual_dt, formato)   
         | 
| 177 | 
            -
                    
         | 
| 178 | 
            -
                # Extraer solo la fecha de los objetos datetime
         | 
| 179 | 
            -
                fecha_registro = datetime_obj_1.date()
         | 
| 180 | 
            -
                #print("Primera extracción: ", fecha_registro)
         | 
| 181 | 
            -
                fecha_actual = datetime_obj_2.date()
         | 
| 182 | 
            -
                #print("Segunda extracción: ", fecha_actual)    
         | 
| 183 | 
            -
                
         | 
| 184 | 
            -
             | 
| 185 | 
            -
                # Verificar si las fechas son diferentes
         | 
| 186 | 
            -
                resultado = fecha_actual > fecha_registro
         | 
| 187 | 
            -
                print("Resultado de resta de fechas: ", resultado)    
         | 
| 188 | 
            -
                
         | 
| 189 | 
            -
                return resultado
         | 
| 190 | 
            -
             | 
| 191 | 
            -
            def getFluxServer(): 
         | 
| 192 | 
            -
                print("In getFluxServer...")
         | 
| 193 | 
            -
                server_keys = list(globales.SERVER_NAMES.values())
         | 
| 194 | 
            -
                random_value = random.choice(server_keys)
         | 
| 195 | 
            -
                print("Random key: ", random_value)
         | 
| 196 | 
            -
                
         | 
| 197 | 
            -
                return random_value
         | 
|  | |
| 1 | 
            +
            #Herramientas Generales
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            def listaTextosExtraidos(result):
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                textos_extraidos = [] 
         | 
| 6 | 
            +
                print("Líneas encontradas con modelo IA:")
         | 
| 7 | 
            +
                for item in result:
         | 
| 8 | 
            +
                    texto = item[1][0] 
         | 
| 9 | 
            +
                    print(texto)
         | 
| 10 | 
            +
                    textos_extraidos.append(texto)
         | 
| 11 | 
            +
                return textos_extraidos
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            #Herramientas para DNI Panamá.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            def buscaIndexPalabra(arreglo, palabra):
         | 
| 16 | 
            +
                palabra_limpia = palabra.lower().replace(" ", "")
         | 
| 17 | 
            +
                for i, texto_limpio in enumerate(arreglo):        
         | 
| 18 | 
            +
                    if palabra_limpia in texto_limpio:
         | 
| 19 | 
            +
                        return i
         | 
| 20 | 
            +
                return 'error'
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            def buscarPatronCedula(lista_textos):    
         | 
| 23 | 
            +
                for i, texto in enumerate(lista_textos):
         | 
| 24 | 
            +
                    if texto and texto[0].isdigit() and '-' in texto:     
         | 
| 25 | 
            +
                        return i 
         | 
| 26 | 
            +
                return 'error' 
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
    	
        ia.py
    ADDED
    
    | @@ -0,0 +1,96 @@ | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 1 | 
            +
            import atexit
         | 
| 2 | 
            +
            import functools
         | 
| 3 | 
            +
            from queue import Queue
         | 
| 4 | 
            +
            from threading import Event, Thread
         | 
| 5 | 
            +
            from paddleocr import PaddleOCR
         | 
| 6 | 
            +
            import documentos
         | 
| 7 | 
            +
            import herramientas
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            LANG_CONFIG = {
         | 
| 10 | 
            +
                "ch": {"num_workers": 2},
         | 
| 11 | 
            +
                "en": {"num_workers": 2},
         | 
| 12 | 
            +
                "fr": {"num_workers": 1},
         | 
| 13 | 
            +
                "german": {"num_workers": 1},
         | 
| 14 | 
            +
                "korean": {"num_workers": 1},
         | 
| 15 | 
            +
                "japan": {"num_workers": 1},
         | 
| 16 | 
            +
            }
         | 
| 17 | 
            +
            CONCURRENCY_LIMIT = 8
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            class PaddleOCRModelManager(object):
         | 
| 20 | 
            +
                def __init__(self,
         | 
| 21 | 
            +
                             num_workers,
         | 
| 22 | 
            +
                             model_factory):
         | 
| 23 | 
            +
                    super().__init__()
         | 
| 24 | 
            +
                    self._model_factory = model_factory
         | 
| 25 | 
            +
                    self._queue = Queue()
         | 
| 26 | 
            +
                    self._workers = []
         | 
| 27 | 
            +
                    self._model_initialized_event = Event()
         | 
| 28 | 
            +
                    for _ in range(num_workers):
         | 
| 29 | 
            +
                        worker = Thread(target=self._worker, daemon=False)
         | 
| 30 | 
            +
                        worker.start()
         | 
| 31 | 
            +
                        self._model_initialized_event.wait()
         | 
| 32 | 
            +
                        self._model_initialized_event.clear()
         | 
| 33 | 
            +
                        self._workers.append(worker)
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def infer(self, *args, **kwargs):
         | 
| 36 | 
            +
                    # XXX: Should I use a more lightweight data structure, say, a future?
         | 
| 37 | 
            +
                    result_queue = Queue(maxsize=1)
         | 
| 38 | 
            +
                    self._queue.put((args, kwargs, result_queue))
         | 
| 39 | 
            +
                    success, payload = result_queue.get()
         | 
| 40 | 
            +
                    if success:
         | 
| 41 | 
            +
                        return payload
         | 
| 42 | 
            +
                    else:
         | 
| 43 | 
            +
                        raise payload
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def close(self):
         | 
| 46 | 
            +
                    for _ in self._workers:
         | 
| 47 | 
            +
                        self._queue.put(None)
         | 
| 48 | 
            +
                    for worker in self._workers:
         | 
| 49 | 
            +
                        worker.join()
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                def _worker(self):
         | 
| 52 | 
            +
                    model = self._model_factory()
         | 
| 53 | 
            +
                    self._model_initialized_event.set()
         | 
| 54 | 
            +
                    while True:
         | 
| 55 | 
            +
                        item = self._queue.get()
         | 
| 56 | 
            +
                        if item is None:
         | 
| 57 | 
            +
                            break
         | 
| 58 | 
            +
                        args, kwargs, result_queue = item
         | 
| 59 | 
            +
                        try:
         | 
| 60 | 
            +
                            result = model.ocr(*args, **kwargs)
         | 
| 61 | 
            +
                            result_queue.put((True, result))
         | 
| 62 | 
            +
                        except Exception as e:
         | 
| 63 | 
            +
                            result_queue.put((False, e))
         | 
| 64 | 
            +
                        finally:
         | 
| 65 | 
            +
                            self._queue.task_done()
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            def create_model(lang):
         | 
| 68 | 
            +
                return PaddleOCR(lang=lang, use_angle_cls=True, use_gpu=False)
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            model_managers = {}
         | 
| 71 | 
            +
            for lang, config in LANG_CONFIG.items():
         | 
| 72 | 
            +
                model_manager = PaddleOCRModelManager(config["num_workers"], functools.partial(create_model, lang=lang))
         | 
| 73 | 
            +
                model_managers[lang] = model_manager
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            def close_model_managers():
         | 
| 76 | 
            +
                for manager in model_managers.values():
         | 
| 77 | 
            +
                    manager.close()
         | 
| 78 | 
            +
             | 
| 79 | 
            +
            # XXX: Not sure if gradio allows adding custom teardown logic
         | 
| 80 | 
            +
            atexit.register(close_model_managers)
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            def inference(img, lang):
         | 
| 83 | 
            +
                ocr = model_managers[lang]
         | 
| 84 | 
            +
                result = ocr.infer(img, cls=True)[0]
         | 
| 85 | 
            +
                textos_extraidos = herramientas.listaTextosExtraidos(result)
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                #Campos DNI Panamá.
         | 
| 88 | 
            +
                nombre, apellido, identificacion = documentos.dni(textos_extraidos)    
         | 
| 89 | 
            +
              
         | 
| 90 | 
            +
                print(f"Hola: {nombre}, {apellido} con identificación: {identificacion}")
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                return {
         | 
| 93 | 
            +
                    "nombre": nombre,
         | 
| 94 | 
            +
                    "apellido": apellido,
         | 
| 95 | 
            +
                    "identificacion": identificacion
         | 
| 96 | 
            +
                }
         | 
    	
        obtenCampo.py
    ADDED
    
    | @@ -0,0 +1,12 @@ | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 1 | 
            +
            import herramientas
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            def Nombre(textos_extraidos, textos_extraidos_limpios):
         | 
| 4 | 
            +
                indice = herramientas.buscaIndexPalabra(textos_extraidos_limpios, 'usual')
         | 
| 5 | 
            +
                nombre = textos_extraidos[indice-2]    
         | 
| 6 | 
            +
                apellido = textos_extraidos[indice-1]
         | 
| 7 | 
            +
                return nombre, apellido
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            def Identificacion(textos_extraidos, textos_extraidos_limpios):   
         | 
| 10 | 
            +
               indice = herramientas.buscarPatronCedula(textos_extraidos_limpios)   
         | 
| 11 | 
            +
               identificacion = textos_extraidos[indice]
         | 
| 12 | 
            +
               return identificacion
         | 
    	
        requirements.txt
    CHANGED
    
    | @@ -4,4 +4,9 @@ huggingface_hub | |
| 4 | 
             
            gradio_client
         | 
| 5 | 
             
            Pillow
         | 
| 6 | 
             
            firebase_admin
         | 
| 7 | 
            -
            pytz
         | 
|  | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 4 | 
             
            gradio_client
         | 
| 5 | 
             
            Pillow
         | 
| 6 | 
             
            firebase_admin
         | 
| 7 | 
            +
            pytz
         | 
| 8 | 
            +
            #OCR
         | 
| 9 | 
            +
            Pillow
         | 
| 10 | 
            +
            requests
         | 
| 11 | 
            +
            paddlepaddle
         | 
| 12 | 
            +
            paddleocr==2.10.0
         |