Cómo autenticar una API REST con OAuth 2.0 en Python
Las APIs de datos más robustas no están abiertas al público: exigen autenticación. En escenarios servidor a servidor, el estándar más común es OAuth 2.0 con el flujo client credentials, y dominarlo es esencial para construir pipelines de datos fiables. Esta guía muestra, paso a paso, cómo obtener un access token y llamar a un endpoint protegido en Python.
Requisitos previos
- Python 3.8 o superior instalado.
- La biblioteca
requests(se instala conpip install requests). - Las credenciales de la API:
client_idyclient_secret, proporcionadas por el portal del proveedor. - La URL del token endpoint (donde se solicitan los tokens) y la URL del recurso protegido que quieres consumir.
Paso 1: Entender el flujo client credentials
OAuth 2.0 define varios flujos. El de client credentials es el indicado cuando es tu aplicación — y no un usuario — la que accede a los datos, como ocurre en un script de ETL o en un servicio programado. La idea es sencilla: la aplicación presenta su client_id y su client_secret a un token endpoint, recibe a cambio un access token temporal y usa ese token para autenticar cada petición a la API. No hay pantallas de login ni intervención humana, lo que lo hace ideal para la automatización.
Paso 2: Obtener el access token
La primera petición es un POST al token endpoint, indicando grant_type=client_credentials. La respuesta es un JSON con el token y su tiempo de validez en segundos (expires_in). Fíjate en que las credenciales van en el cuerpo de la petición, sobre HTTPS, y nunca en la URL.
import requests
TOKEN_URL = "https://auth.example.com/oauth/token"
CLIENT_ID = "your-client-id"
CLIENT_SECRET = "your-client-secret"
def get_token():
response = requests.post(TOKEN_URL, data={
"grant_type": "client_credentials",
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"scope": "data.read",
}, timeout=10)
response.raise_for_status()
return response.json()["access_token"]
token = get_token()
print("Access token obtained")
El método raise_for_status() garantiza que un error de credenciales (HTTP 401) detiene el script de inmediato, en lugar de continuar con un token inválido.
Paso 3: Llamar al endpoint protegido
Con el token en la mano, cada petición a la API lleva la cabecera Authorization: Bearer <token>. Así es como el servidor sabe que estás autorizado.
API_URL = "https://api.example.com/v1/customers"
def get_data(token):
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(API_URL, headers=headers, timeout=10)
response.raise_for_status()
return response.json()
records = get_data(token)
print(f"Received {len(records)} records")
Paso 4: Reutilizar el token y gestionar la expiración
Pedir un token nuevo en cada llamada es lento y, a menudo, está sujeto a límites. Lo mejor es guardar el token y su instante de expiración, y renovarlo solo cuando queda poco tiempo. Una clase sencilla resuelve el problema:
import time
class APIClient:
def __init__(self):
self._token = None
self._expires_at = 0
def valid_token(self):
# Refresh 60 seconds before expiry, to be safe
if not self._token or time.time() > self._expires_at - 60:
response = requests.post(TOKEN_URL, data={
"grant_type": "client_credentials",
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
}, timeout=10)
response.raise_for_status()
payload = response.json()
self._token = payload["access_token"]
self._expires_at = time.time() + payload["expires_in"]
return self._token
client = APIClient()
headers = {"Authorization": f"Bearer {client.valid_token()}"}
Así, el mismo token se reutiliza mientras es válido y se renueva automáticamente cuando hace falta.
Verificar el resultado
Para confirmar que todo funciona, ejecuta el script y comprueba dos señales: la petición del token devuelve HTTP 200 y la llamada a la API devuelve datos en lugar de un error 401. Si recibes un 401, revisa el client_id, el client_secret y el scope. Un error 403 significa que el token es válido pero no tiene permisos para ese recurso — en ese caso, el problema está en los scopes asignados a la aplicación.
Conclusión
Con estos pasos tienes una base sólida para autenticar cualquier API de datos que use OAuth 2.0 client credentials, desde la obtención del token hasta su renovación automática. El siguiente paso natural es combinar esto con paginación y escritura en una base de datos, convirtiendo estas llamadas en un pipeline completo. ¿Qué API vas a integrar primero?