我正在 API (FastAPI) 中创建一个端点,该端点需要向具有非常大响应的外部 API 发送多个请求。外部 API 是分页的,我需要获取所有页面并在我的 API 中返回它们。通常,向外部 API 发出 15-25 个请求,在我当前的实现中可能需要长达 60 秒的时间。我想知道是否有更好的库(例如:asyncio)或不同的实现来潜在地减少我的端点中的响应时间。
这是我当前的(简化的)实现:
def load_url(url, page, parameters):
parameters["page"] = page
try:
response = requests.get(url=url, params=parameters)
return response
except Exception as e:
# handle exception
def get_response(total_page_number, url, parameters):
items = []
CONNECTIONS = 100
with concurrent.futures.ThreadPoolExecutor(max_workers=CONNECTIONS) as executor:
future_to_url = (
executor.submit(load_url, url, page, parameters)
for page in range(1, total_page_number + 1)
)
for future in concurrent.futures.as_completed(future_to_url):
try:
data = future.result()
except Exception as exc:
# handle exception
print(exc)
finally:
items += data
return items
最初我是一项一项地执行请求,这(可以预见)速度较慢。 (一对一的平均时间为 60 秒,当前解决方案的平均时间为 36 秒)想知道我是否做错了什么,并且非常感谢对此的一些指导。
(此代码是在堆栈溢出时从此线程获取并修改的,这是一个不同的用例(仅发送头请求))
您可以尝试此代码并执行时间响应吗,因为我没有您运行的网址。这是一个 I/O 密集型任务,所以我使用
aiohttp
。
import asyncio
import aiohttp
async def load_url(client, url, header, page, parameters):
parameters["page"] = page
resp = await client.get(url, headers=header, params=parameters, timeout=300)
if resp.status != 200:
raise Exception(resp.text)
data = await resp.json()
return data
async def add_task(parameters, url, header, total_page_number):
async with aiohttp.ClientSession(
connector=aiohttp.TCPConnector(force_close=True, limit=50)
) as client:
tasks = []
for page in range(1, total_page_number + 1):
tasks.append(
asyncio.ensure_future(
load_url(client, url, header, page, parameters)
)
)
list_result = await asyncio.gather(*tasks)
return list_result
def get_response(parameters, url, header, total_page_number):
return asyncio.run(add_task(parameters, url, header, total_page_number))