¿Por qué requests?
Python incluye un módulo urllib integrado para trabajar con HTTP, pero su sintaxis es engorrosa y poco intuitiva. La biblioteca requests resuelve este problema proporcionando una interfaz elegante y comprensible. No es de extrañar que su lema sea «HTTP for Humans».
Instalación
Configurar requests es muy fácil:
pip install requestsConceptos básicos: consultas GET
Comencemos con el tipo de solicitud más común: GET. Imaginemos que necesitamos obtener datos sobre un usuario de GitHub:
import requests
response = requests.get('https://api.github.com/users/octocat')
# Comprobando el estado de la respuesta
print(response.status_code) # 200
# Obteniendo JSON
data = response.json()
print(data['name']) # The Octocat
print(data['public_repos']) # Número de repositorios públicosEl objeto response contiene toda la información sobre la respuesta del servidor: código de estado, encabezados, cuerpo de la respuesta y mucho más.

Parámetros de la solicitud
A menudo, las API requieren la transferencia de parámetros en la URL. La biblioteca de solicitudes te permite hacerlo con elegancia:
# Buscar repositorios en GitHub
params = {
'q': 'python requests',
'sort': 'stars',
'order': 'desc'
}
response = requests.get('https://api.github.com/search/repositories', params=params)
repos = response.json()
for repo in repos['items'][:5]:
print(f"{repo['name']}: {repo['stargazers_count']} stars")La biblioteca genera automáticamente la URL correcta con parámetros, escapando los caracteres especiales.
Solicitudes POST y envío de datos
Las solicitudes POST se utilizan para crear recursos o enviar formularios. Consideremos un ejemplo con el envío de JSON:
# Creación de un nuevo recurso
data = {
'title': 'I'm studying requests',
'body': 'This is a very convenient library!',
'userId': 1
}
response = requests.post('https://jsonplaceholder.typicode.com/posts', json=data)
if response.status_code == 201:
print('Resource created!')
print(response.json())Presta atención al parámetro json: requests serializa automáticamente el diccionario en JSON y establece el encabezado Content-Type correcto.
Trabajar con encabezados
Muchas API requieren autenticación a través de encabezados. Así es como se hace:
headers = {
'Authorization': 'Bearer YOUR_TOKEN_HERE',
'User-Agent': 'MyApp/1.0'
}
response = requests.get('https://api.example.com/data', headers=headers)Algunas API utilizan claves API:
headers = {'X-API-Key': 'your_api_key'}
response = requests.get('https://api.example.com/protected', headers=headers)
Tratamiento de errores
El trabajo profesional con la API no es posible sin un procesamiento adecuado de los errores:
try:
response = requests.get('https://api.example.com/data', timeout=5)
response.raise_for_status() # Lanzará una excepción para los códigos 4xx y 5xx
data = response.json()
except requests.exceptions.HTTPError as http_err:
print(f'HTTP error: {http_err}')
except requests.exceptions.ConnectionError:
print('Connection error')
except requests.exceptions.Timeout:
print('Timeout')
except requests.exceptions.RequestException as err:
print(f'An error occurred: {err}')El método raise_for_status() lanza automáticamente una excepción si el servidor ha devuelto un código de error.
Sesiones para múltiples solicitudes
Si necesitas hacer varias solicitudes a una API, usa sesiones. Almacenan cookies y conexión, lo que acelera significativamente el trabajo:
session = requests.Session()
session.headers.update({'Authorization': 'Bearer TOKEN'})
# Todas las solicitudes dentro de la sesión utilizarán encabezados comunes
response1 = session.get('https://api.example.com/users')
response2 = session.get('https://api.example.com/posts')
response3 = session.post('https://api.example.com/comments', json={'text': 'Hello'})
session.close()Es aún mejor usar el gestor contextual:
with requests.Session() as session:
session.headers.update({'Authorization': 'Bearer TOKEN'})
response = session.get('https://api.example.com/data')Trabajar con archivos
Cargar archivos a través de la API tampoco es difícil:
# Cargando archivo
files = {'file': open('document.pdf', 'rb')}
response = requests.post('https://api.example.com/upload', files=files)
# Descarga de archivo
response = requests.get('https://example.com/image.jpg', stream=True)
with open('image.jpg', 'wb') as file:
for chunk in response.iter_content(chunk_size=8192):
file.write(chunk)El parámetro stream=True le permite cargar archivos grandes en porciones sin cargarlos completamente en la memoria.
Ejemplo práctico: trabajo con la API meteorológica
Vamos a crear una aplicación completa para obtener el tiempo:
import requests
def get_weather(city, api_key):
"""Gets the current weather for the specified city"""
base_url = "http://api.openweathermap.org/data/2.5/weather"
params = {
'q': city,
'appid': api_key,
'units': 'metric',
'lang': 'ru'
}
try:
response = requests.get(base_url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
weather_info = {
'city': data['name'],
'temperature': data['main']['temp'],
'feels': data['main']['feels_like'],
'description': data['weather'][0]['description'],
'Humidity': data['main']['humidity'],
'Wind': data['wind']['speed']
}
return weather_info
except requests.exceptions.RequestException as e:
print(f"Error retrieving data: {e}")
return None
# Uso
weather = get_weather('Moscow', 'YOUR_API_KEY')
if weather:
print(f"Weather in the city {weather['city']}:"
print(f"Temperature: {weather['temperature']}°C")
print(f"Feels like: {weather['ощущается']}°C" print(f"Description: {weather['description']}"]}")Opciones avanzadas
Mecanismo de reintento con adaptadores:
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
session = requests.Session()
retry = Retry(
total=3,
backoff_factor=1,
status_forcelist=[500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
response = session.get('https://api.example.com/data')Trabajo con autenticación:
# Basic Auth
response = requests.get('https://api.example.com/data',
auth=('username', 'password'))
# OAuth 2.0 generalmente a través de encabezados
headers = {'Authorization': f'Bearer {access_token}'}
response = requests.get('https://api.example.com/data', headers=headers)Conclusión
La biblioteca requests hace que trabajar con la API en Python sea un placer. Su sintaxis sencilla e intuitiva, sus potentes funciones y su excelente documentación la convierten en el estándar de facto para las solicitudes HTTP en Python. Una vez que domines requests, podrás integrar miles de servicios diferentes en tus proyectos y crear aplicaciones realmente potentes.
Anexo Kodik ofrece cursos estructurados en Python, JavaScript, trabajo con API y mucho más. Las lecciones interactivas, las tareas prácticas y el aprendizaje paso a paso te ayudarán a convertirte en desarrollador.
Únete a nuestro Canal de Telegram, donde encontrarás el apoyo de desarrolladores experimentados, materiales útiles y respuestas a cualquier pregunta sobre programación. ¡Aprende a un ritmo cómodo con una comunidad de personas afines!
