Manejo de errores 429 y 50x en APIs de Wildberries y Ozon
Al extraer datos de las APIs de Wildberries y Ozon, los desarrolladores suelen encontrarse con errores 429 (demasiadas solicitudes) y 50x (errores del servidor). Estos surgen por la alta carga en los endpoints. La solución típica del soporte técnico son los reintentos. Vamos a ver tres estrategias sólidas: manejo básico de reintentos, optimización del volumen de solicitudes y monitoreo con recargas parciales.
Manejo básico de reintentos
Empieza tratando los errores 429 y 50x como interrupciones normales. Implementa lógica de reintentos con retroceso exponencial y analiza cabeceras como X-Ratelimit-Retry. Esto reduce bloqueos y aumenta la resistencia.
Aquí va una función de ejemplo para solicitudes POST con reintentos:
def get_oz(url, heads, params, max_retries=5, timeout=30):
result = {}
for retries in range(1, max_retries + 1):
try:
response = requests.post(url, headers=heads, json=params, timeout=timeout)
except requests.RequestException as e:
print(f'!!! Error de red en intento {retries}: {e}!!!')
time.sleep(2 * retries)
continue
# 200 significa éxito
if response.status_code == 200:
return response.json()
# 429 - Demasiadas solicitudes, pausa inteligente y reintento
elif response.status_code == 429:
pause_time = 2 ** retries
# X-Ratelimit-Retry - Truco de Wildberries, Ozon podría agregarlo algún día
if 'X-Ratelimit-Retry' in response.headers:
pause_time = int(response.headers['X-Ratelimit-Retry']) + 5
print(f'get_oz: ! -Demasiadas solicitudes- en intento {retries}. Pausando {pause_time} seg')
time.sleep(pause_time)
# Errores 5xx - pausa y reintento
elif 500 <= response.status_code < 600:
pause_time = 2 ** retries
print(f'get_oz: ! -Error {response.status_code}- en intento {retries}. Pausando {pause_time} seg')
time.sleep(pause_time)
# Cualquier otro error - ¡sal de ahí!
else:
print(f'get_oz: !!! ¡Fallo al obtener datos de API! código: {response.status_code}')
return None
print(f'get_oz: !!! Todos los {max_retries} intentos fallaron')
return None
- 5 reintentos manejan la mayoría de cargas típicas.
- Maneja bucles de paginación (offset/página) a un nivel superior.
- En fallo total, retrocede una hora o más.
Esto encaja perfectamente en cualquier pipeline ETL para APIs.
Optimización del volumen de datos
Solicitudes grandes (como transacciones de una semana) provocan errores en páginas posteriores de paginación. Divídelas en lotes pequeños e independientes: por día, categoría o filtros. Guarda cada lote en tu base de datos de inmediato — perder uno no borra tu progreso.
Ventajas:
- Menos páginas por solicitud (1–3 vs. 20).
- Reintentos independientes por lote.
- Guardados parciales en fallos.
Ejemplo: Carga de transacciones de Ozon por día:
date_from = today() - timedelta(days=7)
date_to = today() - timedelta(days=1)
current_date = date_from
delta = timedelta(days=1)
# Bucle por días desde date_from hasta date_to
while current_date <= date_to:
transactions_oneday = pd.DataFrame([])
url = "https://api-seller.ozon.ru/v3/finance/transaction/list"
ipage = 1
all_pages_data = []
while True:
data = {
"filter": {
"date": {
"from": str(current_date) + "T00:00:00.000Z",
"to": str(current_date) + "T23:59:59.999Z"
}
},
"page": ipage,
"page_size": 1000
}
dd = []
apioz_response = get_oz(url, headers, data, 5)
if len(apioz_response) > 0 :
dd = apioz_response['result']['operations']
all_pages_data.extend(dd)
else:
print(f'!!! Respuesta vacía de API')
# Si la página tiene <1000 filas, es la última - salir
if len(dd) < 1000: break
ipage +=1
transactions_oneday = pd.DataFrame(all_pages_data)
# Exporta a BD inmediatamente lo obtenido de la API
export_to_db('oz_transactions', transactions_oneday)
# Siguiente día
current_date += delta
Bucles anidados pueden parecer desordenados, pero la fiabilidad se dispara.
Monitoreo y recargas parciales
Para automatización total, añade una red de seguridad: monitoreo en segundo plano. Tras la ejecución principal (digamos, 6–7 AM), revisa logs/BD cada hora (8–12 AM).
- Revisa estado de la última tarea.
- Verifica integridad de datos (huecos en fechas).
- Activa reintentos dirigidos solo para fragmentos faltantes.
Esto minimiza intervenciones manuales, sobre todo en actualizaciones diarias.
Lecciones clave
- Usa retroceso exponencial con cabeceras de reintento para 429.
- Divide solicitudes grandes en lotes diarios/filtros con guardados inmediatos.
- Añade monitoreo horario post-colección para rellenar huecos.
- 5 reintentos cubren el 95% de fallos; fallos totales esperan una hora+.
- Integra en ETL sin ataduras estrictas a paginación.
— Editorial Team
Aún no hay comentarios.