Las librerías de Python más usadas, con ejemplos que funcionan

Portada: las librerías de Python más usadas, con el logotipo de Python y los nombres de diez librerías: requests, tqdm, Pillow, NumPy, pandas, Matplotlib, Beautiful Soup, SQLAlchemy, FastAPI y pytest

Python trae mucho de serie, pero buena parte de lo que se hace con él a diario se apoya en librerías externas. Estas son las que más se usan, agrupadas por tarea y cada una con un ejemplo corto que puedes copiar y ejecutar.

Cómo instalarlas

Lo recomendable es instalar cada proyecto en su propio entorno virtual, para que las versiones de un proyecto no choquen con las de otro:

python -m venv venv
source venv/bin/activate        # en Windows: venv\Scripts\activate
pip install requests tqdm pillow numpy pandas matplotlib beautifulsoup4 sqlalchemy fastapi httpx2 pytest

Ten en cuenta que el nombre del paquete no siempre coincide con el del import: se instala pillow y se importa PIL, se instala beautifulsoup4 y se importa bs4.

Para…LibreríaVersión probada
Peticiones HTTPrequests2.34.2
Barras de progresotqdm4.70.1
ImágenesPillow12.3.0
Cálculo numéricoNumPy2.5.3
Tablas de datospandas3.0.6
GráficasMatplotlib3.11.2
Extraer datos de HTMLBeautiful Soup4.15.0
Bases de datosSQLAlchemy2.1.4
APIs webFastAPI0.143.0
Pruebaspytest9.1.1

requests: peticiones HTTP

import requests

r = requests.get("https://httpbin.org/get", params={"lenguaje": "python"}, timeout=10)
print(r.status_code, r.headers["Content-Type"])
print(r.json()["args"])

r = requests.post("https://httpbin.org/post", json={"sitio": "decodigo.com"}, timeout=10)
print(r.json()["json"])
salida200 application/json
{'lenguaje': 'python'}
{'sitio': 'decodigo.com'}

Con params se arma la cadena de consulta, con json= se envía un cuerpo JSON con su cabecera, y r.json() decodifica la respuesta. Pon siempre un timeout: sin él, una petición a un servidor que no responde puede quedarse esperando indefinidamente. Si solo necesitas algo puntual y no quieres dependencias, la biblioteca estándar también lo hace; lo vemos en peticiones HTTP sin dependencias.

tqdm: barras de progreso

from time import sleep
from tqdm import tqdm

total = 0
for n in tqdm(range(50), desc="Procesando", ncols=70):
    total += n
    sleep(0.02)
print("suma:", total)
salida, última línea de la barraProcesando: 100%|█████████████████████| 50/50 [00:01<00:00, 49.11it/s]
suma: 1225

Basta con envolver el iterable en tqdm(). La barra se va redibujando en la misma línea y muestra el avance, la velocidad y el tiempo que falta. Es muy útil en procesos largos, porque deja ver enseguida si el trabajo avanza o se ha atascado.

Pillow: imágenes

from PIL import Image, ImageDraw

img = Image.new("RGB", (800, 400), "#1e64af")
ImageDraw.Draw(img).rectangle([40, 40, 760, 360], outline="white", width=8)
img.save("original.png")

copia = Image.open("original.png")
copia.thumbnail((200, 200))
copia.save("miniatura.png")
print(Image.open("original.png").size, "->", Image.open("miniatura.png").size)
salida(800, 400) -> (200, 100)

thumbnail reduce la imagen para que quepa en la caja que le das (200×200), pero conserva la proporción: por eso queda en 200×100 y no se deforma. Pillow abre y guarda los formatos habituales (PNG, JPEG, WebP, GIF…) y sirve para recortar, rotar, dibujar o cambiar el formato por lotes.

NumPy y pandas: datos

import numpy as np
import pandas as pd

temps = np.array([18.5, 21.0, 24.3, 19.8, 22.1])
print("media:", temps.mean().round(2), "máxima:", temps.max())
print(temps * 9 / 5 + 32)

ventas = pd.DataFrame({
    "lenguaje": ["Python", "Java", "Python", "Go", "Java", "Python"],
    "visitas": [120, 80, 150, 40, 95, 130],
})
print(ventas.groupby("lenguaje")["visitas"].agg(["count", "sum", "mean"]).sort_values("sum", ascending=False))
salidamedia: 21.14 máxima: 24.3
[65.3  69.8  75.74 67.64 71.78]
          count  sum        mean
lenguaje
Python        3  400  133.333333
Java          2  175   87.500000
Go            1   40   40.000000

NumPy opera sobre arreglos completos de una vez: temps * 9 / 5 + 32 convierte las cinco temperaturas sin escribir ningún bucle, y además mucho más rápido que un bucle en Python. pandas se apoya en NumPy para trabajar con tablas: aquí agrupa por lenguaje y calcula el número de filas, la suma y la media de cada grupo en una sola línea. Si trabajas con archivos muy grandes, merece la pena mirar también Polars, una alternativa más reciente y muy rápida.

Matplotlib: gráficas

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

lenguajes = ["Python", "Java", "Go", "Rust"]
visitas = [400, 175, 40, 65]

fig, ax = plt.subplots(figsize=(8, 4.2))
ax.bar(lenguajes, visitas, color="#1e64af")
ax.set_title("Visitas por lenguaje")
ax.set_ylabel("visitas")
fig.tight_layout()
fig.savefig("grafica.png", dpi=150)
print("guardada grafica.png")
Gráfica de barras generada con matplotlib: visitas por lenguaje, con Python a la cabeza, seguido de Java, Rust y Go (datos de ejemplo)
La gráfica que genera el ejemplo, tal cual. Los datos son inventados.

matplotlib.use("Agg") hace que dibuje directamente a un archivo, sin abrir ninguna ventana; así funciona también en un servidor o en un contenedor. En tu ordenador puedes quitarlo y llamar a plt.show() para ver la gráfica en pantalla.

Beautiful Soup: extraer datos de HTML

from bs4 import BeautifulSoup

html = """
<ul id="lenguajes">
  <li class="activo"><a href="/python">Python</a></li>
  <li><a href="/java">Java</a></li>
  <li class="activo"><a href="/rust">Rust</a></li>
</ul>
"""
soup = BeautifulSoup(html, "html.parser")
for a in soup.select("#lenguajes li.activo a"):
    print(a.text, "->", a["href"])
salidaPython -> /python
Rust -> /rust

select acepta selectores CSS, los mismos que se usan en las hojas de estilo, así que #lenguajes li.activo a se lee igual que en CSS. Para descargar la página se combina con requests. Si lo que necesitas es recorrer un sitio entero siguiendo enlaces, la herramienta adecuada es Scrapy. Y antes de extraer datos de un sitio, revisa sus condiciones de uso y su robots.txt.

SQLAlchemy: bases de datos

from sqlalchemy import create_engine, select, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session

class Base(DeclarativeBase):
    pass

class Articulo(Base):
    __tablename__ = "articulos"
    id: Mapped[int] = mapped_column(primary_key=True)
    titulo: Mapped[str] = mapped_column(String(100))
    visitas: Mapped[int]

engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)

with Session(engine) as s:
    s.add_all([Articulo(titulo="Hola mundo", visitas=10),
               Articulo(titulo="Leer CSV", visitas=42),
               Articulo(titulo="Peticiones HTTP", visitas=27)])
    s.commit()
    consulta = select(Articulo).where(Articulo.visitas > 20).order_by(Articulo.visitas.desc())
    for a in s.scalars(consulta):
        print(a.titulo, a.visitas)
salidaLeer CSV 42
Peticiones HTTP 27

Cada tabla se define como una clase, y las consultas se escriben en Python en lugar de en SQL. Es el estilo de SQLAlchemy 2, con anotaciones de tipo (Mapped[int]). El mismo código funciona con SQLite, PostgreSQL o MySQL cambiando solo la cadena de conexión. Para SQLite sin ninguna librería externa, mira SQLite con Python.

FastAPI: APIs web

from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel

app = FastAPI()

class Articulo(BaseModel):
    titulo: str
    visitas: int = 0

@app.get("/saludo/{nombre}")
def saludo(nombre: str):
    return {"mensaje": f"Hola, {nombre}"}

@app.post("/articulos")
def crear(articulo: Articulo):
    return {"creado": articulo.titulo, "visitas": articulo.visitas}

cliente = TestClient(app)
print(cliente.get("/saludo/Ana").json())
print(cliente.post("/articulos", json={"titulo": "FastAPI"}).json())
r = cliente.post("/articulos", json={"visitas": "muchas"})
print(r.status_code, [e["loc"][-1] + ": " + e["type"] for e in r.json()["detail"]])
salida{'mensaje': 'Hola, Ana'}
{'creado': 'FastAPI', 'visitas': 0}
422 ['titulo: missing', 'visitas: int_parsing']

FastAPI usa las anotaciones de tipo para validar lo que llega: en la última petición falta el título y visitas no es un número, así que responde con un error 422 que explica cada fallo, sin que hayas escrito ninguna validación. Aquí se prueba con TestClient, que llama a la API sin levantar un servidor; en producción se ejecuta con uvicorn.

Con las versiones actuales, TestClient avisa de que usar httpx está obsoleto y pide instalar httpx2. Por eso aparece en el pip install de arriba; con él, el aviso desaparece y el ejemplo funciona igual.

Si buscas un framework completo, con panel de administración, usuarios y plantillas incluidos, la referencia es Django. Para algo pequeño y sin estructura impuesta, Flask.

pytest: pruebas

import pytest

def precio_con_iva(precio, iva=0.16):
    if precio < 0:
        raise ValueError("el precio no puede ser negativo")
    return round(precio * (1 + iva), 2)

def test_iva_por_defecto():
    assert precio_con_iva(100) == 116.0

@pytest.mark.parametrize("precio, iva, esperado", [(50, 0.16, 58.0), (200, 0.08, 216.0), (0, 0.16, 0.0)])
def test_varios(precio, iva, esperado):
    assert precio_con_iva(precio, iva) == esperado

def test_negativo():
    with pytest.raises(ValueError):
        precio_con_iva(-1)
python -m pytest -v test_precios.py
salida (recortada)test_precios.py::test_iva_por_defecto PASSED                             [ 20%]
test_precios.py::test_varios[50-0.16-58.0] PASSED                        [ 40%]
test_precios.py::test_varios[200-0.08-216.0] PASSED                      [ 60%]
test_precios.py::test_varios[0-0.16-0.0] PASSED                          [ 80%]
test_precios.py::test_negativo PASSED                                    [100%]

============================== 5 passed in 0.04s ===============================

Las pruebas son funciones que empiezan por test_ y usan un assert normal. parametrize ejecuta la misma prueba con varios casos, y cada uno aparece por separado en el informe; pytest.raises comprueba que se lanza la excepción esperada.

Otras que conviene conocer

LibreríaPara qué
scikit-learnAprendizaje automático clásico: clasificación, regresión, agrupamiento
PyTorchRedes neuronales y aprendizaje profundo
KerasAPI de alto nivel para redes neuronales; desde Keras 3 funciona sobre JAX, TensorFlow o PyTorch
NLTK y spaCyProcesamiento de lenguaje natural
ScapyCrear, enviar y analizar paquetes de red; muy usada en seguridad
KivyInterfaces gráficas multiplataforma, también para móviles
La versión de 2019 de esta entrada incluía Twisted, un framework de red basado en eventos. Sigue existiendo, pero hoy, para la mayoría de los programas concurrentes, se usa asyncio, que viene con Python, o librerías construidas sobre él.

Entrada publicada en 2019 y revisada en octubre de 2026. Todo el código se ejecutó con Python 3.14.8 en un contenedor limpio, con las versiones de la tabla; las salidas están copiadas de esa ejecución.

Tips para programadores

Aprende un nuevo lenguaje

Es sabido que no debes enfocarte en una sola tecnología o lenguaje de programación.   Pero el sentido de este consejo no es sólo que escojas una tecnología que te permita ganar más dinero (que también es una buena idea), sino que además de eso te permita experimentar y hacer cosas diferentes. Por ejemplo, si siempre has estado enfocado a aplicaciones WEB, puedes comenzar a experimentar con el control de motores eléctricos o para obtener datos desde sensores o hardware que no hayas usado anteriormente, o probar también con aplicaciones para móviles, tendrás una perspectiva más amplia de lo que es el desarrollo de software.

Ten un  «Pet Project»

Todos tenemos ideas para una aplicación o desarrollo que nos gustaría programar.  Sin embargo pocas veces las materializamos.  Esto no sólo es malo porque pierdes la oportunidad de llevar a cabo una buena idea, sino que también es posible que nunca sepas si esa idea es mala o que en realidad no sea tan útil, o peor aún, que ya exista algo parecido porque no habías investigado demasiado y te enfoques mejor en otra cosa.  Adquiere el hábito de tener al menos un proyecto y ve agregando características poco a poco pero de forma constante.

Relaciónate con personas que hagan cosas diferentes

No sólo se trata de encontrar gente que use otras tecnologías, sino otras formas de hacer negocios y de ganar dinero.  Es posible que encuentres oportunidades donde otros no las han visto, tan sólo porque no ha llegado nadie para propornerlas.  No te enfoques sólo a entender los problemas de los clientes de la empresa donde trabajes.

Haz que tu trabajo se vea elegante

Son muchos los desarrolladores que descuidan el aspecto visual de su trabajo y sólo se preocupan porque funcione correctamente.  Sin embargo una apariencia visual o usabilidad deficientes, pueden hacer que el usuario tenga una impresión equivocada sobre como funcionan tus desarrollos y llegue a pensar que tiene errores aún cuando esto no sea verdad, recuerda que haces desarrollo para facilitarle la vida a personas que no siempre tienen un conocimiento técnico silimar al tuyo.

No inventes cosas que ya están bien hechas

Lenguajes como Java o C# no son los más ampliamente usados por su sintaxis o su facilidad de uso, sino por la inmensa variedad de librerías o herramientas que existen y que puedes usar libremente, con la seguridad de que van a funcionar correctamente. No gastes tu tiempo tratndo de hacer algo que ya existe si no lo vas a superar.

Comparte y acepta críticas a tu código

Es universal. Ocurre en todas las profesiones. A nadie le gusta que le digan como hacer cosas que uno supone hace bien.  Pero compartir ideas y tomar en cuenta las recomendaciones de otros es casi tan útil como Google para aprender cosas nuevas.  Además mejoras tu ambiente laboral.

Crea librerías de ejemplos o soluciones

No es que tengas que desarrollar librerías nuevas, se trata más bien de esos ejemplos, como conectarte a bases de datos, nombres de drivers, herramientas, comandos, funciones o técnicas de desarrollo que quizá aplicarás en tus proyectos más de una vez. En cualquier momento puedes usar el buscador y encontrar prácticamente todo lo que necesites, pero tener cosas ya probadas previamente por tí, es muy útil.

Descansa lejos de la computadora

Esto debes hacerlo por puro amor propio y no sólo es descansar, ejercítate.  Algunos problemas de espalda y ojos derivados de pasar horas sentados frente a la computadora pueden agravarse y son difíciles de tratar.  Cuida tu cuerpo.

 

Los gurús y el trabajo en equipo

Sin duda, siempre existen personas brillantes que se distinguen por su buen sentido común, curiosidad y capacidad para resolver problemas difíciles. Pero siempre he sospechado que la imagen del gurú está sobrevalorada.

Algunas malas experiencias me dicen que esto podría ser así.  En cierta ocasión, durante el desarrollo de un proyecto mas o menos grande y en una demostración de capacidades, el líder del equipo, que se sabía muy bueno en el desarrollo de software (el gurú), comenzó a utilizar una serie de tecnologías y frameworks de moda para impresionar al cliente y al administrador de proyecto.  Como resultado, los que tenían menos experiencia comenzaron a sufrir con la curva de aprendizaje y se enfocaron mas a conocer las nuevas tecnologías que al modelo de negocio. El desarrollo se terminó con una aplicación robusta tecnológicamente, pero poco amigable para el cliente y por supuesto en mas tiempo del que se esperaba. Un pequeño desastre.

En otras ocasiones, me he topado con el típico personaje que es capaz de resolver problemas difíciles, pero que cuando tienes que dar mantenimiento a su código o simplemente necesitas usarlo, este te parece tan desordenado que te dan ganas de hacerlo de nuevo.

Otro de los riesgos de tener a una persona que tiene todo el dominio sobre cierta tecnología, herramienta o el conocimiento mas crítico de un proyecto, es que puede simplemente irse, con el todo su conocimiento.

Me agradan mas los equipos de trabajo donde los problemas difíciles o algunas decisiones tecnológicas se resuelven entre varios.

Los gurús se equivocan como cualquier otro.

Además, cuando te autoproclamas gurú, puedes quedarte solo a la hora de resolver problemas difíciles.  Creo que no hay necesidad de que esto sea así, porque el criterio para resolver un problema crítico se reduce al de una sola persona y no creo que esto sea muy conveniente.

Cuando alguien te hace una pregunta complicada sobre algún problema o error, es probable que ella misma tenga mas capacidad para responderla, ya que conoce mejor el contexto del problema.  Por lo que mas que tratar de dar una solución es mejor dar un punto de vista o pistas sobre como resolver el problema.

El protagonismo es algo que nos puede seducir a todos, pero yo me lo pensaría mucho antes de adoptar una postura de este tipo. Sobre todo cuando de lo que se trata es hacer mas agradable y profesional tu trabajo.  Desde luego no estoy diciendo que todos los gurús son malos, de hecho también he conocido a algunos muy buenos. Pero son los menos.

Un hábito que recomiendo a todos es que cuando encuentras la solución a un problema difícil, la comentes a tus demás compañeros. Esto permite tener una base de conocimiento colectiva y evita tener que investigar demasiado sobre un problema que ya se ha sido resuelto con anterioridad.

Tómate con calma eso de ser gurú, puedes serlo sin hacer alarde.  🙂