https://d226lax1qjow5r.cloudfront.net/blog/blogposts/3-ways-to-make-http-calls-with-python-requests-beginner-to-advanced/3-levels_http-calls_python.png

3 formas de realizar llamadas HTTP con peticiones Python (de principiante a avanzado)

Publicado el October 4, 2023

Tiempo de lectura: 7 minutos

La capacidad de hacer una petición HTTP es esencial para la forma en que las aplicaciones interactúan con la web. Si estás usando Python, ya sea para construir un raspador web, consumir APIs RESTful, o necesitas interactuar con la web de alguna otra manera, el módulo Requests de Python es la opción más popular y fácil de usar. En este post, exploraremos tres niveles de peticiones HTTP con el módulo Requests, empezando por lo más básico hasta llegar a técnicas avanzadas. Al final, ¡estarás listo para usar Requests en producción!

Los ejemplos de código de alto nivel de este post provienen del Vonage Python SDKnuestro SDK que te permite llamar a API para mensajería, voz, video, autenticación de 2 factores y más, todo usando Python. Hacemos uso del módulo Requests para hacer todo esto y más, por lo que es el proyecto de ejemplo perfecto para usar Requests.

Subamos de nivel nuestro juego de Peticiones, empezando por el Nivel 1... ¡ahora mismo!

Nivel 1: Peticiones HTTP básicas

En el nivel básico, tenemos las peticiones HTTP. Son el pan de cada día de los desarrolladores de Python que necesitan interactuar con servicios web. El módulo Requests hace que sea increíblemente fácil realizar peticiones GET y POST, lo que te permite recuperar páginas web o enviar datos a un servidor sin esfuerzo.

En primer lugar, instale las solicitudes en un entorno virtual de su elección:

python3 -m venv venv-requests-vonage . ./venv-requests-vonage/bin/activate pip install -U pip requests

Una vez que tengas tu entorno virtual activado y Requests instalado, puedes empezar a utilizarlo inmediatamente. He aquí un ejemplo de petición GET para obtener el contenido de una página web:

import requests

response = requests.get('https://example.com')
print(response.text)

Ejecutando el código anterior debería presentarle el HTML completo de la página https://example.com página. ¡Pero podemos hacer algo más que obtener páginas web con peticiones!

Esta es una petición POST, en la que enviamos datos a una URL:

import requests

data = {'vonage': 'loves', 'python': '!'}
response = requests.post('https://httpbin.org/post', json=data)
print(response.json())

Podemos ver la respuesta, serializada en un diccionario Python, a continuación. Observa que incluye los datos que hemos publicado:

{'args': {}, 'data': '{"vonage": "loves", "python": "!"}', 'files': {}, 'form': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '34', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.31.0', 'X-Amzn-Trace-Id': 'Root=1-65012480-007aeecf146f5ff007c7678d'}, 'json': {'python': '!', 'vonage': 'loves'}, 'origin': '82.30.197.62', 'url': 'https://httpbin.org/post'}

Con estos sencillos ejemplos, ya puedes empezar a hacer peticiones HTTP en Python. ¿Pero qué pasa si necesitas persistir configuraciones a través de múltiples peticiones o compartir recursos? Ahí es donde entra el Nivel 2.

Nivel 2: Uso de sesiones para la persistencia

Las sesiones HTTP son una forma de persistir la configuración a través de múltiples peticiones al mismo servidor. Las sesiones también utilizan la agrupación de conexiones, lo que significa que si realizas varias llamadas HTTP a los mismos hosts, utilizarás los mismos recursos y podrás ver mejoras significativas en el rendimiento.

Si te ocurre alguna de estas dos cosas, quizá te interese utilizar una sesión:

  • Si necesita mantener una conexión con estado, como cuando trabaja con API autenticadas o aplicaciones web.

  • Si realizas muchas peticiones a la misma API/host y no quieres perder tiempo y recursos.

El módulo Requests proporciona un objeto Session que le permite hacer precisamente eso. He aquí un ejemplo:

import requests

# Create a session
session = requests.Session()

# Set headers to be sent in every request
session.headers.update({'Accepts': 'application/json'})

# Perform multiple requests within the same session
response1 = session.get('https://example.com/some-page')
response2 = session.get('https://example.com/some-other-page')

Usar una sesión como esta significa que cualquier cookie que establezcamos será persistente. También podemos establecer valores predeterminados para una sesión agregándolos al objeto de sesión, como hicimos anteriormente con el encabezado que enviamos. Esto es increíblemente útil, pero la razón principal por la que usamos objetos de sesión en el SDK Python de Vonage es porque significa que nuestros usuarios pueden realizar muchas llamadas a la API, muy rápidamente.

Este es un ejemplo de los beneficios de rendimiento de usar una sesión HTTP. El código a continuación NO utiliza una sesión, sino que realiza 100 llamadas separadas a la API de Vonage Number Insight API de Vonage de Vonage para buscar información sobre 100 números de teléfono diferentes y convertirlos al formato internacional E.164:

import requests
import time

start_time = time.perf_counter()

number_conversions = {}
params = {'api_key': 'MY_API_KEY', 'api_secret': 'MY_API_SECRET', 'country': 'GB'}

for i in range(100):
    phone_number = str(1614960100 + i)
    params['number'] = phone_number
    
    with requests.get(
        'https://api.nexmo.com/ni/basic/json',
        params=params,
    ) as response:
        number_conversions[phone_number] = response.json()[
            'international_format_number'
        ]

elasped_time = time.perf_counter() - start_time
print(f'Time elapsed is: {elasped_time} seconds.')

Obtenemos el siguiente resultado: Time elapsed is: 11.103735665994463 seconds. Así que tomó más de 11 segundos para ejecutar 100 llamadas a la API, que no es terrible, pero podría ser mucho mejor.

He perfilado el código de arriba, aquí está una visualización parcela carámbano utilizando snakeviz:

An icicle plot showing how much time was spent executing each part of the program for the vanilla requests caseVanilla requests icicle plot

Podemos ver que pasamos la mayor parte del tiempo (más de 10/11 segundos) en la agrupación de conexiones. El uso de una sesión para permitir que varias llamadas HTTP utilicen la agrupación de conexiones comunes y compartan recursos debería reducir este tiempo. Veámoslo.

Si utilizamos un objeto de sesión para las llamadas a la API Number Insight, podemos ver la diferencia:

with requests.Session() as session:

    for i in range(100):
        phone_number = str(441614960100 + i)
        params['number'] = phone_number
    
        with session.get(
            'https://api.nexmo.com/ni/basic/json',
            params=params,
        ) as response:
            number_conversions[phone_number] = response.json()[
                'international_format_number'
            ]

Esta vez, obtenemos esta salida: Time elapsed is: 4.058261167003366 seconds. ¡casi tres veces más rápido! Podemos ver en este gráfico de carámbano del programa que nuestro sistema gastó menos tiempo proporcionalmente en la agrupación de conexiones, y el tiempo que se utilizó se gastó mucho más eficientemente que cuando se hicieron 100 peticiones separadas como hicimos anteriormente.

An icicle plot showing how much time was spent executing each part of the program for the case where we use a session object with RequestsSession requests case icicle plot

Así que podemos ver que mediante el uso de una sesión, puede manejar automáticamente cosas como cookies y cabeceras, haciendo que su código más limpio y más eficiente. Pero, ¿y si necesitas aún más control sobre tus peticiones HTTP o quieres afinar tus conexiones? Es el momento del Nivel 3.

Nivel 3: Aprovechamiento de un adaptador HTTP para configuraciones avanzadas

Ahora estamos listos para el nivel más avanzado, en el que personalizamos el comportamiento de las peticiones HTTP a un nivel muy bajo, incluyendo configuraciones como la agrupación de conexiones y los reintentos. Requests nos permite establecer estas propiedades de bajo nivel utilizando un adaptador HTTP, que puedes montar en un objeto Session para utilizar tu configuración personalizada para toda la sesión. En Requests, utilizamos un objeto llamado HTTPAdapter para hacer esto.

A continuación se explica cómo utilizar el objeto HTTPAdapter para configurar opciones personalizadas:

import requests
from requests.adapters import HTTPAdapter

session = requests.Session()

# Create an HTTPAdapter object and configure connection pooling and retries
adapter = HTTPAdapter(pool_connections=20, pool_maxsize=5, max_retries=3)

# Mount the HTTPAdpater object to the session
session.mount('https://', adapter)

response = session.get('https://example.com')

Esto también puede combinarse con valores específicos de la solicitud, como el tiempo de espera (por ejemplo session.get('https://example.com', timeout=10)) para proporcionar un control detallado por solicitud.

El uso de un adaptador HTTP permite controlar el modo en que se realizan las peticiones HTTP, lo que hace posible ajustar el comportamiento de la aplicación para satisfacer requisitos específicos.

Bonificación: Uso de un SDK de Python adecuado

En SDK Python de Vonageutilizamos todas estas técnicas para enviar solicitudes de la manera más eficaz. Utilizamos una sesión y permitimos que los usuarios configuren los parámetros de solicitud y del adaptador HTTP cuando crean un objeto Client objeto. El siguiente código muestra cómo ejecutar la misma solicitud anterior para realizar 100 llamadas a Number Insight API, pero esta vez utiliza el SDK Python de Vonage para realizar las llamadas.

import vonage

client = vonage.Client(key='MY_API_KEY', secret='MY_API_SECRET')
number_conversions = {}

for i in range(100):
    phone_number = str(1614960100 + i)
    response = client.number_insight.get_basic_number_insight(
        country='GB', number=phone_number
    )
    number_conversions[phone_number] = response['international_format_number']

Si desea personalizar alguno de los valores predeterminados como pool_connections o solicitar timeoutpuede especificarlo al crear el objeto client objeto.

La ventaja de usar el SDK de Vonage para llamar a las API de Vonage es que no tienes que preocuparte por la lógica de la solicitud. Especificas lo que quieres que suceda y el SDK se encarga de ello por ti. Muchos otros servicios tienen SDK en la misma línea para abstraer la lógica que podría no importarte, pero te permiten sumergirte en los detalles si lo necesitas o lo deseas.

Conclusión

En esta entrada del blog, hemos explorado los tres niveles de peticiones HTTP con el módulo Requests de Python, desde peticiones básicas hasta personalización avanzada usando sesiones y adaptadores HTTP. Al dominar estos niveles, estarás bien equipado para abordar una amplia gama de tareas relacionadas con la web en tus proyectos de Python.

Recuerda que cada nivel se basa en el anterior, así que empieza por lo básico y ve subiendo de nivel progresivamente a medida que evolucionan los requisitos de tu proyecto. Las peticiones HTTP son un aspecto fundamental del desarrollo web, y con el módulo Requests tienes a tu disposición una potente herramienta para gestionarlas con eficacia.

Si quieres comenzar a usar las API de Vonage, puedes inscribirte para obtener una cuenta de desarrollador gratuita (¡con créditos gratis!)

Si tienes alguna pregunta sobre este artículo, no dudes en ponerte en contacto con nosotros en nuestro Slack de la comunidad de Vonage y pregúntanos allí, o enviándonos un mensaje en X, antes conocido como Twitter.

Así que adelante, experimenta con diferentes niveles de peticiones HTTP y haz que tus aplicaciones Python interactúen con la web como un profesional.

Compartir:

https://a.storyblok.com/f/270183/400x400/92109caf6a/max-kahan.png
Max KahanVonage Antiguo miembro del equipo

Max es un defensor de los desarrolladores de Python e ingeniero de software interesado en las API de comunicaciones, el aprendizaje automático, la experiencia de los desarrolladores y el baile. Su formación es en Física, pero ahora trabaja en proyectos de código abierto y hace cosas para mejorar la vida de los desarrolladores.