Python 裸 HTTP 重试(requests)
python · raw http什么时候用
你用 requests 或 httpx 直调 POST /v1/systemone,并希望重试逻辑在自己代码里看得见。它重试 408、429 与整个 5xx 家族(含 529),遵守 Retry-After,且绝不重试校验或鉴权类错误。
# jev_retry.py — raw-HTTP retry for POST /v1/systemone.
# Documented statuses: 401 · 422 · 429 · 529 (docs.typesafe.ai/api.md).
# The retry mechanics below are general engineering practice — the official
# docs publish no numeric limits, so none are assumed here.
import os
import random
import time
import requests
URL = "https://api.typesafe.ai/v1/systemone"
# Mirrors the official SDK's default retryable set ({408, 429, all 5xx});
# 529 is listed explicitly — it is TypeSafe's documented overload status.
RETRYABLE = {408, 429, 500, 502, 503, 504, 529}
def evaluate(state: str, questions: dict, max_attempts: int = 4) -> dict:
delay = 0.5 # first backoff; doubles per attempt, capped at 5 s (SDK shape)
resp = None
for _ in range(max_attempts):
resp = requests.post(
URL,
headers={
"Authorization": f"Bearer {os.environ['TYPESAFE_API_KEY']}",
"Content-Type": "application/json",
},
json={"model": "jev-latest", "state": state, "questions": questions},
timeout=5.0,
)
if resp.status_code < 400:
return resp.json()
if resp.status_code not in RETRYABLE:
# 400/401/403/404/422: identical bytes in, identical error out.
resp.raise_for_status()
# Honor the server's requested wait when it sends one:
# Retry-After (seconds). The official SDK also parses retry-after-ms.
wait = resp.headers.get("Retry-After")
sleep_s = (
float(wait) if wait else min(delay, 5.0) * random.uniform(0.75, 1.0)
)
time.sleep(sleep_s)
delay *= 2
resp.raise_for_status() # budget spent on a retryable status
raise RuntimeError("retry budget spent")可重试集合对齐官方 SDK 默认值({408, 429, 全部 5xx}),并把 529 显式列出以便阅读。5 秒封顶对应 SDK 文档中的 backoff_max。