Using Asyncio with Quart¶
Quart is a Python web framework designed
to have a similar API to Flask, but using asyncio
.
from quart import Quart
app = Quart(__name__)
@app.route('/')
async def hello():
return 'hello'
app.run()
Monkey Patching¶
Flask-Discord-Interactions supports using Quart. This can provide a more
familiar development experience to those used to discord.py
’s
async commands.
Specifically, Quart supports monkey patching to allow Flask extensions to run with Quart. The specifics of this are in this tutorial.
Flask-Discord-Interactions will work with this monkey patching. Additionally, this library has some extra logic to handle mixing async and non-async commands, and to allow awaiting when handling followup messages.
from quart import Quart
import quart.flask_patch
from flask_discord_interactions import DiscordInteractions
app = Quart(__name__)
discord = DiscordInteractions(app)
discord.update_commands()
@discord.command()
async def ping(ctx):
"Respond with a friendly 'pong'!"
return "Pong!"
# Non-async functions still work
@discord.command()
def pong(ctx):
return "Ping!"
Use an Async Route Handler¶
If you want to use async commands in Flask-Discord-Interactions, then the
library needs to register an asynchronous handler for the interactions
endpoint. This is what allows Flask-Discord-Interactions to await
your function handler.
If you are using Flask-Discord-Interactions with Quart, you need to call
DiscordInteractions.set_route_async()
instead of
DiscordInteractions.set_route()
.
discord.set_route_async("/interactions")
Context in Async Commands¶
A special AsyncContext
class is exposed to asynchronous commands.
This class makes AsyncContext.edit()
, AsyncContext.send()
, and
AsyncContext.delete()
awaitable.
@discord.command()
async def wait(ctx, seconds: int):
async def do_followup():
await asyncio.sleep(seconds)
await ctx.edit("Done!")
asyncio.create_task(do_followup())
return Message(deferred=True)
# Normal followups use the normal Context
@discord.command()
def wait_sync(ctx, seconds: int):
def do_followup():
time.sleep(seconds)
ctx.edit("Done!")
threading.Thread(target=do_followup).start()
return Message(deferred=True)
When creating command groups and subgroups, you will only get an
AsyncContext
if you provide the is_async=True
flag.
toplevel = discord.command_group("toplevel", is_async=True)
secondlevel = toplevel.subgroup("secondlevel", is_async=True)
@secondlevel.command()
async def thirdlevel(ctx):
async def do_followup():
print(type(ctx))
await asyncio.sleep(1)
await ctx.edit(f"Hello, {ctx.author.display_name}!")
asyncio.create_task(do_followup())
return Message(deferred=True)
Full API¶
- class flask_discord_interactions.AsyncContext(**kwargs)¶
Bases:
Context
Represents the context in which an asynchronous
Command
is invoked. Also provides coroutine functions to handle followup messages.Users should not need to instantiate this class manually.
- async delete(message: str = '@original')¶
Delete an existing message.
- Parameters:
message (str) – The ID of the message to delete. If omitted, deletes the original message.