RuntimeError: cannot reuse already awaited coroutine
@asynccontextmanager
async def get_connection(
postgres: Postgresql = postgresql,
) -> Cursor:
"""Get async connection to postgresql of pool."""
async with postgres.get_connect() as connection:
async with (await connection.cursor(cursor_factory=RealDictCursor)) as c:
yield c
class Postgresql(BaseConnector):
uri: str
pool: typing.Optional[typing.AsyncContextManager[aiopg.Pool]] = None
def __init__(self, uri: str):
self.uri = uri
@asynccontextmanager
async def get_connect(self) -> typing.AsyncIterator[Connection]:
if self.pool is None:
self.pool = aiopg.create_pool(dsn=self.uri)
async with self.pool as pool:
async with pool.acquire() as conn:
yield conn
class UserRepository:
@classmethod
@collect_response
async def create(cls, cmd: models.CreateUserCommand) -> models.User:
q = f"""
insert into users(
uid, username, password
) values (
'{uuid4()}',
%(username)s,
%(password)s
)
returning uid, username, password;
"""
async with get_connection() as c:
await c.execute(q, cmd.to_dict(show_secrets=True))
return await c.fetchone()
@router.post(
"/",
response_model=models.User,
status_code=status.HTTP_201_CREATED,
summary="Create user",
response_model_exclude={"password"},
)
async def create_user(
cmd: models.CreateUserCommand
) -> Any:
await cmd.set_hash_password()
return await UserRepository.create(cmd=cmd)
Почему не работает?, срабатывает только один раз Полный трейс ошибки:
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/Users/eric/projects/test-task-for-victory/victory/__main__.py", line 20, in <module>
main()
└ <function main at 0x1005884a0>
File "/Users/eric/projects/test-task-for-victory/victory/__main__.py", line 8, in main
uvicorn.run(
│ └ <function run at 0x1017d7ce0>
└ <module 'uvicorn' from '/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/uvicorn/__init__.py'>
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/uvicorn/main.py", line 569, in run
server.run()
│ └ <function Server.run at 0x1019056c0>
└ <uvicorn.server.Server object at 0x101ff3b50>
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/uvicorn/server.py", line 60, in run
return asyncio.run(self.serve(sockets=sockets))
│ │ │ │ └ None
│ │ │ └ <function Server.serve at 0x101905760>
│ │ └ <uvicorn.server.Server object at 0x101ff3b50>
│ └ <function run at 0x1010b8fe0>
└ <module 'asyncio' from '/opt/homebrew/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyn...
File "/opt/homebrew/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 190, in run
return runner.run(main)
│ │ └ <coroutine object Server.serve at 0x101f6b120>
│ └ <function Runner.run at 0x101150b80>
└ <asyncio.runners.Runner object at 0x1025ccf50>
File "/opt/homebrew/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
│ │ │ └ <Task pending name='Task-1' coro=<Server.serve() running at /Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-pac...
│ │ └ <method 'run_until_complete' of 'uvloop.loop.Loop' objects>
│ └ <uvloop.Loop running=True closed=False debug=False>
└ <asyncio.runners.Runner object at 0x1025ccf50>
> File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 419, in run_asgi
result = await app( # type: ignore[func-returns-value]
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x1040559d0>
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x1044289d0>>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x1044289...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <fastapi.applications.FastAPI object at 0x104045290>
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x1040559d0>
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/fastapi/applications.py", line 270, in __call__
await super().__call__(scope, receive, send)
│ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x1044289d0>>
│ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x1044289...
└ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/starlette/applications.py", line 124, in __call__
await self.middleware_stack(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x1044289d0>>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x1044289...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <starlette.middleware.errors.ServerErrorMiddleware object at 0x10406acd0>
└ <fastapi.applications.FastAPI object at 0x104045290>
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/starlette/middleware/errors.py", line 184, in __call__
raise exc
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
│ │ │ │ └ <function ServerErrorMiddleware.__call__.<locals>._send at 0x10443dbc0>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x1044289...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <starlette.middleware.exceptions.ExceptionMiddleware object at 0x10406ab10>
└ <starlette.middleware.errors.ServerErrorMiddleware object at 0x10406acd0>
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
raise exc
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
await self.app(scope, receive, sender)
│ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x10443dd00>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x1044289...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <fastapi.middleware.asyncexitstack.AsyncExitStackMiddleware object at 0x10406ae50>
└ <starlette.middleware.exceptions.ExceptionMiddleware object at 0x10406ab10>
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
raise e
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
│ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x10443dd00>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x1044289...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <fastapi.routing.APIRouter object at 0x1038e1c90>
└ <fastapi.middleware.asyncexitstack.AsyncExitStackMiddleware object at 0x10406ae50>
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/starlette/routing.py", line 706, in __call__
await route.handle(scope, receive, send)
│ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x10443dd00>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x1044289...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <function Route.handle at 0x102a73560>
└ APIRoute(path='/api/user/', name='create_user', methods=['POST'])
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/starlette/routing.py", line 276, in handle
await self.app(scope, receive, send)
│ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x10443dd00>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x1044289...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
│ └ <function request_response.<locals>.app at 0x10405b420>
└ APIRoute(path='/api/user/', name='create_user', methods=['POST'])
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/starlette/routing.py", line 66, in app
response = await func(request)
│ └ <starlette.requests.Request object at 0x1044287d0>
└ <function get_request_handler.<locals>.app at 0x10405b4c0>
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/fastapi/routing.py", line 237, in app
raw_response = await run_endpoint_function(
└ <function run_endpoint_function at 0x102a71940>
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/fastapi/routing.py", line 163, in run_endpoint_function
return await dependant.call(**values)
│ │ └ {'cmd': CreateUserCommand(username='varick', password='$2b$12$q0QZ2KYHjvVgOWUE4wLP0uAloz3ARZG3opt37hxmHEhggVZ6Tctdu')}
│ └ <function create_user at 0x1038a2de0>
└ <fastapi.dependencies.models.Dependant object at 0x104068bd0>
File "/Users/eric/projects/test-task-for-victory/victory/web/api/user/views.py", line 24, in create_user
return await UserRepository.create(cmd=cmd)
│ │ └ CreateUserCommand(username='varick', password='$2b$12$q0QZ2KYHjvVgOWUE4wLP0uAloz3ARZG3opt37hxmHEhggVZ6Tctdu')
│ └ <classmethod(<function UserRepository.create at 0x1038a3060>)>
└ <class 'victory.db.repository.user.UserRepository'>
File "/Users/eric/projects/test-task-for-victory/victory/db/repository/handlers/handle_exception.py", line 28, in wrapper
return await func(*args, **kwargs)
│ │ └ {'cmd': CreateUserCommand(username='varick', password='$2b$12$q0QZ2KYHjvVgOWUE4wLP0uAloz3ARZG3opt37hxmHEhggVZ6Tctdu')}
│ └ (<class 'victory.db.repository.user.UserRepository'>,)
└ <function collect_response.<locals>.inner at 0x1038a2fc0>
File "/Users/eric/projects/test-task-for-victory/victory/db/repository/handlers/collect_response.py", line 35, in inner
response = await fn(*args, **kwargs)
│ │ └ {'cmd': CreateUserCommand(username='varick', password='$2b$12$q0QZ2KYHjvVgOWUE4wLP0uAloz3ARZG3opt37hxmHEhggVZ6Tctdu')}
│ └ (<class 'victory.db.repository.user.UserRepository'>,)
└ <function UserRepository.create at 0x1038a2f20>
File "/Users/eric/projects/test-task-for-victory/victory/db/repository/user.py", line 26, in create
async with get_connection() as c:
└ <function get_connection at 0x102f70400>
File "/opt/homebrew/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/contextlib.py", line 204, in __aenter__
return await anext(self.gen)
│ └ <async_generator object get_connection at 0x104077a40>
└ <contextlib._AsyncGeneratorContextManager object at 0x1040ab550>
File "/Users/eric/projects/test-task-for-victory/victory/db/repository/connection.py", line 18, in get_connection
async with postgres.get_connect() as connection:
│ └ <function Postgresql.get_connect at 0x1038a1120>
└ <victory.db.connectors.postgresql.Postgresql object at 0x1025a1290>
File "/opt/homebrew/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/contextlib.py", line 204, in __aenter__
return await anext(self.gen)
│ └ <async_generator object Postgresql.get_connect at 0x104075140>
└ <contextlib._AsyncGeneratorContextManager object at 0x1040ab2d0>
File "/Users/eric/projects/test-task-for-victory/victory/db/connectors/postgresql.py", line 25, in get_connect
async with self.pool as pool:
│ └ <aiopg.utils._ContextManager object at 0x1038d1180>
└ <victory.db.connectors.postgresql.Postgresql object at 0x1025a1290>
File "/Users/eric/venvs/victory-odDYh4YD-py3.11/lib/python3.11/site-packages/aiopg/utils.py", line 82, in __aenter__
self._obj = await self._coro
│ │ │ └ <member '_coro' of '_ContextManager' objects>
│ │ └ <aiopg.utils._ContextManager object at 0x1038d1180>
│ └ <member '_obj' of '_ContextManager' objects>
└ <aiopg.utils._ContextManager object at 0x1038d1180>
RuntimeError: cannot reuse already awaited coroutine
Источник: Stack Overflow на русском