Consumir APIs REST con Python y requests
La librería requests es el estándar para hacer peticiones HTTP en Python: GET, POST, autenticación, paginación, descarga de archivos y manejo de errores.
Instalación
pip install requests
GET Básico
import requests
resp = requests.get("https://jsonplaceholder.typicode.com/posts/1")
resp.raise_for_status() # Lanza excepción si hay error HTTP
dato = resp.json()
print(f"Título: {dato['title']}")
print(f"Cuerpo: {dato['body'][:80]}")
print(f"Status: {resp.status_code} | Tiempo: {resp.elapsed.total_seconds():.2f}s")
Parámetros de URL y Cabeceras
import requests
def buscar_usuarios(query, pagina=1, por_pagina=10):
resp = requests.get(
"https://api.ejemplo.com/usuarios",
params={
"q": query,
"page": pagina,
"per_page": por_pagina,
},
headers={
"Accept": "application/json",
"User-Agent": "MiApp/1.0",
},
timeout=10
)
resp.raise_for_status()
return resp.json()
resultados = buscar_usuarios("python", pagina=1)
print(f"Resultados: {len(resultados)}")
POST, PUT y DELETE
import requests
BASE = "https://jsonplaceholder.typicode.com"
# POST — Crear recurso
def crear_post(titulo, cuerpo, user_id):
resp = requests.post(f"{BASE}/posts",
json={"title": titulo, "body": cuerpo, "userId": user_id},
headers={"Content-Type": "application/json"}
)
resp.raise_for_status()
print(f"Creado (id={resp.json()['id']}): {resp.status_code}")
return resp.json()
# PUT — Actualizar recurso
def actualizar_post(post_id, titulo, cuerpo):
resp = requests.put(f"{BASE}/posts/{post_id}",
json={"id": post_id, "title": titulo, "body": cuerpo, "userId": 1}
)
resp.raise_for_status()
return resp.json()
# DELETE — Eliminar recurso
def eliminar_post(post_id):
resp = requests.delete(f"{BASE}/posts/{post_id}")
resp.raise_for_status()
print(f"Eliminado post {post_id}: {resp.status_code}")
crear_post("Mi Título", "Mi contenido de prueba.", 1)
actualizar_post(1, "Título Actualizado", "Cuerpo actualizado.")
eliminar_post(1)
Autenticación: API Key y Bearer Token
import requests
# API Key en cabecera
resp = requests.get(
"https://api.openweathermap.org/data/2.5/weather",
params={"q": "Madrid", "units": "metric", "lang": "es"},
headers={"X-API-Key": "TU_API_KEY"}
)
datos = resp.json()
print(f"Temperatura en Madrid: {datos['main']['temp']}°C")
# Bearer Token (OAuth2, JWT)
TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
resp = requests.get(
"https://api.miservicio.com/perfil",
headers={"Authorization": f"Bearer {TOKEN}"}
)
print(resp.json())
Paginación Automática
import requests
def obtener_todos(url, params=None, limite=None):
resultados = []
pagina = 1
while True:
p = {**(params or {}), "page": pagina, "per_page": 100}
resp = requests.get(url, params=p, timeout=10)
resp.raise_for_status()
datos = resp.json()
if not datos: break
resultados.extend(datos)
print(f" Página {pagina}: {len(datos)} registros")
if len(datos) < 100: break
if limite and len(resultados) >= limite: break
pagina += 1
return resultados
todos = obtener_todos("https://jsonplaceholder.typicode.com/posts")
print(f"Total: {len(todos)} posts")
Descargar Archivos
import requests
from pathlib import Path
def descargar_archivo(url, destino, mostrar_progreso=True):
resp = requests.get(url, stream=True, timeout=30)
resp.raise_for_status()
total = int(resp.headers.get("Content-Length", 0))
bajado = 0
with open(destino, "wb") as f:
for bloque in resp.iter_content(chunk_size=8192):
f.write(bloque)
bajado += len(bloque)
if mostrar_progreso and total:
pct = bajado * 100 // total
print(f"\r {pct:3d}% ({bajado//1024}KB/{total//1024}KB)", end="")
if mostrar_progreso: print()
print(f"Descargado: {destino} ({Path(destino).stat().st_size//1024} KB)")
descargar_archivo(
"https://example.com/archivo_grande.zip",
"descarga.zip"
)
Recurso Adicional
Para convertir archivos descargados entre PDF, ZIP, JPG y otros formatos sin instalar nada, usa KaijuConverter — gratis y sin registro.
Conversiones relacionadas
Conversiones frecuentes del catálogo: