Lección 12 de 12 · Nivel 3: Avanzado

APIs y automatización con Python: requests, archivos y reportes

En esta lección
  1. Qué es una API
  2. Tu primera petición con requests
  3. Una función robusta
  4. Parámetros y claves de API
  5. Automatizar archivos con pathlib
  6. Generar reportes de Excel
  7. Que se ejecute solo
  8. Proyecto final: tus gastos en dólares, cada mañana
  9. Resumen del curso
Lo que lograrás en esta lección
  • Consultar APIs web con requests y trabajar con sus respuestas JSON.
  • Guardar claves de acceso de forma segura con variables de entorno.
  • Automatizar tareas con archivos: organizar carpetas y generar reportes.
  • Programar tus scripts para que se ejecuten solos.

Has llegado a la última lección. Hasta ahora tus programas trabajaban con datos que tú les dabas. Ahora los conectarás con el mundo: tipos de cambio en tiempo real, datos de servicios web, archivos que se ordenan solos, reportes que se generan cada mañana. Es aquí donde Python empieza a ahorrarte horas de trabajo cada semana.

Qué es una API

Una API web es una "puerta" que un servicio abre para que otros programas le pidan datos o le den órdenes. En lugar de una página para personas, devuelve datos para programas, casi siempre en formato JSON (el mismo de la lección 8). Ejemplos: tipos de cambio, clima, pagos, mapas, redes sociales, modelos de inteligencia artificial.

La conversación es siempre parecida:

  1. Tu programa hace una petición (request) a una URL: GET para pedir datos, POST para enviarlos.
  2. El servidor responde con un código de estado (200 = bien, 404 = no encontrado, 401 = no autorizado, 429 = demasiadas peticiones, 500 = error del servidor) y los datos.

Tu primera petición con requests

pip install requests
import requests

url = "https://open.er-api.com/v6/latest/USD"     # API pública de tipos de cambio

respuesta = requests.get(url, timeout=10)
respuesta.raise_for_status()          # lanza una excepción si el código no es 2xx
datos = respuesta.json()              # convierte el JSON en un diccionario

print(datos["base_code"])             # USD
print(datos["rates"]["MXN"])          # pesos mexicanos por dólar
print(datos["rates"]["PEN"])          # soles por dólar
  • timeout=10: si el servidor no responde en 10 segundos, no te quedas esperando para siempre. Ponlo siempre.
  • raise_for_status(): convierte los errores HTTP en excepciones que puedes capturar.
  • .json(): te da diccionarios y listas de Python, que ya sabes recorrer (lección 6).

Antes de usar cualquier API, lee su documentación: qué URL usar, qué parámetros acepta, cómo es la respuesta, cuántas peticiones permite y sus condiciones de uso.

1. Una API responde con código 429. ¿Qué significa?

  • Que todo salió bien.
  • Que hiciste demasiadas peticiones en poco tiempo.
  • Que la URL no existe.

429 = Too Many Requests. Debes esperar o reducir la frecuencia. El 404 sería "no encontrado".

Una función robusta

import requests


def tipo_de_cambio(base="USD", destino="MXN"):
    """Devuelve cuántas unidades de 'destino' vale 1 unidad de 'base', o None si falla."""
    try:
        r = requests.get(f"https://open.er-api.com/v6/latest/{base}", timeout=10)
        r.raise_for_status()
        return r.json()["rates"][destino]
    except requests.RequestException as e:
        print(f"Error de conexión: {e}")
    except KeyError:
        print(f"Moneda no encontrada: {destino}")
    return None

Las peticiones a internet fallan más de lo que crees: sin conexión, servidor caído, cambios en la API. Un programa profesional lo prevé con try/except (lección 8).

Parámetros y claves de API

Muchas APIs piden parámetros y una clave (API key) que identifica tu cuenta:

import os
import requests

clave = os.environ.get("CLIMA_API_KEY")       # leída del entorno, nunca escrita en el código
if not clave:
    raise SystemExit("Falta la variable de entorno CLIMA_API_KEY")

params = {"q": "Lima", "units": "metric", "appid": clave}
r = requests.get("https://api.ejemplo-clima.com/weather", params=params, timeout=10)
Nunca escribas tus claves en el código

Si subes a GitHub un archivo con una clave, cualquiera puede usarla y hacerte gastar dinero. Guárdalas en variables de entorno (set CLIMA_API_KEY=… en Windows CMD, export CLIMA_API_KEY=… en macOS y Linux) o en un archivo .env que esté en tu .gitignore (con la librería python-dotenv).

2. ¿Cuál es la forma correcta de usar una clave de API en tu script?

  • Escribirla en una variable al principio del archivo.
  • Leerla de una variable de entorno con os.environ.
  • Ponerla en un comentario.

Así la clave no queda en el código ni se comparte por accidente al publicar el proyecto.

Automatizar archivos con pathlib

Una de las automatizaciones más útiles: ordenar la carpeta de descargas por tipo de archivo.

from pathlib import Path
import shutil

CARPETA = Path.home() / "Downloads"
TIPOS = {
    "Documentos": {".pdf", ".docx", ".txt"},
    "Hojas": {".xlsx", ".csv"},
    "Imagenes": {".jpg", ".jpeg", ".png"},
}

for archivo in CARPETA.iterdir():
    if not archivo.is_file():
        continue
    for destino, extensiones in TIPOS.items():
        if archivo.suffix.lower() in extensiones:
            carpeta_destino = CARPETA / destino
            carpeta_destino.mkdir(exist_ok=True)
            shutil.move(str(archivo), carpeta_destino / archivo.name)
            print(f"Movido: {archivo.name} → {destino}")
            break
  • Path.home() / "Downloads" construye rutas que funcionan en Windows, macOS y Linux.
  • iterdir() recorre el contenido de la carpeta; suffix es la extensión.
  • mkdir(exist_ok=True) crea la carpeta si no existe.
Prueba primero "en seco"

Antes de mover o borrar archivos de verdad, cambia shutil.move por un print y comprueba qué haría el script. Y prueba en una carpeta de copia.

Generar reportes de Excel

Con pandas (lección 11) puedes crear un Excel con formato básico; con openpyxl controlas cada celda:

from openpyxl import Workbook
from openpyxl.styles import Font

wb = Workbook()
hoja = wb.active
hoja.title = "Resumen"
hoja.append(["Categoría", "Monto"])
for categoria, monto in [("Comida", 350.5), ("Transporte", 120.0), ("Ocio", 90.0)]:
    hoja.append([categoria, monto])

for celda in hoja[1]:
    celda.font = Font(bold=True)
hoja["A5"] = "Total"
hoja["B5"] = "=SUM(B2:B4)"         # las fórmulas se escriben en inglés
wb.save("resumen.xlsx")

Que se ejecute solo

  • Windows: el Programador de tareas (Task Scheduler) → Crear tarea básica → acción "Iniciar un programa" con la ruta de python.exe de tu entorno virtual y la ruta de tu script como argumento.
  • macOS y Linux: cron. Por ejemplo, para ejecutarlo de lunes a viernes a las 8:00, en crontab -e:
    0 8 * * 1-5 /ruta/al/proyecto/.venv/bin/python /ruta/al/proyecto/informe.py
  • En la nube: servicios como GitHub Actions o funciones serverless pueden ejecutar scripts con horario sin dejar tu computadora encendida.

Para scripts automáticos, guarda lo que pasa en un archivo de registro con el módulo logging en lugar de print: así sabrás qué ocurrió aunque nadie estuviera mirando.

Web scraping con responsabilidad

Extraer datos de páginas web (con librerías como BeautifulSoup) es posible, pero antes revisa si existe una API oficial, lee las condiciones de uso del sitio y su archivo robots.txt, no satures el servidor con peticiones y no recopiles datos personales.

3. Tu script va a mover cientos de archivos. ¿Qué haces antes de ejecutarlo de verdad?

  • Nada, para eso está la papelera.
  • Probarlo en seco (solo mostrando qué haría) y en una carpeta de copia.
  • Ejecutarlo dos veces para asegurarse.

Las acciones de un script sobre archivos no se deshacen con un clic. Probar primero evita desastres.

Proyecto final: tus gastos en dólares, cada mañana

Este script reúne todo el curso: lee el CSV del gestor de gastos de la lección 8, consulta el tipo de cambio en una API, calcula el resumen con pandas y genera un Excel. Puedes programarlo para que se ejecute cada mañana.

import logging
from datetime import date
from pathlib import Path

import pandas as pd
import requests

logging.basicConfig(filename="informe.log", level=logging.INFO,
                    format="%(asctime)s %(levelname)s %(message)s")

MONEDA_LOCAL = "MXN"           # cámbiala por PEN, COP, ARS, CLP, EUR...
ARCHIVO = Path("gastos.csv")


def obtener_tipo_cambio(moneda):
    r = requests.get("https://open.er-api.com/v6/latest/USD", timeout=10)
    r.raise_for_status()
    return r.json()["rates"][moneda]      # unidades de moneda local por 1 USD


def generar_informe():
    if not ARCHIVO.exists():
        logging.warning("No existe %s", ARCHIVO)
        return
    gastos = pd.read_csv(ARCHIVO)
    tasa = obtener_tipo_cambio(MONEDA_LOCAL)

    resumen = gastos.groupby("categoria", as_index=False)["monto"].sum()
    resumen["monto_usd"] = (resumen["monto"] / tasa).round(2)
    resumen = resumen.sort_values("monto", ascending=False)

    salida = f"informe_{date.today().isoformat()}.xlsx"
    resumen.to_excel(salida, index=False)
    logging.info("Informe %s creado (1 USD = %s %s)", salida, tasa, MONEDA_LOCAL)
    print(resumen.to_string(index=False))


if __name__ == "__main__":
    try:
        generar_informe()
    except requests.RequestException as e:
        logging.error("No se pudo obtener el tipo de cambio: %s", e)

Retos para terminar el curso

  1. Ejecuta el proyecto con tu propio gastos.csv y revisa el archivo informe.log.
  2. Añade una segunda hoja al Excel con el gasto por mes (pista: pd.ExcelWriter, como en la lección 11).
  3. Prográmalo para que se ejecute cada lunes a las 8:00.
  4. Reorganízalo como paquete con pruebas (lección 10) y súbelo a GitHub como parte de tu portafolio, sin claves ni datos personales.
¿Qué pasa si la API no responde?

La excepción requests.RequestException se captura en el bloque principal y queda registrada en informe.log; el script termina sin bloquearse. Una mejora: guardar el último tipo de cambio obtenido en un archivo JSON y usarlo como respaldo.

Resumen del curso

  • Básico: instalación, variables, textos y condicionales.
  • Intermedio: bucles, estructuras de datos, funciones, archivos y errores.
  • Avanzado: clases, módulos y entornos, pandas, APIs y automatización.

¡Felicidades, terminaste el curso de Python! Ya puedes construir programas que leen datos, los analizan, se conectan a servicios web y trabajan solos. Marca las lecciones como completadas para descargar tu certificado. Para seguir: profundiza en análisis de datos o en desarrollo web, o aprende a usar los modelos de lenguaje desde Python en el curso de inteligencia artificial.

¿Quieres tu certificado gratis?

Crea tu cuenta, marca tus avances y descarga el certificado al terminar el curso.

Inscribirme gratis