Etiqueta: App Flask

  • AdventureWorks: Custom Full-Stack Data & Analytics Platform

    Este proyecto documenta el diseño e implementación de una plataforma de datos full-stack y de código abierto, desarrollada para reemplazar una infraestructura analítica comercial costosa y rígida. A través de la migración de la base de datos relacional de AdventureWorks desde SQL Server hacia PostgreSQL, el desarrollo de pipelines ETL modulares en Python y la integración de modelos predictivos de Machine Learning, se transformó un sistema de reportes tradicional en un motor independiente y escalable, centralizado en una aplicación web interactiva con Flask y Docker.

    El Desafío del Negocio (The Problem Statement)

    AdventureWorks Inc. gestionaba su inteligencia de negocio y reportería a través de una suite de analítica comercial propietaria y tradicional basada en licencias de software cerrado. Al escalar la organización, el equipo se enfrentó a tres bloqueos críticos:

    1. Escala Exponencial de Costos por Licenciamiento: El modelo de cobro por usuario o por núcleo se volvió financieramente insostenible ante la creciente demanda de acceso concurrente por parte de Ventas, RRHH, Producción y Compras.
    2. Limitaciones de Integración con Data Science y ML: El ecosistema cerrado dificultaba acoplar modelos avanzados de Machine Learning (como forecasting de series temporales con Prophet o clasificación con XGBoost) en los flujos de datos sin recurrir a costosos módulos de IA adicionales.
    3. Dependencia del Proveedor (Vendor Lock-in): La falta de control sobre el procesamiento impedía personalizar la interfaz a nivel corporativo y flexibilizar el despliegue en infraestructura propia.

    Nuestra Solución:

    Arquitectura Full-Stack Data de Código Abierto. Diseñamos y desarrollamos una plataforma web propietaria, independiente y end-to-end que migró la infraestructura y transformó los reportes rígidos del pasado en un motor analítico y predictivo centralizado:

    Pipeline del proyecto

    Fase 1: Ingesta, Auditoría y Exploración Profunda (OLTP)

    Objetivo: Comprender las reglas y la estructura exacta del negocio para mitigar sesgos en las etapas de transformación y modelado.

    • Aprovisionamiento: Extracción y restauración del backup relacional nativo (.bak) de AdventureWorks 2022 en SQL Server.
    • Data Quality & Perfilado Inicial: Auditoría técnica mediante scripts SQL de exploración individual para cada una de las 18 tablas relevantes, documentando rangos de fechas, valores únicos y patrones de columnas clave.
    • Garantía de Integridad: Identificación exhaustiva de claves primarias y foráneas reales, consolidando las dinámicas operacionales en un Diccionario de Datos maestro y un diagrama relacional completo.

    Fase 2: Diseño del Modelo Analítico Relacional y Requerimientos

    Objetivo: Traducir los objetivos corporativos en una arquitectura de datos técnica limpia y estructurada.

    • Definición de Granularidad: Establecimiento preciso del nivel de detalle de las entidades operativas (ej. Ventas por línea de pedido, Inventarios por snapshots de producto/almacén y Finanzas por periodo contable).
    • Mapeo de KPIs: Selección de indicadores estratégicos para una visión de 360° (Sales Amount, Total Product Cost, Profit, Margen %, Tendencias YoY/MoM, Ticket Promedio y Alertas de Stock).
    • Gobernanza Técnica: Generación de un Documento de Requerimientos Funcionales como base para validar formalmente las necesidades lógicas con cada área antes de iniciar el código.

    Fase 3: Extracción y Preparación mediante Vistas SQL

    Objetivo: Proveer una capa de datos purificada, segura y optimizada desde la base de origen.

    • Desacoplamiento Estructural: Creación de vistas en SQL Server diseñadas según los requerimientos funcionales para pre-estructurar el set de datos.
    • Seguridad y Anonimización: Selección rigurosa de atributos descriptivos y demográficos para segmentación, aplicando políticas de privacidad al anonimizar o remover datos sensibles de clientes.
    • Cómputo en Base de Datos: Implementación de transformaciones básicas directamente en el motor de origen (como cálculo dinámico de edad y unificación de jerarquías de productos) para aligerar las fases posteriores de procesamiento en Python.

    Fase 4: Migración Heterogénea de Bases de Datos

    Objetivo: Romper la dependencia con el proveedor tradicional migrando el núcleo de la compañía a un motor Open-Source (PostgreSQL) sin alterar su estructura relacional original.

    • Schema Mapping: Traducción de tipos de datos, restricciones e incompatibilidades entre SQL Server y PostgreSQL mediante el uso de Python.
    • Pipelines de Ingesta: Diseño de scripts de migración progresiva y por lotes para mover de manera controlada el modelo relacional puro, asegurando consistencia matemática absoluta entre ambos motores.
    • Stack Principal: SQL Server, PostgreSQL, SQLAlchemy, PyODBC, Psycopg2 y Pandas.

    Fase 5: Pipeline ETL y Automatización con Python

    Objetivo: Construir un pipeline reproducible con un solo comando que extraiga, limpie y guarde datos curados listos para consumo concurrente.

    • Pipeline Modular (Jupyter/Scripts): Desarrollo de notebooks de experimentación consolidados posteriormente en un script ejecutable (etl_pipeline.py) alimentado por un archivo central de configuración (config.py).
    • Feature Engineering & Limpieza: Tratamiento automatizado de valores nulos mediante reglas específicas según la columna, conversión estructurada de tipos/fechas y eliminación de duplicados mediante funciones reutilizables (CheckData).
    • Persistencia Eficiente (Formatos de Alto Rendimiento): Exportación de datasets limpios y validados a disco en formato Parquet (para optimizar espacio y velocidad de lectura).
    • Trazabilidad y Auditoría: Integración de logs detallados de seguimiento en consola para registrar el éxito/fallo del pipeline y mantenimiento de un registro maestro de control (datasets_control.xlsx) con métricas de filas y columnas procesadas.

    Fase 6: Optimización de la Capa Analítica en PostgreSQL

    Objetivo: Centralizar la lógica analítica pesada dentro de PostgreSQL para mitigar la carga computacional en el backend de la aplicación.

    • Modelado Lógico: Configuración de Vistas (Views) enriquecidas y almacenamiento indexado en PostgreSQL directamente sobre las tablas migradas.
    • Agregación Avanzada: Construcción de consultas complejas diseñadas para unificar la información dispersa de las áreas de Sales, HR, Product Performance, Supply Chain y Customer Analytics en estructuras consolidadas.

    Fase 7: Backend Analítico y Arquitectura de Software

    Objetivo: Construir la capa lógica del servidor encargada de procesar peticiones y unificar los datos analíticos de la empresa.

    • Backend Engineering: Desarrollo de una aplicación web robusta en Python utilizando Flask, estructurada de forma modular mediante Blueprints para segmentar los servicios de cada departamento de la compañía.
    • Persistencia Dinámica y APIs: Conexión interactiva a PostgreSQL para leer de forma nativa los archivos estructurados y las vistas optimizadas, garantizando tiempos mínimos de respuesta del servidor (latencia en milisegundos).

    Fase 8: Pipeline de Machine Learning y Analítica Predictiva

    Objetivo: Escalar la plataforma hacia la analítica predictiva, dotando al sistema de la capacidad de anticipar eventos críticos de negocio.

    • Modelado de Inteligencia Artificial: Diseño e implementación de modelos supervisados y de análisis temporal utilizando Scikit-Learn, XGBoost y Prophet.
    • Casos de Uso Operacionales:
      • Forecasting de Ventas: Modelos de series de tiempo para proyectar la demanda mensual e ingresos.
      • Clasificación de Churn: Modelos predictivos para calcular la probabilidad de abandono de clientes recurrentes.
      • Optimización de Cadena de Suministro: Predicción de quiebres de stock basándose en flujos históricos de inventario.
    • Inferencia en Producción: Creación de un script automatizado para la extracción de features, reentrenamiento de modelos y serialización de artefactos (.pkl / ONNX), consumidos directamente por la API de Flask para generar predicciones en tiempo real. [1]

    Fase 9: Visualización de Datos e Interfaces de Usuario (Frontend)

    Objetivo: Democratizar los insights corporativos permitiendo a la mesa directiva evaluar el rendimiento histórico y forecast predictivos en una sola pantalla unificada.

    • Frontend Interactivo: Creación de una interfaz web multipágina y responsive codificada con Plotly y Flask, reemplazando por completo los visualizadores de la suite comercial rígida.
    • Dashboards Ejecutivos Diseñados: Executive Overview, Sales Intelligence, HR Analytics, Product Performance y Geographic Insights.
    • Capa Semántica Unificada: Ocultamiento de columnas técnicas y exposición directa al usuario de medidas avanzadas de KPIs históricos calculados en base de datos junto a las proyecciones dinámicas estimadas por los modelos de Machine Learning.

    Fase 10: Despliegue en Producción y DevOps (MLOps)

    Objetivo: Publicar el sistema bajo una infraestructura escalable, segura y con costos de mantenimiento fijos, logrando la independencia total del negocio.

    • Infraestructura Cloud: Aprovisionamiento, hardening y configuración de políticas de seguridad en un Servidor Virtual Privado (VPS) con Ubuntu Server.
    • Contenerización Completa: Aislamiento de entornos y servicios (PostgreSQL, la aplicación Flask con sus pipelines de ML, las dependencias de Python y los servidores web) mediante Docker y Docker Compose.
    • Arquitectura de Producción: Implementación del servidor WSGI Gunicorn acoplado a Nginx como proxy inverso, garantizando la gestión eficiente de peticiones, compresión de assets, balanceo de carga básico y cifrado SSL.

    Ecosistema Tecnológico (Tech Stack)

    CategoríaTecnologías ClavePropósito en el Proyecto
    LenguajesPython (v3.11+), SQL (T-SQL / PL-pgSQL), HTML5/CSS3Procesamiento central, consultas optimizadas e interfaz nativa.
    Bases de DatosSQL Server , PostgreSQLMigración heterogénea desde el motor origen tradicional al destino Open-Source.
    Data Engineering & ETLPandas, SQLAlchemy, PyODBC, Psycopg2, ParquetScripting modular, mapeo de esquemas y persistencia de alto rendimiento.
    Data Science & MLXGBoost, Prophet (Meta), Scikit-Learn, ONNX / PickleModelos predictivos de series temporales, clasificación de churn e inferencia.
    Backend & APIsFlask, Flask Blueprints, GunicornArquitectura de software modular para servir datos y predicciones en tiempo real.
    Frontend & UXPlotly, Dash / Custom ComponentsVisualizaciones interactivas multipágina y dashboards corporativos 360°.
    DevOps & MLOpsDocker, Docker Compose, Nginx, Ubuntu Server (VPS), SSLContenerización multi-servicio, proxy inverso, seguridad y despliegue en la nube.

    Infografía de pipeline y arquitectura tecnológica

  • Dockerizar una app Flask para producción

    Construyendo aplicaciones analíticas portables con DashForge

    Las aplicaciones desarrolladas con Flask son extremadamente flexibles para crear dashboards, plataformas analíticas y sistemas de machine learning interactivos. Sin embargo, cuando el proyecto crece y empieza a desplegarse en servidores reales, surge un problema importante: el entorno.

    Distintas versiones de Python, conflictos entre librerías, dependencias del sistema operativo o diferencias entre equipos pueden hacer que una aplicación funcione correctamente en desarrollo pero falle en producción.

    Docker resuelve este problema encapsulando toda la aplicación dentro de un contenedor reproducible. El resultado es un entorno completamente aislado que puede ejecutarse exactamente igual en cualquier servidor compatible con Docker.

    En este tutorial vamos a dockerizar una aplicación Flask desarrollada con DashForge utilizando una arquitectura preparada para producción.

    Docker permite empaquetar una aplicación junto con todas sus dependencias. Todo queda integrado en una única imagen portable. Esto aporta ventajas muy importantes para aplicaciones analíticas:

    • despliegues reproducibles
    • aislamiento entre proyectos
    • facilidad para escalar aplicaciones
    • despliegues automáticos
    • ejecución bajo demanda
    • compatibilidad entre servidores
    • simplificación del entorno de producción

    En el caso de DashForge, Docker permite convertir cada dashboard o aplicación analítica en una unidad independiente que puede iniciarse o detenerse dinámicamente desde un portal central.

    Instalar docker

    Linux

    Para instalar en sistemas Debian sigue las siguientes instrucciones :

    # Descarga la lista actualizada de los paquetes disponibles en los servidores de Linux
    sudo apt update
    
    # Intalar las dependencias
    sudo apt install -y ca-certificates curl gnupg
    
    # Añadir clave oficial de Docker
    sudo install -m 0755 -d /etc/apt/keyrings
    
    # Descargar y registrar de forma segura la clave pública oficial de Docker en tu sistema
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
    sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    
    # Dar permisos de lectura a todos los usuarios sobre la clave de seguridad de Docker
    sudo chmod a+r /etc/apt/keyrings/docker.gpg

    Añadir el repositorio Docker

    echo \
      "deb [arch=$(dpkg --print-architecture) \
      signed-by=/etc/apt/keyrings/docker.gpg] \
      https://download.docker.com/linux/ubuntu \
      $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
      sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    Actualizar los índices e instalar Docker

    sudo apt update
    
    sudo apt install -y \
        docker-ce \
        docker-ce-cli \
        containerd.io \
        docker-buildx-plugin \
        docker-compose-plugin

    Permitir utilizar Docker sin sudo

    sudo usermod -aG docker $USER
    
    # reinicia seccion ssh
    exit

    Verificar la instalación

    docker --version
    
    # Probar Docker
    docker ps
    
    # verificar servicio
    sudo systemctl status docker

    Windows

    Lo primero, instalar Docker en tu sistema: https://www.docker.com/products/docker-desktop/

    Una vez instalado, hay que reiniciar el sistema. Docker instala servicios, WSL, variables y el daemon. Sigue las instrucciones de la aplicación; quizás sea necesario actualizar WSL, Docker Desktop normalmente guía todo automáticamente.

    Verifica la instalación de Docker y su daemon, PowerShell ejecuta:

    # Verifica la instalacion de docker
    docker --version
    
    # Verifica que el daemon este funcionando
    docker ps
    

    Preparar el proyecto Flask para Docker

    Antes de dockerizar la aplicación, es recomendable mantener una estructura organizada. Una aplicación Flask típica preparada para Docker podría tener esta estructura:

    DashForge/
    
    ├── app/
    ├── static/
    ├── templates/
    ├── requirements.txt
    ├── run.py
    ├── Dockerfile
    ├── .dockerignore
    └── gunicorn.conf.py

    Preparando las dependencias del proyecto

    Docker necesita conocer todas las librerías utilizadas por la aplicación para poder instalarlas dentro del contenedor. La forma estándar de hacerlo es mediante un archivo requirements.txt. Este archivo incluirá todas las librerías necesarias para ejecutar la aplicación.

    Al usar este comando, ten en cuenta que exporta todo, incluyendo paquetes del sistema Windows que pueden impedir crear la imagen Docker al tratar de instalar paquetes de Windows en WLS (Subsistema de Linux para Windows). Una vez ejecutado el código revisa el fichero y elimina archivos como pywin32, pywinpty o
    winshell.

    pip freeze > requirements.txt

    Excluyendo archivos innecesarios con .dockerignore

    Cuando Docker construye una imagen, copia el contenido del proyecto al contenedor. Sin embargo, muchos archivos no deben incluirse:

    • entornos virtuales
    • cachés
    • configuraciones del editor
    • repositorios Git
    • logs

    Para evitarlo se utiliza un archivo /.dockerignore.

    __pycache__/
    *.pyc
    
    .venv/
    venv/
    
    .git/
    .vscode/
    .idea/
    
    .env
    *.log
    
    .ipynb_checkpoints/

    Instalar Gunicorn

    Instalamos Gunicorn dentro del entorno virtual y lo agregamos a las dependencias:

    pip install gunicorn
    pip show gunicorn

    Configurar Gunicorn creando el archivo: /gunicorn.conf.py. Esta configuración es suficiente para la mayoría de los dashboards analíticos pequeños y medianos.

    bind = "0.0.0.0:5000"
    
    workers = 2
    
    threads = 2
    
    timeout = 120
    
    worker_class = "gthread"

    Creando el Dockerfile

    El archivo más importante del proceso es el /Dockerfile. Aquí se define cómo construir el contenedor.

    FROM python:3.13-slim
    
    ENV PYTHONDONTWRITEBYTECODE=1
    ENV PYTHONUNBUFFERED=1
    
    WORKDIR /app
    
    COPY requirements.txt .
    
    RUN pip install --no-cache-dir -r requirements.txt
    
    RUN apt-get update && apt-get install -y curl
    
    COPY . .
    
    EXPOSE 5000
    
    HEALTHCHECK CMD curl --fail http://localhost:5000 || exit 1
    
    CMD ["gunicorn", "-c", "gunicorn.conf.py", "run:app"]
    

    Entendiendo cada sección del Dockerfile

    • FROM python:3.13-slim: La aplicación se construirá sobre una imagen ligera de Python. La versión slim reduce considerablemente el tamaño final del contenedor.
    • ENV PYTHONDONTWRITEBYTECODE=1: Evitan generar archivos .pyc, mejoran el comportamiento del contenedor en producción.
    • ENV PYTHONUNBUFFERED=1: fuerzan salida inmediata de logs.
    • WORKDIR /app: Define el directorio interno donde vivirá la aplicación.
    • RUN pip install : instala las librerías listadas en requirements.txt.
    • RUN apt-get ... : instalar curl para healthcheck.
    • COPY ... : Copia el resto del proyecto al contenedor.
    • EXPOSE 5000: Indica que Flask/Gunicorn utilizará el puerto 5000.
    • HEALTHCHECK CMD curl: añadir comprobaciones automáticas de salud de los contenedores.
    • CMD : inicia la aplicación utilizando Gunicorn.

    Construyendo la imagen Docker

    Una vez preparados todos los archivos, ya podemos construir la imagen. En Powershell y desde la raíz del proyecto ejecutamos:

    docker build -t dashforge-spacex .

    Docker empezará a:

    1. descargar la imagen base
    2. instalar dependencias
    3. copiar el proyecto
    4. construir la imagen final
    • docker build: Es el comando principal que le ordena a Docker empaquetar tu aplicación, sus dependencias (como Python, Pandas, Scikit-Learn) y el sistema operativo base en una sola imagen aislada.
    • -t dashforge-spacex (Tag): Asigna un nombre y una etiqueta personalizada a la imagen que estás creando. El nombre que elijas aquí (dashforge-spacex) es la referencia exacta que usarás después para arrancar el contenedor con el comando docker run.
    • . (Punto final): Indica el contexto de construcción, diciéndole a Docker que busque el archivo llamado Dockerfile en el directorio actual.

    Ejecutar el contenedor

    Cuando la imagen termina de construirse, podemos iniciar la aplicación:

    docker run -d -p 5010:5000 --name dashforge-spacex dashforge-spacex
    • docker run -d : Esto crea un contenedor en segundo plano -d (Detached).
    • -p 5000:5000 (Publish / Ports): Conecta un puerto de tu computadora real (Anfitrión) con un puerto dentro del contenedor (Contenedor) siguiendo la estructura -p puerto_externo:puerto_interno.
    • Primer 5010 (Externo): El puerto de tu máquina real. Podrás abrir tu navegador web e ingresar a http://localhost:5000 para ver tu app.
    • Segundo 5000 (Interno): El puerto donde tu servidor (como Flask, Dash o FastAPI) está escuchando dentro del entorno cerrado del contenedor.
    • --name dashforge-spacex: Asigna un nombre personalizado e identificable a este contenedor específico.
    • dashforge-spacex (Al final): Es el nombre de la imagen de Docker de origen que vas a utilizar como plantilla para construir este contenedor. Debe coincidir exactamente con el nombre de la imagen que creaste previamente con el comando docker build.

    Gestionando contenedores Docker

    Docker incluye comandos para administrar los contenedores.

    # Ver dontenedores activos
    docker ps
    
    # Detener un contendor
    docker stop dashforge-spacex
    
    # Eliminar un contenedor
    docker rm dashforge-spacex
    
    # Eliminar una imagen de docker
    docker rmi dashforge-spacex
    
    

    Preparando DashForge para despliegues dinámicos

    Una de las ventajas más potentes de Docker es que cada dashboard puede ejecutarse como un contenedor independiente. Esto permite construir una arquitectura bajo demanda:

    • El portal principal permanece activo
    • Las aplicaciones solo se inician cuando un usuario las solicita
    • Los contenedores pueden apagarse automáticamente tras un periodo de inactividad

    Cada proyecto puede ejecutarse aislado, con sus propias dependencias, sus modelos ML y su configuración independiente. Esta arquitectura escala muchísimo mejor que mantener decenas de aplicaciones Flask activas permanentemente.