イベントループをカスタマイズする#

イベントループをカスタマイズすると、Quart を別のライブラリと一緒に使用しつつ、両方が同じループを使用できるようにすることがよくあります。Quart で作成・初期化されたループ内でサードパーティを作成/初期化する最善の手法は次の方法で スタートアップとシャットダウン before_serving 関数を使用することです。

@app.before_serving
async def startup():
    loop = asyncio.get_event_loop()
    app.smtp_server = loop.create_server(aiosmtpd.smtp.SMTP, port=1025)
    loop.create_task(app.smtp_server)

@app.after_serving
async def shutdown():
    app.smtp_server.close()

例に一般的に見られるこのパターンには従わないでください。このパターンでは、サードパーティのために Quart ループとは別の新しいループが作成されます。

loop = asyncio.get_event_loop()
third_party = ThirdParty(loop)
app.run()  # A new loop is created by default

イベントループを制御する#

Quart を実行しているイベントループを所有するのは、Quart を実行している ASGI サーバーです。デフォルトではそのサーバーは Hypercorn です。Quart と Hypercorn はいずれもループを指定できます。開発における Quart のショートカットは app.run メソッドにループを渡すことです。

loop = asyncio.get_event_loop()
third_party = ThirdParty(loop)
app.run(loop=loop)

あるいは、 app.run_task メソッドを使用することもできます。

loop = asyncio.get_event_loop()
third_party = ThirdParty(loop)
loop.run_until_complete(app.run_task())

Hypercorn(運用)の解決策は Hypercorn API を活用して次の処理を行うことです。

from hypercorn.asyncio import serve
from hypercorn.config import Config
...
loop = asyncio.get_event_loop()
third_party = ThirdParty(loop)
loop.run_until_complete(serve(app, Config()))
# or even
await serve(app, config)