首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >循环内部的Python异步请求调用

循环内部的Python异步请求调用
EN

Stack Overflow用户
提问于 2020-12-05 22:59:15
回答 1查看 469关注 0票数 0

我正在尝试用FastAPI开发Python,我必须从几个URL下载一系列图像,放在一个foor循环中。

问题是,我必须检索图像,但我不能这样做,因为它是一个正常的for循环中的异步操作。

这是我的代码:

代码语言:javascript
复制
@app.post("/v1/img_color")
async def img_color(request: Request):
    body = await request.json()
    images = []
    
    for img in body['images']:
        img_id = img['id']
        img_url = img['url']
        r = requests.get(img_url)
        content = await r.content
        dw_image = Image.open(BytesIO(content))
        images.append(dw_image)
    

    return images

但它给了我以下错误:

TypeError:在“等待”表达式中不能使用对象字节

我怎么才能解决这个问题?我已经搜索过这个问题,并找到了一些关于asyncio的解决方案,但我无法让它们发挥作用。

更新:

按照从await中删除await r.content代码的建议,我遇到了另一个错误,即:

TypeError(‘无法将字典更新序列元素#0转换为序列’),TypeError('vars()参数必须具有dict属性‘)

我不太明白这一点,因为我可以从原始POST请求的JSON正文中完美地检索url .

回溯

代码语言:javascript
复制
Traceback (most recent call last):
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 388, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 45, in __call__
    return await self.app(scope, receive, send)
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\fastapi\applications.py", line 190, in __call__
    await super().__call__(scope, receive, send)
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\starlette\applications.py", line 111, in __call__
    await self.middleware_stack(scope, receive, send)
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
    raise exc from None
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\starlette\exceptions.py", line 82, in __call__
    raise exc from None
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\starlette\exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\starlette\routing.py", line 566, in __call__
    await route.handle(scope, receive, send)
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\starlette\routing.py", line 227, in handle
    await self.app(scope, receive, send)
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\starlette\routing.py", line 41, in app
    response = await func(request)
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\fastapi\routing.py", line 196, in app
    response_data = await serialize_response(
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\fastapi\routing.py", line 124, in serialize_response

    return jsonable_encoder(response_content)
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\fastapi\encoders.py", line 102, in jsonable_encoder
    jsonable_encoder(
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\fastapi\encoders.py", line 140, in jsonable_encoder
    return jsonable_encoder(
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\fastapi\encoders.py", line 88, in jsonable_encoder
    encoded_value = jsonable_encoder(
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\fastapi\encoders.py", line 88, in jsonable_encoder
    encoded_value = jsonable_encoder(
  File "d:\users\kendo\documents\git\empathy\kala_api\env\lib\site-packages\fastapi\encoders.py", line 139, in jsonable_encoder
    raise ValueError(errors)
ValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-06 12:47:37

requests.get()是同步的。没什么可等的了。调用完成后,内容字节是完全可用的。删除await

代码语言:javascript
复制
for img in body['images']:
    r = requests.get(img['url'])
    dw_image = Image.open(BytesIO(r.content))
    images.append( (img['id'], dw_image) )

如果你有冒险精神(或者想要了解迪克特的理解),你可以用一行替换整个循环。

代码语言:javascript
复制
@app.post("/v1/img_color")
async def img_color(request: Request):
    body = await request.json()
    return {img['id']: Image.open(BytesIO(requests.get(img['url']).content)) for img in body['images']}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65162854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档