A veces cuando trabajamos en odoo.sh con miles de publicaciones de Mercadolibre obtenemos el error
[Errno -5] No address associated with hostname'))
el cual se presenta de forma aleatoria. Pero ocurre muchas veces. Y tiene que ver con el hecho que realizamos muchas llamadas en un período de tiempo muy corto a un particular endpoint de Mercadolibre. Concretamente al endpoint items realizando un POST (lo noté actualizando precios).
A que se debe esto? Los usuarios del API de Mercadolibre rápido entienden algo. Que para poder trabajar bien con Mercadolibre necesitan estar constantemente leyendo o actualizando sus publicaciones en Mercadolibre. Lo que implica estar todo el tiempo usando el API de Mercadolibre, sobre todo el endpoint items (el cual administra las publicaciones).
Como protege Mercadolibre su infraestructura de estos usuarios? Muchas veces Mercadolibre demora las respuestas a estas conecciones abusivas, o puede descartarlas (en lugar de rechazarlas). Esto se evidencia como errores de resolución de DNS, errores de conección, o errores 403 (cuando llegamos a conectarnos).
Que podemos hacer para solucionar este problema? En lugar de hacer el tradicional requests.get, necesitamos trabajar con un cliente HTTP más robusto que re-intente de forma automática frente a las fallas. En lugar de:
response = requests.get('api.mercadolibre.com/items/xxx',headers=headers)
Debemos conectarnos de la siguiente manera:
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
retry = Retry(
total=5,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504],
)
adapter = HTTPAdapter(max_retries=retry)
session.mount("https://", adapter)
response = session.get("https://api.mercadolibre.com/items/MLA1916537820")
Donde primero definimos una sesión que nos permite reutilizar la configuración con la que trabajamos.
session = requests.Session()
Luego definimos como queremos comportarnos en caso de reintentar la conección. Por ejemplo lacantidad de reconecciones, cuanto aumenta el tiempo re reconección, y sobre todo que errores atender en los reintentos (lo que nos permite descartar otros errores, por ejemplo de autenticación)
adapter = HTTPAdapter(max_retries=retry)
session.mount("https://", adapter)
Se agrega este comportamiento a todas las conecciones que se hacen mediante HTTPS. Esto va a hacer que cada pedido del API reintente en forma automática en caso de falla y sea más robusta.
Como se usa? De la siguiente manera:
resp = sessions.get('https://api.mercadolibre.com/items/MLA22222',headers=headers)
Como pueden ver no es dificil modificar el código con el que trabajamos para incorporar este comportamiento.