使用tqdm创建的进度条的asyncio aiohttp。

27

我试图将一个tqdm进度条集成到使用Python 3.5的aiohttp生成的POST请求中进行监视。我有一个工作正常的进度条,但似乎无法使用as_completed()收集结果。感激任何指针。

我发现的示例表明使用以下模式,这与Python 3.5的async def定义不兼容:

for f in tqdm.tqdm(asyncio.as_completed(tasks), total=len(coros)):
    yield from f

没有进度条的工作(尽管被编辑过)异步代码:

def async_classify(records):

    async def fetch(session, name, sequence):
        url = 'https://app.example.com/api/v0/search'
        payload = {'sequence': str(sequence)}
        async with session.post(url, data=payload) as response:
            return name, await response.json()

    async def loop():
        auth = aiohttp.BasicAuth(api_key)
        conn = aiohttp.TCPConnector(limit=100)
        with aiohttp.ClientSession(auth=auth, connector=conn) as session:
            tasks = [fetch(session, record.id, record.seq) for record in records]
            responses = await asyncio.gather(*tasks)    
        return OrderedDict(responses)

这是我尝试修改loop()但未成功的尝试:

async def loop():
    auth = aiohttp.BasicAuth(api_key)
    conn = aiohttp.TCPConnector(limit=100)
    with aiohttp.ClientSession(auth=auth, connector=conn) as session:
        tasks = [fetch(session, record.id, record.seq) for record in records]
        for f in tqdm.tqdm(asyncio.as_completed(tasks), total=len(tasks)):
            await f
        responses = await asyncio.gather(f)
        print(responses)
1个回答

42

await f 返回一个单一的响应。为什么要将已经完成的 Future 传递给 asyncio.gather(f) 是不清楚的。

尝试:

responses = []
for f in tqdm.tqdm(asyncio.as_completed(tasks), total=len(tasks)):
    responses.append(await f)

Python 3.6 实现了PEP 530 -- 异步推导式

responses = [await f
             for f in tqdm.tqdm(asyncio.as_completed(tasks), total=len(tasks))]

现在它可以在async def函数内部工作。


@j-f-sebastien 很好!谢谢你让我知道。 - Bede Constantinides

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接