RuntimeError using asynpcg and fastapi running async function: Task attached to a different loop
See original GitHub issueFirst Check
- I added a very descriptive title to this issue.
- I used the GitHub search to find a similar issue and didn’t find it.
- I searched the FastAPI documentation, with the integrated search.
- I already searched in Google “How to X in FastAPI” and didn’t find any information.
- I already read and followed all the tutorial in the docs and didn’t find an answer.
- I already checked if it is not related to FastAPI but to Pydantic.
- I already checked if it is not related to FastAPI but to Swagger UI.
- I already checked if it is not related to FastAPI but to ReDoc.
Commit to Help
- I commit to help with one of those options 👆
Example Code
# api.py
from fastapi import FastAPI
class API:
def __init__(self, client):
self.app = FastAPI()
self.client = client
async def get_user_locker(self, user_id: int):
locker = await self.client.database.get_user_locker(user_id)
characters = self.client.characters.get_by_id(locker)
return characters
# main.py
from telegram import TelegramClient
from api import API
from threading import Thread
import asyncio
import uvicorn
import sys
async def start():
client = TelegramClient("test")
await client.start()
api = API(client)
api.app.add_api_route("/locker/{user_id}", api.get_user_locker)
Thread(target=lambda: uvicorn.run(
api.app, host="0.0.0.0", port=5002
), daemon=True).start()
await client.database.init()
print("Client started as @{}".format(client.me.username))
while True:
await asyncio.sleep(600)
if __name__ == "__main__":
try:
asyncio.run(start())
except KeyboardInterrupt:
print("Shutting down...")
sys.exit(0)
# telegram.py
from characters import Characters
from database import Database
import pyrogram
import json
class TelegramClient(pyrogram.Client):
def __init__(self, name):
super().__init__(
name="sessions/" + name,
api_id="123",
api_hash="abc",
plugins=dict(root="handlers")
)
self.banned_list = []
self.translations = json.load(open("translations.json"))
self.database = Database(database="waifu")
self.characters = Characters("char.json", lambda x: x.likes >= 50)
def get_translation(self, name, language):
try:
return self.translations[name][language]
except:
return "TRANSLATION_NOT_FOUND"
async def spawn(self, group: dict):
chat_id = group["chat_id"]
character = await self.characters.get_random()
await self.database.set_current(chat_id, character.id)
return await self.send_photo(chat_id, character.image,
caption=self.get_translation("character_spawned", group["language"]),
)
Description
I run the script. Everything works fine. But, when i reach the endpoint /locker/user_id, I get an Internal Error. Checking the shell i see a huge traceback. The database i use is PosgteSQL with asyncpg module. The error raises when an async function is ran in the FastAPI handler. I can run the same function totally fine outside of FastAPI:
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/home/wicked/.local/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py", line 419, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "/home/wicked/.local/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
File "/home/wicked/.local/lib/python3.9/site-packages/fastapi/applications.py", line 270, in __call__
await super().__call__(scope, receive, send)
File "/home/wicked/.local/lib/python3.9/site-packages/starlette/applications.py", line 124, in __call__
await self.middleware_stack(scope, receive, send)
File "/home/wicked/.local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 184, in __call__
raise exc
File "/home/wicked/.local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "/home/wicked/.local/lib/python3.9/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
raise exc
File "/home/wicked/.local/lib/python3.9/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
await self.app(scope, receive, sender)
File "/home/wicked/.local/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
raise e
File "/home/wicked/.local/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "/home/wicked/.local/lib/python3.9/site-packages/starlette/routing.py", line 706, in __call__
await route.handle(scope, receive, send)
File "/home/wicked/.local/lib/python3.9/site-packages/starlette/routing.py", line 276, in handle
await self.app(scope, receive, send)
File "/home/wicked/.local/lib/python3.9/site-packages/starlette/routing.py", line 66, in app
response = await func(request)
File "/home/wicked/.local/lib/python3.9/site-packages/fastapi/routing.py", line 235, in app
raw_response = await run_endpoint_function(
File "/home/wicked/.local/lib/python3.9/site-packages/fastapi/routing.py", line 161, in run_endpoint_function
return await dependant.call(**values)
File "/home/wicked/bots/waifu/api.py", line 9, in get_user_locker
locker = await self.client.database.get_user_locker(user_id)
File "/home/wicked/bots/waifu/database.py", line 31, in get_user_locker
query = await self.conn.fetchrow("SELECT locker FROM users WHERE user_id = $1;", user_id)
File "/home/wicked/.local/lib/python3.9/site-packages/asyncpg/connection.py", line 678, in fetchrow
data = await self._execute(
File "/home/wicked/.local/lib/python3.9/site-packages/asyncpg/connection.py", line 1658, in _execute
result, _ = await self.__execute(
File "/home/wicked/.local/lib/python3.9/site-packages/asyncpg/connection.py", line 1683, in __execute
return await self._do_execute(
File "/home/wicked/.local/lib/python3.9/site-packages/asyncpg/connection.py", line 1710, in _do_execute
stmt = await self._get_statement(
File "/home/wicked/.local/lib/python3.9/site-packages/asyncpg/connection.py", line 397, in _get_statement
statement = await self._protocol.prepare(
File "asyncpg/protocol/protocol.pyx", line 168, in prepare
RuntimeError: Task <Task pending name='Task-52' coro=<RequestResponseCycle.run_asgi() running at /home/wicked/.local/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py:419> cb=[set.discard()]> got Future <Future pending cb=[Protocol._on_waiter_completed()]> attached to a different loop
Operating System
Linux
Operating System Details
Debian 11
FastAPI Version
0.88.0
Python Version
Python 3.9.2
Additional Context
No response
Issue Analytics
- State:
- Created 9 months ago
- Comments:8
Top Results From Across the Web
getting task attached to a different loop runtime error when ...
i am trying to create an app with mongodb client motor and fastapi . I created seperate routes and a seperate file to...
Read more >Future task attached to a different loop - python - Stack Overflow
You can have mongodb motor client in the global scope, but creating and closing it should be done inside an async function.
Read more >Async Tests - FastAPI
If you encounter a RuntimeError: Task attached to a different loop when integrating asynchronous function calls in your tests (e.g. when using MongoDB's ......
Read more >Common Mistakes Using Python3 asyncio
4. Task/Future is awaited in a different EventLoop than it is created ... Compared to C# async/await , the interfaces of Python3 asyncio...
Read more >Asynchronous I/O (asyncio) - SQLAlchemy 1.4 Documentation
Using awaitable-only driver methods in connection pool and other events ... RuntimeError: Event loop is closed within garbage collection.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
This worked. Now everything works fine. Thank you so much 😄
Sorry I was not clear, I mean like they describe here in the uvicorn docs https://www.uvicorn.org/#config-and-server-instances
Specifically where it says
If you'd like to run Uvicorn from an already running async environment