Proyecto PokeQueue

Este proyecto implementa una arquitectura en Azure para la generacion de reportes de datos de Pokemon. Permite a los usuarios solicitar reportes con informacion basica (nombre, habilidades y estadisticas base) de los Pokemon de tipos especificos, los cuales son generados en formato CSV.

La arquitectura esta compuesta por una interfaz web, una API, una base de datos SQL, Azure Queue Storage, Azure Blob Storage y una Azure Function App. El flujo completo funciona de la siguiente manera: los usuarios realizan solicitudes a traves de la UI, la API registra cada peticion en la base de datos SQL y envia la solicitud al Azure Queue Storage. La Function App actua como procesador asincrono, consume los mensajes de la queue, realizando las peticiones correspondientes a la PokeAPI para recopilar la informacion solicitada, generando el reporte en formato CSV y finalmente, almacenandolo en Azure Blob Storage para su descarga desde la UI.

Arquitectura de la Solucion

Tecnologias Clave

Se utilizo NextJS con React para el desarollo de la interfaz web.
La API fue construida con Python con FastAPI.
Para la base de datos se utilizo Azure SQL Database.
Se utilizo Storage Account de Azure para el Queue Storage y Blob Storage.
La Function App fue desarrollada en Python
La definicion de la arquitectura en Azure se construyo utilizando Terraform.

Resumen de funcionalidades

El proyecto dado en clase ya tenia algunas caracteristicas iniciales implementadas, con mi compañero de equipo implementamos funcionalidades extras al proyecto.

La primera funcionalidad implementada fue la de eliminar los reportes, para ello modificamos la UI para agregar un boton de eliminado y agregamos la funcionalidad de eliminado en la API, para el borrado se creo un procedimiento almacenado en la base de datos para ejecutar la consulta DELETE, la API hace uso de este procedimiento almacenado obteniendo el ID de la solicitud a eliminar y a la vez se hizo uso del SDK de Azure Storage Blob para eliminar el archivo dentro del Blob Storage.

Luego enriquecimos la informacion del reporte agregando las estadisticas base y las habilidades de los Pokemon obtenidos, para ello se modifico la Function App para agregar una funcion que itera sobre la lista que se habia obtenido inicialmente y utilizando la URL de cada Pokemon, se accedio a los campos requeridos para el enriquecimiento del reporte, creando un nuevo diccionario con toda la informacion deseada, este nuevo diccionario es utilizado por la funcion para generar el CSV.

Por ultimo, se implemento la funcionalidad para el muestreo aleatorio, en esta funcionalidad el usuario ingresa un numero de maximos registros a obtener y de acuerdo al numero, el reporte selecciona aleatoriamente los Pokemon que se incluiran en el reporte. Para ello se modifico la UI para agregar un campo para ingresar el numero, y en la API se modifico la funcion de insertar una nueva solicitud para aceptar este nuevo parametro, asi mismo en la base de datos se altero la tabla para agregar la nueva columna. Luego en la Function App se modifico la funcion que obtiene los pokemon para aceptar este numero, con ello se selecciona aleatoriamente los pokemon obtenidos de acuerdo al numero del muestro o a la cantidad de pokemon disponibles.

Desafios y Soluciones

El desafio que nos enfrentamos en este proyecto fue para recolectar la informacion adicional de los reportes, ya que se estaba obteniendo solo nombre y una URL que contenia esta informacion adicional. La solucion fue implementar una funcion que hace el llamado a la PokeAPI con la URL que recolectamos en el primer llamado, crear la estructura de datos que contiene esta informacion y juntarla con la que ya se tenia del primer llamado. Esta estructura de datos combinada es la que luego obtiene la funcion de generar el archivo CSV.
Otro desafio fue al momento de realizar cambios en la arquitectura mediante Terraform, ya que al correr el comando para aplicar el cambio se borraron las variables de entorno ya configuradas. Esta fue una leccion aprendida de tener cuidado con ello, ya que la solucion fue volverlas a configurar. Aunque una mejor practica hubiera sido utilizar el bloque "lifecycle" con el atributo "ignore_changes" para evitar que ciertos cambios afecten los recursos ya creados, en este caso, las Web Apps.