battery/apis.py

59 lines
1.9 KiB
Python

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
import httpx
import logging
logger = logging.getLogger(__name__)
# 配置更合理的超时时间
DEFAULT_TIMEOUT = httpx.Timeout(connect=10.0, read=30.0, write=10.0, pool=5.0)
# 重试装饰器配置
def retry_decorator():
return retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=2, max=10),
retry=retry_if_exception_type(
(httpx.ConnectTimeout, httpx.ConnectError, httpx.ReadTimeout)
),
reraise=True,
before=lambda retry_state: logger.warning(
f"请求失败,第 {retry_state.attempt_number} 次重试..."
)
)
@retry_decorator()
async def send_battery_cell_to_server(url: str, data):
"""发送电池单元数据到服务器,包含重试机制"""
try:
async with httpx.AsyncClient(
timeout=DEFAULT_TIMEOUT,
limits=httpx.Limits(max_connections=100, max_keepalive_connections=20),
follow_redirects=True
) as client:
logger.info(f"正在发送请求到: {url}")
logger.debug(f"发送数据: {data}")
response = await client.post(
url,
json={"data": data},
headers={
"Content-Type": "application/json",
"User-Agent": "BatteryDataSender/1.0"
}
)
# 记录响应信息
logger.info(f"响应状态码: {response.status_code}")
logger.debug(f"响应内容: {response.text}")
response.raise_for_status()
return response.json()
except httpx.TimeoutException as e:
logger.error(f"请求超时: {str(e)}")
raise
except httpx.HTTPError as e:
logger.error(f"HTTP请求错误: {str(e)}")
raise