-
-
Save haykkh/49ed16a9c3bbe23491139ee6225d6d09 to your computer and use it in GitHub Desktop.
import asyncio | |
import discord | |
from fastapi import FastAPI | |
app = FastAPI() | |
client = discord.Client() | |
# where the magic happens | |
# register an asyncio.create_task(client.start()) on app's startup event | |
# ^ note not client.run() | |
@app.on_event("startup") | |
async def startup_event(): | |
asyncio.create_task(client.start('token')) | |
@app.get("/") | |
async def read_root(): | |
return {"Hello": str(client.user)} |
Thanks
Save my Life! Thanks!
You just saved my life!
Thank you very much!!!!
saved my life
Maybe someone can help me
I moved this function into the new lifespan implementation of FastAPI
`@asynccontextmanager
async def lifespan(app: FastAPI):
# Load the ML model
asyncio.create_task(client.start(DISCORD_TOKEN))
yield
client.close()
app = FastAPI(lifespan=lifespan)`
Running with uvicorn I get this error:
ValueError: The future belongs to a different loop than the one specified as the loop argument
Bot works but it's slower and take ssome time to refresh API calls. What can I do?
@djalo here is how I deal with discord client inside my endpoint. It's not ideal but might be a decent start
@app.post("/screenshot")
async def send_screenshot_to_discord_channel(image: schemas.ScreenShot):
# create a task and wait for its initialization
asyncio.create_task(client.start(DISCORD_API_TOKEN))
await asyncio.sleep(1)
# Preparation of file to be sent
base64_cut = image.image_base64.split(",")[1]
file = discord.File(io.BytesIO(base64.b64decode(base64_cut)), filename="1.png")
# Getting channel and sending the file
channel = client.get_channel(DISCORD_CHAT_ID)
await channel.send(file=file)
# Closing the client
await client.close()
return {"ok": True}
In this implementation discord bot goes online for a second, sends a file, and goes offline. I didn't succeed in improving this code further. Also, my code is running in the deta.space services (I think they are using AWS Lambdas for running the apps so maybe this short term living client is good in my case)
@kovalbogdan95 thanks for Your input, but still the same :(
What webserver are You using?
I'm running Uvicorn and there's one thing I can't wrap my head around:
If I run uvicorn like this:
uvicorn.run("main:app", host="0.0.0.0", port=5000, reload=True)
No problems occur, when I try to run it in "production" mode:
uvicorn.run(app, host="0.0.0.0", port=5000, log_level="info")
That loop error appears. Any ideas maybe?
This is what I tried:
@app.get("/isdcvip/{discordID}")
async def isdcvip(discordID: str):
print(discordID)
asyncio.create_task(client.start(DISCORD_TOKEN))
await asyncio.sleep(1)
guild = client.get_guild(XXXXXXX)
vip = discord.utils.get(guild.roles, name="VIP")
hvip = discord.utils.get(guild.roles, name="Honorable Member")
member = guild.get_member_named(discordID)
if member not in guild.members:
await client.close()
return 'User not found!'
if vip in member.roles:
await client.close()
return True
if hvip in member.roles:
await client.close()
return "Honorable Member"
await client.close()
return False
@djalo you can try to setup and initialize the async loop before starting anything so they would most likely run on the same loop. If FastAPI creates its own loop it will not solve any thing though. This helped me to go through the same issue when running FastAPI with a mix between sync and async methods and google Firebase client in async mode.
loop = new_event_loop()
set_event_loop(loop)
@titouanfreville
Thanks for Your input! Gonna save this for another occasion.
I solved that pretty easily. Switched to discord.py library just because was curious.
No more errors, maybe that will help somebody too
Saved my day