非同期との互換性#

同期コードと非同期コードは、タイプに応じて関数の呼び出し方法が異なるため、直接互換性がありません。これにより、Quart が Flask 拡張機能と相互作用する方法や、Flask を直接非同期にするためのあらゆる取り組みなどの、実行できることが制限されます。

私の意見では、Python では非同期コードベースから同期コードを呼び出す方が、その逆よりもはるかに簡単です。以下にその理由について説明します。

非同期関数から同期コードを呼び出す#

これは主に簡単で、同期関数の呼び出しや、単純なラッパーを使用して非同期関数を待機できます。

async def example():
    sync_call()
    await asyncio.coroutine(sync_call)()

これは本質的にコードの性質を変えず、呼び出しは同期で行われますが、機能します。

同期関数から非同期コードを呼び出す#

イベントループはただ 1 つしか作成できないため、これは困難になります。したがって、これは一度しか使用できません。

def example():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(async_call())

したがって、最も外側のスコープにない場合は、同期関数から非同期コードを呼び出すことは実際にはできません。

Flask 拡張機能を扱う場合、これは問題になります。たとえば、拡張機能には次のようなものがある場合があります。

@app.route('/')
def route():
    data = request.form
    return render_template_string("{{ name }}", name=data['name'])

ルート関数は asyncio.coroutine 関数でラップでき、したがって待機できますが、 awaitrequest.formrender_template 呼び出しの前に挿入する(簡単な)方法はありません。

この理由により、Quart-Flask-Patch は Flask 拡張機能に対して同期ラップバージョンを作成します。前者は同期要求メソッドを追加し、後者は同期関数を提供します。

Quart は、 sync_wait メソッドをベースイベントループにパッチして、次の定義を可能にします。

from quart.templating import render_template as quart_render_template

def render_template(*args):
    return asyncio.sync_wait(quart_render_template(*args))