如何优化这段代码?使用python的并发请求(并发库)

yx2lnoni  于 11个月前  发布在  Python
关注(0)|答案(1)|浏览(109)

我正在我的API(FastAPI)中创建一个端点,它需要向外部API发送多个请求,并具有非常大的响应。外部API是分页的,我需要获取所有页面并在我的API中返回它们。通常是15-25个请求到外部API,这可能需要60秒。我想知道是否有更好的库(例如:Penccio)或不同的实现,以潜在地减少我的端点中的响应时间。
以下是我的当前(简化)实现:

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秒平均为目前的解决方案)想知道我是否做错了什么,真的很感激一些指导。
(This在堆栈溢出时从this thread获取并修改代码,这是一个不同的用例(仅发送头部请求))

lf5gs5x2

lf5gs5x21#

你能试试这段代码并执行时间响应吗?因为我没有你运行的URL。这是一个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))

字符串

相关问题