RuntimeError using asynpcg and fastapi running async function: Task attached to a different loop #6087
-
First Check
Commit to Help
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"]),
)DescriptionI run the script. Everything works fine. But, when i reach the endpoint Operating SystemLinux Operating System DetailsDebian 11 FastAPI Version0.88.0 Python VersionPython 3.9.2 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments
-
|
You are spawning running uvicorn in a different thread and it is starting a different loop from the one your database client which is probably starting its own loop. Then you are trying to access your database from the thread you spawned uvicorn on and it doesnt work because you essentially awaiting tasks from one loop on another. Either dont spawn the uvicorn instance in another thread or figure out how to get the current loop and pass it to both ( I am not sure if you can set the loop for Uvicorn or the Telegram client). |
Beta Was this translation helpful? Give feedback.
-
|
@jgould22 hi. thank you for replying. i ran uvicorn using another Thread so it won't block my code and make the other stuff execute normally :D I'm very noob with asyncio, so I have no clue about how get the loop and use it. I'll be glad if you could help me more 😁 |
Beta Was this translation helpful? Give feedback.
-
|
Are you actually doing anything in that or is it just part of the example you have here ? |
Beta Was this translation helpful? Give feedback.
-
|
@jgould22 i do it to "idle" the script so it wont block, but its not cause of the problem |
Beta Was this translation helpful? Give feedback.
-
|
Why not just block on uvicorn run ? |
Beta Was this translation helpful? Give feedback.
-
|
@jgould22 i can't run uvicorn directly. this code here: 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))
uvicorn.run(api.app, host="0.0.0.0", port=5002)
# while True:
# await asyncio.sleep(600)will give me this error: |
Beta Was this translation helpful? Give feedback.
-
|
Sorry I was not clear, I mean like they describe here in the uvicorn docs Specifically where it says |
Beta Was this translation helpful? Give feedback.
-
|
This worked. Now everything works fine. Thank you so much :D |
Beta Was this translation helpful? Give feedback.
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