Я не уверен, что правильно сформулировал вопрос, но, например, я хочу вернуть ответ, не возвращая функцию.
Мой контекст здесь таков: пользователь запрашивает создание большого файла Excel, поэтому ему будет возвращена ссылка, и когда Excel будет выполнен, также будет отправлено электронное письмо.
Пример псевдо:
from flask import Flask
from flask import send_file
from someXlsLib import createXls
from someIoLib import deleteFile
from someMailLib import sendMail
import uuid
app = Flask(__name__)
host = 'https://myhost.com/myApi'
@app.route('/getXls')
def getXls:
fileName = uuid.uuid4().hex + '.xls'
downloadLink = host + '/tempfiles/' + fileName
#Returning the downloadLink for the user to acces when xls file ready
return downloadLink
#But then this code is unreachable
generateXls(fileName)
def generateXls(fileName, downloadLink)
createXls('/tempfiles/' + fileName)
sendMail(downloadLink)
@app.route('/tempfiles/<fileName>')
def getTempFile:
#Same problem here, I need the user to finish the download before deleting the file
return send_file('/tempfiles/' + fileName, attachment_filename=fileName)
deleteFile('/tempfiles/' + fileName)
Кажется, этот пост отвечает на вашу проблему с использованием celery: stackoverflow.com/questions/31866796/…
Если вы хотите вернуть ответ, а затем сделать что-то простое, Отложенные обратные вызовы запроса может быть достаточно.
@Fian, но это будет происходить для каждого запроса, верно?
Вы можете настроить его самостоятельно: можно вызывать после каждого запроса или вызывать только по определенным запросам, отвечающим определенным условиям.






Другие комментаторы правы в том, что вам нужно что-то использовать для управления асинхронными действиями. Один из самых популярных вариантов, который поставляется с множеством инструментов для выполнения отложенных, запланированных и асинхронных действий, — Сельдерей. Вы можете делать то, что хотите, используя сельдерей, например:
from celery import Celery
...
# This is for Redis on the local host. You can also use RabbitMQ or AWS SQS.
celery = Celery(app.name, broker='redis://localhost:6379/0')
celery.conf.update(app.config)
...
# Create your Celery task
@celery.task(bind=True)
def generateXls(file_name, downloadLink):
createXls('/tempfiles/' + fileName)
sendMail(downloadLink)
@app.route('/getXls')
def getXls:
fileName = uuid.uuid4().hex + '.xls'
downloadLink = host + '/tempfiles/' + fileName
# Asynchronously call your Celery task.
generateXls.delay(file_name, downloadLink)
return downloadLink
Это немедленно вернет ссылку для загрузки, продолжая generateXls в своем собственном потоке.
Это действительно сработало, но, к сожалению, я только что заметил, что мой хост (pythonanywhere) не поддерживает это. Не уверен, нужен ли мне сейчас другой хост или другое решение.
Если проблема заключается в Redis, вы можете настроить АМС SQS без установки чего-либо на локальном хосте или запустить Redis или RabbitMQ на удаленном хосте.
@Mojimi Вы когда-нибудь решали эту проблему? Я заметил, что вы, возможно, не видели (поскольку я не отметил вас) моего сообщения о решении проблемы с установкой брокера с помощью удаленного брокера. Если этот ответ работает, можете ли вы отметить его ответом?
Да, я уже знал о сельдерее, просто подумал, есть ли что-то встроенное в Flask для продолжения обработки.
Кажется, что вам нужны асинхронные действия. Взгляните на
celeryилиasyncio.