Flask:在运行长数据收集过程时解决超时错误

时间:2015-11-30 19:59:14

标签: python-2.7 python-3.x concurrency flask

我有一个将在OpenShift上运行的Flask应用,需要一段时间来生成数据,并可能导致超时错误。

通过查看示例,我认为我可以渲染一个"请等待"模板,它立即返回,同时也调用我长时间运行的run_analysis()函数。收集完数据后,run_analysis()将呈现新页面。

要么这不可能,要么我做错了。谢谢你的帮助。

from flask import Flask
import jinja2

app = Flask(__name__)

please_wait_template = jinja2.Template('''
<!DOCTYPE html>
<html lang="en">
<head>
    <title>please wait for data</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1>Collecting data, this could take a while.</h1>
</body>
</html>''')

input_template = jinja2.Template('''
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Input Keywords</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1>Doing stuff</h1>
    <form action="/please_wait/"  method="POST">
        Enter keywords<br>
        <input type="text" name="kw" placeholder="data science"><br>
        <input type="submit" value="Submit" name="submit">
    </form>
</body>
</html>''')

output_template = jinja2.Template("""
<!DOCTYPE html>
<html lang="en-US">
<head>
    <title>results</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1>RESULTS</h1>
    {{ results }}
</body>

</html>
""")

@app.route('/')
def render_input_page():
    return input_template.render()

@app.route('/please_wait/')
def please_wait():
    return please_wait_template.render()

@app.route('/please_wait/', methods=['post'])
def run_analysis():
    kws = request.form['kw']
    zips = request.form['zipcodes']
    template = run_long_analysis(kws, zips)

    return template

def run_long_analysis(kws, zips):
    import time
    time.sleep(2400)
    return output_template(results="testing")

1 个答案:

答案 0 :(得分:-1)

是的,有可能。但是,您需要打破单个文件。即创建模板目录并在那里存储模板。 http://flask.pocoo.org/docs/0.10/quickstart/#rendering-templates

引用文档基本示例:

from flask import render_template

@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
    return render_template('hello.html', name=name)

您可以看到render_template代替.render()output_template。这很方便,它使得读取Flask逻辑变得更容易。

专门针对您的代码:

@app.route('/please_wait/', methods=['post'])
def run_analysis():
    kws = request.form['kw']
    zips = request.form['zipcodes']
    template = run_long_analysis(kws, zips)

zips = request.form['zipcodes']会很麻烦,因为我在 please_wait 路径下看不到表格。也许你意识到了这一点。

一般来说,根据我的经验,有助于此类情况的工具是Flask session对象。这基本上是一个贯穿用户会话的全局字典。请参阅文档http://flask.pocoo.org/docs/0.10/quickstart/#sessions中的详细信息。

引用该示例:

from flask import Flask, session, redirect, url_for, escape, request

app = Flask(__name__)

@app.route('/')
def index():
    if 'username' in session:
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form action="" method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/logout')
def logout():
    # remove the username from the session if it's there
    session.pop('username', None)
    return redirect(url_for('index'))

# set the secret key.  keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

您可以在上面的示例中看到session对象的行为类似于dict。它还允许您通过 Jinja2 动态更改显示的内容。换句话说,它可以传递到模板中。这些方法结合起来,应该为您提供所需的功能。