В комментарии есть все, что вам нужно, чтобы ответить на веб-запрос и запланировать генерацию PDF на будущее.
asyncio.create_task(generatePdf())
Однако не рекомендуется, если обработка pdf идет медленно, поскольку она блокирует поток событий asyncio.т. е. текущий запрос будет обработан быстро, но следующий запрос должен будет дождаться завершения генерации pdf.
Правильный способ будет выполнить задачу в исполнителе (особенно 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
и должны хорошо работать с другими асинхронными функциями.