You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中不使用aiohttp如何正确发起异步请求?(HubSpot场景)

解决方案

在仅内置requests包的HubSpot自定义代码环境中,你有两种可行方式实现高效的异步请求,无需额外安装依赖:

方案1:优化线程池式异步(代码简洁,复用requests能力)

虽然本质还是基于线程池,但相比asyncio.to_thread,通过显式配置ThreadPoolExecutor可以更精准控制资源使用,适配HubSpot的内存和时长限制。这种方式能直接复用requests的所有特性(如请求头、认证、超时处理等),代码改动极小。

示例代码:

import asyncio
import requests
from concurrent.futures import ThreadPoolExecutor

# 根据API速率限制和内存情况调整线程数,建议3-5
MAX_WORKERS = 4

async def async_request(url, **kwargs):
    with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
        loop = asyncio.get_event_loop()
        # 将requests.get提交到线程池执行
        response = await loop.run_in_executor(executor, requests.get, url, **kwargs)
        return response

# 批量获取记录示例
async def sync_records(url_list):
    # 创建所有请求任务
    tasks = [async_request(url, headers={"Authorization": "Bearer YOUR_TOKEN"}) for url in url_list]
    # 并发执行并收集结果
    responses = await asyncio.gather(*tasks)
    # 过滤有效响应并解析
    return [resp.json() for resp in responses if resp.status_code == 200]

方案2:纯异步IO实现(无多线程,低内存开销)

如果需要严格的异步非阻塞实现,可以基于Python标准库的asyncio和套接字功能,手动实现HTTP请求逻辑。这种方式不依赖线程池,内存占用更低,但需要自己处理HTTP协议的细节(如HTTPS、请求头、响应解析等)。

示例代码:

import asyncio
from urllib.parse import urlparse
import json

async def async_http_get(url, headers=None):
    parsed_url = urlparse(url)
    host = parsed_url.netloc
    path = parsed_url.path or "/"
    if parsed_url.query:
        path += f"?{parsed_url.query}"
    
    # 建立异步SSL连接
    reader, writer = await asyncio.open_connection(host, 443, ssl=True)
    
    # 构造HTTP请求头
    request_headers = [
        f"GET {path} HTTP/1.1",
        f"Host: {host}",
        "Connection: close",
    ]
    if headers:
        for key, value in headers.items():
            request_headers.append(f"{key}: {value}")
    request_headers.append("\r\n")
    request = "\r\n".join(request_headers).encode("utf-8")
    
    # 发送请求
    writer.write(request)
    await writer.drain()
    
    # 读取响应
    response_data = await reader.read()
    writer.close()
    await writer.wait_closed()
    
    # 解析响应
    header_part, body_part = response_data.split(b"\r\n\r\n", 1)
    status_line = header_part.split(b"\r\n")[0].decode("utf-8")
    status_code = int(status_line.split()[1])
    
    if status_code == 200:
        return json.loads(body_part)
    return None

# 批量请求示例
async def fetch_multiple_records(url_list, auth_headers):
    tasks = [async_http_get(url, headers=auth_headers) for url in url_list]
    return await asyncio.gather(*tasks)

方案选择建议

  • 若你的请求逻辑依赖requests的高级特性(如自动重定向、会话保持、复杂认证),优先选方案1,代码维护成本低,且在HubSpot的资源限制下足够高效。
  • 若你需要极致的内存效率或避免线程池开销,可选择方案2,但需自行处理HTTP协议的细节(如超时、错误重试等)。

内容的提问来源于stack exchange,提问作者Jeroen Vermunt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 03:23:12