Why does adding async to Fastapi function gives me the "'coroutine' object is not iterable" error
I only get the error after I add the async keyword at the front of my function as follows, when I call the function/endpoint using Swagger UI:
@router.post("/create")
async def job_create_post_view(
request: Request,
is_htmx=Depends(is_htmx),
db:Session=Depends(get_db),
short_description: str = Form(default=None),
long_description: str = Form(default=None),
.....
job_image:Optional[UploadFile]=File(...)
):
The error is as follows:
[TypeError("'coroutine' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]
I am trying to do something asynchronous inside the function:
contents = await job_image.read()
This is the stack trace:
Traceback (most recent call last):
File "D:\TEMP\job_search - revert\venv\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 366, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 75, in __call__
return await self.app(scope, receive, send)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\fastapi\applications.py", line 269, in __call__
await super().__call__(scope, receive, send)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\starlette\applications.py", line 124, in __call__
await self.middleware_stack(scope, receive, send)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\starlette\middleware\errors.py", line 184, in __call__
raise exc
File "D:\TEMP\job_search - revert\venv\lib\site-packages\starlette\middleware\errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\starlette\middleware\cors.py", line 92, in __call__
await self.simple_response(scope, receive, send, request_headers=headers)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\starlette\middleware\cors.py", line 147, in simple_response
await self.app(scope, receive, send)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\starlette\middleware\authentication.py", line 48, in __call__
await self.app(scope, receive, send)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\starlette\exceptions.py", line 93, in __call__
raise exc
File "D:\TEMP\job_search - revert\venv\lib\site-packages\starlette\exceptions.py", line 82, in __call__
await self.app(scope, receive, sender)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 21, in __call__
raise e
File "D:\TEMP\job_search - revert\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\starlette\routing.py", line 670, in __call__
await route.handle(scope, receive, send)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\starlette\routing.py", line 266, in handle
await self.app(scope, receive, send)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\starlette\routing.py", line 65, in app
response = await func(request)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\fastapi\routing.py", line 235, in app
response_data = await serialize_response(
File "D:\TEMP\job_search - revert\venv\lib\site-packages\fastapi\routing.py", line 149, in serialize_response
return jsonable_encoder(response_content)
File "D:\TEMP\job_search - revert\venv\lib\site-packages\fastapi\encoders.py", line 144, in jsonable_encoder
raise ValueError(errors)
ValueError: [TypeError("'coroutine' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]
I had the same error.
I found out that the problem was from calling a async function without putting await before calling it.
The function which I was trying to call, was like something like this:
async def func1():
...
async def func2():
x = func1()
...
So, the problem got resolved when I edited like this:
async def func1():
...
async def func2():
x = await func1()
...
[TypeError("'coroutine' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')] usually happened when the developer made a mistake inside the async function like this [Mistake]:
@app.get("/")
async def read_root():
return fetch_all_todos()
but the correct behavior for async is like this [Correct]:
@app.get("/")
async def read_root():
response = await fetch_all_todos()
return response
You need to put await in a variable and then return it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With