In my python3 flask application I would like to execute a couple of recurring tasks before the first request.
In order to achieve this, I want to make use of the#app.before_first_request_funcs.
Can anyone please give me an example usage of #app.before_first_request_funcs?
Here is my sample code:
import threading
import time
from flask import Flask
app = Flask(__name__)
def activate_job():
def run_job():
while True:
print("recurring task")
time.sleep(3)
thread = threading.Thread(target=run_job())
thread.start()
def activate_job2():
def run_job2():
while True:
print("recurring task2")
time.sleep(3)
thread = threading.Thread(target=run_job2())
thread.start()
#app.after_first_request(activate_job())
#app.before_first_request(activate_job2())
#app.route('/')
def home():
return {"action": "This has done something"}
if __name__ == '__main__':
print(app.before_first_request_funcs)
app.run()
As per the documentation, you should use #app.before_first_request to do what you want.
from flask import Flask
app = Flask(__name__)
def some_func(some_arg):
print('coucou')
# #app.before_first_request(some_func)
#app.route('/')
def home():
return {"action" : "This has done something"}
if __name__ == '__main__':
print(app.before_first_request_funcs)
app.run()
You can see the behavior of the method before_first_request_funcs that is not a decorator by commenting and uncommenting the decorator before_first_request.
If it is commented, it'll print an empty list, and if you uncomment the line, it'll return a list of one element containing the function some_func object (for me, it was [<function some_func at 0x0000021393A0AD90>]).
Related
I have found a piece of flask: https://github.com/pratik55/Python-Flask-dynamic-update- code that dynamically updates the HTML, but it requires a function like time.time() - it outputs, pauses, and outputs again. I would like a custom function to do just this but not with a time value.
I tried something similar to this https://www.geeksforgeeks.org/g-fact-41-multiple-return-values-in-python/ but I could not put a pause in between each output.
The flask code looks like this:
from flask import Flask, jsonify, render_template, request
import webbrowser
import time
app = Flask(__name__)
#app.route('/_stuff', methods = ['GET'])
def stuff():
return jsonify(result=time.time())
#app.route('/')
def index():
return render_template('dy1.html')
if __name__ == '__main__':
app.run()
The result is just a question mark when I replace result=time.time() with something else unless its very explicit like result="hello"
Thanks
problem with flask ask
#ask.launch issue
am having problem running my python flask script. I am using python 2.7, the error says:
File "C:\Users\user1\AppData\Local\Continuum\anaconda2\Lib\site-packages\hello_lumion.py", line 13, in #ask.launch NameError: name 'ask' is not defined
import logging
import os
from flask import request
from flask import Flask
from flask_ask import Ask, statement, request, context, session, question, version
import requests
#ask.launch
def welcome():
return statement ('Welcome to Foo')
app = Flask(__name__)
ask= Ask(app,"/")
logging.getLogger("flask_ask").setLevel(logging.DEBUG)
#ask.intent("Hello")
def hello():
msg= "hello from lumion"
return statement (msg)
if __name__ == '__main__':
port = 9000
app.run(host='0.0.0.0', port=port)
app.run(debug=True)
any advice on how to overcome this issue?
You are calling ask before it is defined. In your code you have
#ask.launch # ask has not been made
def welcome():
return statement ('Welcome to Foo')
app = Flask(__name__)
ask= Ask(app,"/") # ask gets made here!
You will need to reorder it so when you call ask, it has been defined. Something like:
app = Flask(__name__)
ask= Ask(app,"/") # define it first
#ask.launch # now use it
def welcome():
return statement ('Welcome to Foo')
I'm new on flask.I configured a server with flask+gunicorn.
the code file called test.py like this:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def test():
return aa+"world!"
if __name__ == '__main__':
aa = "hello"
app.run()
run it using:gunicorn -b 0.0.0.0:8080 test:app
I got a mistake:NameError: name 'aa' is not defined.
I want some codes like variable aa runing before gunicorn.
How to do that?
Put in a small block just before your #app.route and you dont need the last block in the question
#app.before_first_request
def _declareStuff():
global aa
aa='hello'
Just declare aa outside of "__main__", in the global scope of the file.
from flask import Flask
app = Flask(__name__)
#app.route('/')
def test():
return aa+"world!"
aa = "hello"
if __name__ == '__main__':
app.run()
The code in the if __name__ == '__main__': block executes only if the Python code is run as a script, e.g., from the command line. Gunicorn imports the file, so in that case the code in __main__ will not be executed.
Note that if it is your intention to modify the value of aa then different requests can produce different results depending on how many requests each gunicorn worker process has handled. e.g.:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def test():
global counter
counter += 1
return "{} world! {}".format('aa', counter)
counter = 0
if __name__ == '__main__':
app.run()
Run the above script with more than one worker (gunicorn -w 2 ...) and make several requests to the URL. You should see that the counter is not always contiguous.
As of Flask 2.2, the #app.before_first_request decorator suggested by Vipluv in their answer is deprecated and will be removed in 2.3.
Deprecated since version 2.2: Will be removed in Flask 2.3. Run setup code when creating the application instead.
The equivalent can be done by manually pushing the app context, as suggested by Enkum :
# In place of something like this
#app.before_first_request
def create_tables():
db.create_all()
...
# USE THIS INSTEAD
with app.app_context():
db.create_all()
I am using Flask to build a tool to view data locally in a browser. I want to pass the directory containing the data as a command line argument, and then pass it to the appropriate routing function to do the rendering.
This does what I want, but with global variables:
dataDir = None
def initializeData(pathname):
global dataDir
dataDir = pathname
#app.route('/')
def home():
# Use dataDir as desired
if __name__ == '__main__':
initializeData(sys.argv[1])
app = Flask(__name__)
app.run()
Is there a better way to communicate between the command line and my routes?
Your flask app has a config property. Also, this code will fail with a NameError. You want something like this:
import sys
from flask import Flask
app = Flask(__name__)
#app.route('/')
def home():
return 'You wanted {!r} directory'.format(app.config.get('some_setting'))
if __name__ == '__main__':
app.config['some_setting'] = sys.argv[1]
app.run()
Consider using app.config.from_json('config.json') so that you can configure your env parameters in a json file.
I'm trying to get access to the current app instance from a Flask-Script manager.command.
This errors out (url_map is a property of flask.app)
#manager.command
def my_function():
x = app.url_map # this fails, because app is a callable
print "hi"
This works, but I don't like having to add parens next to app.
#manager.command
def my_function():
x = app().url_map
print "hi"
The debugger shows that app is a callable. That has to do with the way that I'm creating the app instance. I'm following this pattern:
def create_app(settings=None, app_name=None, blueprints=None):
...lots of stuff...
app = flask.Flask(app_name)
...lots of stuff...
return app
def create_manager(app):
manager = Manager(app)
#manager.command
def my_function():
x = app.url_map
print "hi"
def main():
manager = create_manager(create_app)
manager.run()
if __name__ == "__main__":
main()
The docs from flask-script say about the app parameters on Manager(app):
app – Flask instance, or callable returning a Flask instance.
I'm comfortable with putting a callable in there because the docs say it's OK. :-) Plus I've seen others do it like that.
But now I have this peripheral command that I'd like to add and it's forcing me to use the app with parens and that smells wrong. What am I doing wrong?
EDIT: I did some experiments. This is definitely wrong. By adding the parens, the app instance is getting recreated a second time.
Use flask.current_app
This works:
import flask
... other stuff ...
#manager.command
def my_function():
x = flask.current_app.url_map
print "hi"
I 'overthunk' it. :-)