Python Flask returning a html page while simultaneously performing a function -
i'm creating web app using python flask , i've run road block , i'm not sure if i'm thinking correctly.
so website's homepage simple landing page text input required perform websites function. trying accomplish web app perform 2 things after text input. first, server takes username input , performs function doesn't return user creates bunch of data logged sqlite database, , used later on in process. then, server returns web page survey has taken after username input. however, function server performs can take upwards of 2 minutes depending on user. way have coded, server performs function, once has finished, returns web page, user stuck @ loading screen 2 minutes.
@app.route("/survey") def main(raw_user): raw_user = request.args.get("steamid") < games = creategamedict(user_obj) <----- function tag_lst = get_tags(games) < return render_template("survey_page.html")
since survey doesn't depend on user input, instead of having user sitting @ loading screen, them able start survey while functions works in background, possible, , how that?
for more complex background tasks, celery best bet. simpler use cases however, want threading
module.
consider following example:
from flask import flask time import sleep app = flask(__name__) def slow_function(some_object): sleep(5) print(some_object) @app.route('/') def index(): some_object = 'this test' slow_function(some_object) return 'hello' if __name__ == '__main__': app.run()
here, create function, slow_function()
sleeps 5 seconds before returning. when call in our route function blocks page load. run example , hit http://127.0.0.1:5000 in browser, , you'll see page wait 5 seconds before loading, after test message printed in terminal.
what want put slow_function()
on different thread. couple of additional lines of code, can use threading
module separate out execution of function onto different thread:
from flask import flask time import sleep threading import thread app = flask(__name__) def slow_function(some_object): sleep(5) print(some_object) @app.route('/') def index(): some_object = 'this test' thr = thread(target=slow_function, args=[some_object]) thr.start() return 'hello' if __name__ == '__main__': app.run()
what we're doing here simple. we're creating new instance of thread
, passing 2 things: target
, function want run, , args
, argument(s) passed target function. notice there no parentheses on slow_function
, because we're not running - functions objects, we're passing function itself thread
. args
, expects list. if have 1 argument, wrap in list args
gets it's expecting.
with our thread ready go, thr.start()
executes it. run example in browser, , you'll notice index route loads instantly. wait 5 seconds , sure enough, test message print in terminal.
now, stop here - in opinion @ least, it's bit messy have threading code inside route itself. if need call function in route, or different context? better separate out own function. make threading behaviour part of slow function itself, or make "wrapper" function - approach take depends lot on you're doing , needs are.
let's create wrapper function, , see looks like:
from flask import flask time import sleep threading import thread app = flask(__name__) def slow_function(some_object): sleep(5) print(some_object) def async_slow_function(some_object): thr = thread(target=slow_function, args=[some_object]) thr.start() return thr @app.route('/') def index(): some_object = 'this test' async_slow_function(some_object) return 'hello' if __name__ == '__main__': app.run()
the async_slow_function()
function doing pretty doing before - it's bit neater now. can call in route without having rewrite threading logic on again. you'll notice function returns thread - don't need example, there other things might want thread later, returning makes thread object available if ever need it.
Comments
Post a Comment