コメントには、Web リクエストに応答し、後で PDF 生成をスケジュールするために必要なすべてが含まれています。
asyncio.create_task(generatePdf())
ただし、asyncio イベント スレッドをブロックするため、pdf 処理が遅い場合はお勧めできません。つまり、現在のリクエストはすぐに応答されますが、次のリクエストは PDF 生成が完了するまで待たなければなりません。
正しい方法は、executor (特にProcessPoolExecutor ) でタスクを実行することです。
from quart import Quart
import asyncio
import time
from concurrent.futures import ProcessPoolExecutor
app = Quart(__name__)
executor = ProcessPoolExecutor(max_workers=5)
@app.route('/')
async def pdf():
t1 = time.time()
asyncio.get_running_loop().run_in_executor(executor, generatePdf)
# await generatePdf()
return 'Time to execute : {} seconds'.format(time.time() - t1)
def generatePdf():
#sync generatepdf
#send pdf link to email
app.run()
generatePdf
別のプロセスで実行されているため、 は同期しないとデータにアクセスできないことに注意してください。そのため、関数を呼び出すときに関数が必要とするすべてのものを渡します。
アップデート
generatePdf
関数をリファクタリングして非同期にすることができれば、最もうまく機能します。
生成されたPDFが次のように見える場合の例
def generatePdf():
image1 = downloadImage(image1Url)
image2 = downloadImage(image2Url)
data = queryData()
pdfFile = makePdf(image1, image2, data)
link = upLoadToS3(pdfFile)
sendEmail(link)
次のように関数を非同期にすることができます。
async def generatePdf():
image1, image2, data = await asyncio.gather(downloadImage(image1Url), downloadImage(image2Url), queryData())
pdfFile = makePdf(image1, image2, data)
link = await upLoadToS3(pdfFile)
await sendEmail(link)
注: のようなすべてのヘルパー関数は、 をサポートするようdownloadImage
にqueryData
書き直す必要がありますasync
。これにより、データベースや画像サーバーの速度が遅くても、リクエストがブロックされることはありません。すべてが同じ asyncio スレッドで実行されます。
それらのいくつかがまだ非同期である場合、それらはrun_in_executor
他の非同期関数と一緒に使用でき、うまく機能するはずです。