我故意的完整代码是一个网站,将其从youtube视频中获取并转换为mp3,将其保存到S3,然后将S3链接返回给用户。
因为我想在低性能的EC2上使用(省钱),并且也不想阻止很多人同时使用它,所以我使用celery进行异步操作。
芹菜做完后,我可以执行回调函数。但这仅显示在终端上,我如何(显示为替换)重定向等待屏幕?
from flask import Flask, render_template, request
from celery import Celery
import youtube_dl
app = Flask(__name__)
app.config['CELERY_BROKER_URL'] = 'redis://:password@redis-YYYY.cloud.redislabs.com:YYYY/0'
app.config['CELERY_RESULT_BACKEND'] = 'redis://:password@redis-YYYY.cloud.redislabs.com:YYYY/0'
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
def done_download_hook(d):
if d['status'] == 'finished':
print('Done downloading, now converting ...')
ydl_opts = {
'format': 'bestaudio/best',
'outtmpl': '%(id)s.%(ext)s',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
'progress_hooks': [done_download_hook],
}
@celery.task(bind=True)
def download_task(self, link, ydl_opts):
# some long running task here
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([link])
# and copy converted file to S3, return/get S3 link
# I could handle the process from EC2 to S3.
@app.route('/')
def my_form():
return render_template('hello.html')
# I try some decorators @app.XXXXX but no success.
def test_callback():
print('it worked and run until here')
# should redirect user to S3 link, or redirect the page with link to click
# How can I do that ?
return 'http://...'
@app.route('/', methods=['POST'])
def my_form_post():
download_link = request.form['text']
# download_task.delay(download_link, ydl_opts)
download_task.apply_async((download_link, ydl_opts),link=test_callback())
return "please waiting, after done converting, we would redirect you to the link"
答案 0 :(得分:0)
由于celery将任务运行在一个单独的进程中(或多个,如果您运行celery的多个实例),并且您已选择使体验异步进行,以确定任务何时完成,浏览器上的页面将转到必须轮询(即通过AJAX)。这意味着它将需要一些可用于查询任务状态/结果的ID。最简单的ID是.delay()
执行任务时所获得的对象中的一个ID。呈现页面时将其传递,以便可以进行AJAX调用。
然后,用于处理调用的view方法将执行类似的操作
from celery.result import AsyncResult
@app.route('/taskstatus')
def taskstatus(uuid):
result = AsyncResult(uuid)
return HttpResponse(json.dumps({'done': result.ready()}),
content_type='application/json')
页面显示done: true
时,它可以执行任何操作(重定向,更改元素的文本或颜色,...)