Ответ на возврат фляги, но продолжить обработку?

Я не уверен, что правильно сформулировал вопрос, но, например, я хочу вернуть ответ, не возвращая функцию.

Мой контекст здесь таков: пользователь запрашивает создание большого файла 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 или asyncio.

spaniard 23.01.2019 14:30

Кажется, этот пост отвечает на вашу проблему с использованием celery: stackoverflow.com/questions/31866796/…

F Blanchet 23.01.2019 15:59

Если вы хотите вернуть ответ, а затем сделать что-то простое, Отложенные обратные вызовы запроса может быть достаточно.

Fine 23.01.2019 16:04

@Fian, но это будет происходить для каждого запроса, верно?

Mojimi 23.01.2019 16:25

Вы можете настроить его самостоятельно: можно вызывать после каждого запроса или вызывать только по определенным запросам, отвечающим определенным условиям.

Fine 24.01.2019 13:06
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
929
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Другие комментаторы правы в том, что вам нужно что-то использовать для управления асинхронными действиями. Один из самых популярных вариантов, который поставляется с множеством инструментов для выполнения отложенных, запланированных и асинхронных действий, — Сельдерей. Вы можете делать то, что хотите, используя сельдерей, например:

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) не поддерживает это. Не уверен, нужен ли мне сейчас другой хост или другое решение.

Mojimi 23.01.2019 18:12

Если проблема заключается в Redis, вы можете настроить АМС SQS без установки чего-либо на локальном хосте или запустить Redis или RabbitMQ на удаленном хосте.

Logan Bertram 23.01.2019 19:32

@Mojimi Вы когда-нибудь решали эту проблему? Я заметил, что вы, возможно, не видели (поскольку я не отметил вас) моего сообщения о решении проблемы с установкой брокера с помощью удаленного брокера. Если этот ответ работает, можете ли вы отметить его ответом?

Logan Bertram 25.01.2019 15:36

Да, я уже знал о сельдерее, просто подумал, есть ли что-то встроенное в Flask для продолжения обработки.

Mojimi 25.01.2019 15:38

Другие вопросы по теме