1 / 1
Presentación
← Curso

AplicativoswebMódulo 4

Oscar Iván Vargas Pineda Docente
Cómo vamos a avanzar

Dos caminos hasta un enlace público

El objetivo es el mismo: que cualquiera abra tu trabajo desde un navegador, sin instalar nada. Cambia quién ejecuta el código, y de ahí se derivan todas las demás diferencias.

Ruta A · Streamlit

Tu Python se sigue ejecutando, pero en un servidor. El navegador solo muestra el resultado.

pandasmatplotlibseabornscikit-learn
  • Sigues escribiendo solo Python
  • Todo lo de los módulos 2 y 3 funciona igual
  • Puede leer datos vivos: Google Sheets, una base de datos
  • Se duerme si nadie la usa; tarda unos segundos en despertar

Ruta B · HTML + JS

No hay Python. El navegador ejecuta JavaScript sobre datos que exportaste antes.

HTMLCSSJavaScript
  • Instantánea y gratis para siempre
  • No se duerme nunca: son archivos, no un servidor
  • Aguanta cualquier cantidad de visitas
  • Los datos quedan congelados en el momento de exportar
La pregunta que decide: ¿los datos cambian después de publicar? Si sí, Ruta A. Si es una foto de un análisis terminado, Ruta B.
Ruta A · Streamlit

El camino completo

Cinco pasos desde el script que ya tienes hasta un enlace que puedes mandar por WhatsApp. Las siguientes diapositivas desarrollan cada uno.

1Tu scriptEl análisis de los módulos 2 y 3, ya funcionando en tu computador
2app.pyLe añades unas líneas de Streamlit: títulos, filtros, gráficas
3Probar en localstreamlit run app.py abre el navegador en tu máquina
4Subir a GitHubEl código y un requirements.txt con las librerías
5DesplegarStreamlit Cloud lee el repositorio y te da la URL pública

Lo que necesitas

cuenta de GitHubcuenta de Streamlit

Las dos gratuitas, y la de Streamlit se crea con la de GitHub.

Lo que produce

tu-app.streamlit.app

Un enlace público y permanente. Cada vez que hagas push, la app se actualiza sola.

Cuánto tarda

~20 minutos

La primera vez. Las siguientes, el despliegue es automático.

Ruta B · GitHub Pages

El camino completo

Aquí Python solo aparece al principio, para preparar los datos. Lo que se publica son archivos que el navegador entiende directamente.

1Exportar datosDesde pandas, a un archivo .json ligero
2Tres archivosindex.html, style.css y app.js
3Probar en localAbriendo index.html con doble clic
4Subir a GitHubLos archivos en la raíz del repositorio
5Activar PagesUn interruptor en Settings y te da la URL

Lo que necesitas

cuenta de GitHub

Solo una. No hace falta ningún servicio adicional.

Lo que produce

usuario.github.io/repo

Un sitio estático. Carga al instante y no caduca.

Quién escribe el JS

tu agente de IA

No vas a aprender JavaScript en este curso: se lo pides al agente y tú revisas que haga lo correcto.

Esta ruta no es Python, y está bien que lo sepas. La incluimos porque es la forma más barata y rápida de dejar algo publicado para siempre.
Ruta A · paso 1

Tu script, con interfaz

Streamlit no te obliga a reescribir nada. Tomas el script que ya tienes y le añades líneas st. donde quieras que aparezca algo en pantalla.

1 Lo que ya tenías

analisis.py
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("datos/ventas_empresa.csv")

g = (df.groupby("categoria_producto")["ventas_cop"]
       .sum().sort_values() / 1e6)

fig, ax = plt.subplots()
ax.barh(g.index, g.values)
plt.show()

2 Lo mismo, como app

app.py
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt

st.title("Panel de ventas 2025")

df = pd.read_csv("datos/ventas_empresa.csv")

# un filtro: el usuario elige la ciudad
ciudad = st.selectbox("Ciudad",
                      df["ciudad"].unique())
df = df[df["ciudad"] == ciudad]

st.metric("Ventas totales",
          f"${df['ventas_cop'].sum():,.0f}")

g = (df.groupby("categoria_producto")["ventas_cop"]
       .sum().sort_values() / 1e6)

fig, ax = plt.subplots()
ax.barh(g.index, g.values)
st.pyplot(fig)          # en vez de plt.show()

st.dataframe(df)        # la tabla, interactiva

Las que más vas a usar

st.title()st.selectbox()st.metric()st.pyplot()st.dataframe()
La idea clave: cada vez que el usuario mueve un filtro, Streamlit vuelve a ejecutar el archivo entero de arriba abajo. Por eso no necesitas aprender nada de programación de interfaces.
Ruta A · paso 2

Verlo en tu computador

Nunca despliegues algo que no has visto funcionar. Streamlit levanta un servidor en tu propia máquina y abre el navegador solo.

terminal
pip install streamlit

streamlit run app.py
  You can now view your Streamlit app in your browser.

  Local URL: http://localhost:8501
  Network URL: http://192.168.1.14:8501
Deja la terminal abierta: si la cierras, la app se apaga. Cada vez que guardes app.py, el navegador te ofrece recargar.

Las rutas cambian al desplegar

"datos/ventas.csv" funciona en tu máquina y también en el servidor solo si subes la carpeta datos al repositorio. Es el fallo número uno del primer despliegue.

Comprueba antes de subir

¿carga los datos?¿funcionan los filtros?¿se ven las gráficas?

Lo que falla en local va a fallar igual en internet, pero allí es mucho más difícil de diagnosticar.

Ruta A · paso 3

Subir el proyecto a GitHub

Streamlit Cloud no lee tu computador: lee un repositorio. Necesita el código, los datos y la lista de librerías.

1 Qué tiene que haber en el repositorio

estructura del proyecto
mi-panel-ventas/
├── app.py                 # la aplicación
├── requirements.txt       # las librerías
└── datos/
    └── ventas_empresa.csv # los datos
requirements.txt
streamlit
pandas
matplotlib
seaborn

2 Subirlo

terminal
git init
git add .
git commit -m "Panel de ventas"
git branch -M main
git remote add origin https://github.com/TU_USUARIO/mi-panel-ventas.git
git push -u origin main
requirements.txt no es opcional. Sin él, el servidor no sabe que necesita pandas y la app falla al arrancar con ModuleNotFoundError — el mismo error del Módulo 1.
Nunca subas contraseñas ni claves al repositorio: es público. Si tu app se conecta a Google Sheets o a una base de datos, esas credenciales van en el paso siguiente.
Ruta A · paso 4

Publicar en Streamlit Cloud

Es el paso más corto: conectas la cuenta de GitHub, señalas el repositorio y esperas un par de minutos.

Los clics, en orden

1 · Entra en share.streamlit.io con tu cuenta de GitHub
2 · New app
3 · Elige el repositorio, la rama main y el archivo app.py
4 · Deploy

Al terminar tendrás algo como mi-panel-ventas.streamlit.app. Ese enlace ya se puede compartir con quien sea.
A partir de ahora, cada git push actualiza la app sola. No hay que volver a desplegar.

! Si tu app usa credenciales

Settings → Secrets (en la web de Streamlit)
[gcp_service_account]
type = "service_account"
project_id = "mi-proyecto"
private_key = "-----BEGIN PRIVATE KEY-----\n..."
client_email = "app@mi-proyecto.iam.gserviceaccount.com"
app.py · cómo se leen
# en tu computador: desde un archivo local
# en el servidor: desde los Secrets
try:
    creds = Credentials.from_service_account_file(
        "credentials.json", scopes=SCOPES)
except FileNotFoundError:
    creds = Credentials.from_service_account_info(
        st.secrets["gcp_service_account"], scopes=SCOPES)

Así el mismo código funciona en local y desplegado, sin que la clave llegue nunca al repositorio.

Ruta B · paso 1

Por qué hace falta otro lenguaje

Un navegador solo entiende tres cosas: HTML, CSS y JavaScript. No hay Python. Por eso, para publicar sin servidor, hay que traducir.

HTML · el esqueleto

index.html

Qué elementos hay: títulos, un menú desplegable, el hueco de la gráfica, la tabla.

CSS · el aspecto

style.css

Colores, tamaños, espaciados. Es lo mismo que hace el diseño de estas diapositivas.

JavaScript · el comportamiento

app.js

Lo que pandas hacía: filtrar, agrupar, sumar. Y dibujar la gráfica cuando cambia el filtro.

No vas a escribirlo tú

Le pasas al agente tu script de Python y le dices: "conviérteme esto en una página con HTML, CSS y JavaScript, sin librerías externas". Tu trabajo es revisar que los números coincidan con los de tu análisis.

Lo que se pierde

scikit-learn, statsmodels y cualquier cálculo pesado no existen en el navegador. Si tu app necesita entrenar un modelo, esta ruta no sirve: usa la A.

Ruta B · paso 2

Congelar los datos en un archivo

JavaScript no puede abrir tu Excel. El puente es JSON: un formato de texto que el navegador lee de forma nativa, y que pandas exporta en una línea.

1 Exportar desde Python

preparar_datos.py
import pandas as pd
from pathlib import Path

df = pd.read_csv("datos/ventas_empresa.csv")

# solo las columnas que la página va a usar
df = df[["fecha", "ciudad", "categoria_producto",
         "unidades", "ventas_cop"]]

df.to_json("datos.json", orient="records",
           force_ascii=False)
force_ascii=False conserva las tildes. Sin él, Bogotá se convierte en Bogot\u00e1.

2 Cómo queda el archivo

datos.json
[
  {"fecha": "2025-01-06", "ciudad": "Armenia",
   "categoria_producto": "Papelería y consumibles",
   "unidades": 9, "ventas_cop": 157460},
  {"fecha": "2025-01-07", "ciudad": "Envigado",
   "categoria_producto": "Muebles y oficina",
   "unidades": 5, "ventas_cop": 2101320}
]
¿Te suena? Es exactamente una lista de diccionarios — lo que viste al final del capítulo de diccionarios del Módulo 1.
Ruta B · paso 3

HTML, CSS y JS en la misma carpeta

Con los datos ya en JSON, la página es un esqueleto que los lee y los pinta. Así se ve la estructura mínima.

estructura
mi-panel/
├── index.html
├── style.css
├── app.js
└── datos.json
index.html
<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <title>Panel de ventas</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>Panel de ventas 2025</h1>
  <select id="ciudad"></select>
  <p id="total"></p>
  <canvas id="grafica"></canvas>
  <script src="app.js"></script>
</body>
</html>
app.js · lo que hacía pandas
// cargar el JSON
const datos = await fetch("datos.json")
                    .then(r => r.json());

// filtrar  ->  df[df.ciudad == x]
const filtrados = datos.filter(
  d => d.ciudad === ciudadElegida);

// sumar    ->  df["ventas_cop"].sum()
const total = filtrados.reduce(
  (a, d) => a + d.ventas_cop, 0);

document.getElementById("total").textContent =
  "Ventas: $" + total.toLocaleString("es-CO");
.filter() es el df[df.col == x] de pandas y .reduce() es el .sum(). Cambia la sintaxis, no la idea.
Ruta B · paso 4

Publicar en GitHub Pages

GitHub puede servir cualquier repositorio como si fuera un sitio web. Es un interruptor, y es gratis para siempre.

terminal
git init
git add .
git commit -m "Panel de ventas"
git branch -M main
git remote add origin https://github.com/TU_USUARIO/mi-panel.git
git push -u origin main

Los clics, en orden

1 · En el repositorio, pestaña Settings
2 · Menú lateral, Pages
3 · En Source, elige la rama main y la carpeta / (root)
4 · Save

Tu dirección

En un par de minutos estará en:
https://TU_USUARIO.github.io/mi-panel/

El archivo se debe llamar index.html

Si lo llamas panel.html, la dirección raíz dará error 404. GitHub Pages busca index.html por convención.

Todo lo que subas es público, incluido datos.json. No publiques datos personales ni confidenciales.
Para decidir

¿Cuál uso para mi proyecto?

No hay una mejor: hay una adecuada para cada caso. Estas cinco preguntas resuelven casi siempre la duda.

Elige Streamlit si…

  • Los datos cambian y la app debe leerlos actualizados
  • Necesitas modelos o cálculos pesados
  • El usuario va a subir su propio archivo
  • Quieres seguir escribiendo solo Python
  • Da igual que tarde unos segundos en despertar

Elige GitHub Pages si…

  • El análisis ya está terminado: es una foto
  • Quieres que cargue al instante
  • Lo van a ver muchas personas
  • Es tu portafolio y debe estar siempre disponible
  • No te importa reexportar los datos cuando cambien

En la práctica mucha gente hace las dos: el panel interactivo en Streamlit para trabajar, y una versión estática en GitHub Pages como carta de presentación.

Fin del módulo 4

Tu trabajo ya tiene un enlace

Empezaste sin saber qué era una variable. Ahora cargas datos reales, los analizas, los grafícas y los publicas en internet para que cualquiera los use.

Módulo 1

fundamentos de Python y agentes de IA

Módulo 2

cargar, limpiar y exportar datos

Módulo 3

gráficas que se entienden

Módulo 4

tu aplicativo publicado

Lo que te llevas de verdad: no es Python. Es saber descomponer un problema, dirigir a un agente y verificar lo que te entrega. Eso se transfiere a cualquier herramienta que salga el año que viene.

Trabajo Científico · @TCientifico · Democratizando la ciencia de datos