I am trying to create a script to basically create all the flask endpoint from existing python classes/methods.
one way which i came across was app.add_url_rule
but it is not working for me
#app.route('/username/<username>')
def userstatus(username):
print("user is logged in")
app.add_url_rule('/username/', 'userstatus', defaults={"username":None})**
the above one is working but if i remove #app.route('/username/<username>') and try juust with add_url_rule, it is not working.
You have to provide the rule, the end point and the view function to add_url_rule (see API doc):
from flask import Flask
app = Flask(__name__)
def userstatus(username):
return f'Hello {username}!'
app.add_url_rule('/username/<username>', '/username/<username>', userstatus)
Then you can start your flask app:
(venv) $ FLASK_APP=url_rule.py flask run
* Serving Flask app "url_rule.py"
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
And send queries in a different shell (or your browser):
$ curl http://localhost:5000/username/alice && echo
Hello alice!
$ curl http://localhost:5000/username/bob && echo
Hello bob!
You could then use your existing python files and call add_url_rule for the endpoints you want to create dynamically.
Related
I would like to use standard output from my Flask application to communicate status information to other process connected through pipeline, but it turns out that Flask somehow disables standard output when standard output is redirected.
Here is my sample Flask app:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello, World!'
def prepare():
# Do some preparation work
pass
prepare()
print('ready')
Now compare two different but very similar ways of starting this app:
$ FLASK_APP=my_app.py flask run 2>/dev/null
* Serving Flask app "my_app.py"
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
ready
When standard output is redirected, my status message is muted (but application works as evidenced when accessed through web interface):
$ FLASK_APP=my_app.py flask run 2>/dev/null | cat
* Serving Flask app "my_app.py"
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
Does anybody know how to allow standard output messages go through pipeline in Flask app?
I can't use web interface for the purpose because I have a function decorated with #before_first_request and querying for status will trigger it, which I don't want.
Version information:
$ flask --version
Python 3.6.12
Flask 1.1.2
Werkzeug 1.0.1
I'm trying to run the Hello World using Flask framework :
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello() -> str:
return 'Hell world from Flask!'
app.run()
Then I go to my cmd and I run my script according to the documentation:
set FLASK_APP = flaskhello.py
python -m flask run
And what I get is a grey window with a click me header and when I click it i get the X and Y but I don't get the http address on my cmd to run it on browser. What should I do to correct this ?
I've already installed flask correctly as it seems, but I'm not sure.
edit. I also tried creating a new venv and the same happens
You are mixing old and new documentation. You can lose the last line in flaskhello.py (app.run()). Then, don't pass the flask run command to python, but run it directly in the CMD. So not python -m flask run, but flask run.
I've tested your code and it is serving a page with Hell world from Flask!, are you sure your flask servers starts, do you see the following in the console:
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [04/Aug/2019 13:35:44] "GET / HTTP/1.1" 200 -
Starting with Flask 0.11 there are multiple built-in ways to run a development server. The best one is the flask command line utility (https://flask.palletsprojects.com/en/1.1.x/server/)
export FLASK_APP= flaskhello.py
flask run
I've read a couple dozen threads on this issue and I cannot find a solution that has worked for me so any help you can provide for me to understand what is breaking the reloader is greatly appreciated. I'm still fairly new to dev (mainly worked in node, angular and django). I've done tests on mac and ubuntu, with both a minimal flask app and a large application setup via their docs, here is the simplest test of the various attempts I've made:
in terminal:
python3 -m venv virtualenv
source virtualenv/bin/activate
pip install flask
vim server.py
then
from flask import Flask
app = Flask(__name__)
#app.route('/')
def home():
return 'Hi'
wq and then back in terminal:
export FLASK_ENV=development
export FLASK_DEBUG=1
export FLASK_APP=server.py
flask run
now change the return statement string from 'hi' to 'hello' and nothing changes until I hit refresh on the browser. Importantly, the server does announce that there was a change - it just doesn't reload the browser. See output below:
(virtualenv) ➜ test git:(master) ✗ Flask run
* Serving Flask app "server.py" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 297-732-354
* Detected change in '/Users/pb/Documents/code/projects/test/server.py', reloading
* Restarting with stat
* Debugger is active!
* Debugger PIN: 297-732-354
I've tried this with template rendering, with alterations to css files, and like above with simple return statements. Thank you for any help you can offer me.
Flask detects the local file changes, but won't push the changes to your browser. Flask and the browser are fully de-coupled, Flask just stands there and waits for requests, it only responds if it receives a request. After return 'Hello', the connection between the browser and Flask is going to be disconnected.
If you don't make a request to Flask, Flask can't send you the response.
You can use https://github.com/lepture/python-livereload to create a livereload debug server which can auto refresh your browser.
I don't think the browser is supposed to reload the information by itself - you have to refresh the page for anything new to show up, unless you have built that functionality in with some sort of backend application.
This library livereload automatically refreshes the page upon file changes.
One of the latest versions is not working correctly, so you must install the specific version 2.5.1.
Install livereload at 2.5.1
pip install -Iv livereload==2.5.1
Change your wsgi.py (provided by the documentation)
# app is a Flask object
app = create_app()
# remember to use DEBUG mode for templates auto reload
# https://github.com/lepture/python-livereload/issues/144
app.debug = True
server = Server(app.wsgi_app)
# server.watch
server.serve()
Run python wsgi.py instead of flask run
Notice that it should display a different terminal than flask's.
I'm investigating how to develop a decent web app with Python. Since I don't want some high-order structures to get in my way, my choice fell on the lightweight Flask framework. Time will tell if this was the right choice.
So, now I've set up an Apache server with mod_wsgi, and my test site is running fine. However, I'd like to speed up the development routine by making the site automatically reload upon any changes in py or template files I make. I see that any changes in site's .wsgi file causes reloading (even without WSGIScriptReloading On in the apache config file), but I still have to prod it manually (ie, insert extra linebreak, save). Is there some way how to cause reload when I edit some of the app's py files? Or, I am expected to use IDE that refreshes the .wsgi file for me?
Run the flask run CLI command with debug mode enabled, which will automatically enable the reloader. As of Flask 2.2, you can pass --app and --debug options on the command line.
$ flask --app main.py --debug run
--app can also be set to module:app or module:create_app instead of module.py. See the docs for a full explanation.
More options are available with:
$ flask run --help
Prior to Flask 2.2, you needed to set the FLASK_APP and FLASK_ENV=development environment variables.
$ export FLASK_APP=main.py
$ export FLASK_ENV=development
$ flask run
It is still possible to set FLASK_APP and FLASK_DEBUG=1 in Flask 2.2.
If you are talking about test/dev environments, then just use the debug option. It will auto-reload the flask app when a code change happens.
app.run(debug=True)
Or, from the shell:
$ export FLASK_DEBUG=1
$ flask run
http://flask.palletsprojects.com/quickstart/#debug-mode
In test/development environments
The werkzeug debugger already has an 'auto reload' function available that can be enabled by doing one of the following:
app.run(debug=True)
or
app.debug = True
You can also use a separate configuration file to manage all your setup if you need be. For example I use 'settings.py' with a 'DEBUG = True' option. Importing this file is easy too;
app.config.from_object('application.settings')
However this is not suitable for a production environment.
Production environment
Personally I chose Nginx + uWSGI over Apache + mod_wsgi for a few performance reasons but also the configuration options. The touch-reload option allows you to specify a file/folder that will cause the uWSGI application to reload your newly deployed flask app.
For example, your update script pulls your newest changes down and touches 'reload_me.txt' file. Your uWSGI ini script (which is kept up by Supervisord - obviously) has this line in it somewhere:
touch-reload = '/opt/virtual_environments/application/reload_me.txt'
I hope this helps!
If you're running using uwsgi look at the python auto reload option:
uwsgi --py-autoreload 1
Example uwsgi-dev-example.ini:
[uwsgi]
socket = 127.0.0.1:5000
master = true
virtualenv = /Users/xxxx/.virtualenvs/sites_env
chdir = /Users/xxx/site_root
module = site_module:register_debug_server()
callable = app
uid = myuser
chmod-socket = 660
log-date = true
workers = 1
py-autoreload = 1
site_root/__init__.py
def register_debug_server():
from werkzeug.debug import DebuggedApplication
app = Flask(__name__)
app.debug = True
app = DebuggedApplication(app, evalex=True)
return app
Then run:
uwsgi --ini uwsgi-dev-example.ini
Note: This example also enables the debugger.
I went this route to mimic production as close as possible with my nginx setup. Simply running the flask app with it's built in web server behind nginx it would result in a bad gateway error.
For Flask 1.0 until 2.2, the basic approach to hot re-loading is:
$ export FLASK_APP=my_application
$ export FLASK_ENV=development
$ flask run
you should use FLASK_ENV=development (not FLASK_DEBUG=1)
as a safety check, you can run flask run --debugger just to make sure it's turned on
the Flask CLI will now automatically read things like FLASK_APP and FLASK_ENV if you have an .env file in the project root and have python-dotenv installed
app.run(use_reloader=True)
we can use this, use_reloader so every time we reload the page our code changes will be updated.
I got a different idea:
First:
pip install python-dotenv
Install the python-dotenv module, which will read local preference for your project environment.
Second:
Add .flaskenv file in your project directory. Add following code:
FLASK_ENV=development
It's done!
With this config for your Flask project, when you run flask run and you will see this output in your terminal:
And when you edit your file, just save the change. You will see auto-reload is there for you:
With more explanation:
Of course you can manually hit export FLASK_ENV=development every time you need. But using different configuration file to handle the actual working environment seems like a better solution, so I strongly recommend this method I use.
Use this method:
app.run(debug=True)
It will auto-reload the flask app when a code change happens.
Sample code:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "Hello World"
if __name__ == '__main__':
app.run(debug=True)
Well, if you want save time not reloading the webpage everytime when changes happen, then you can try the keyboard shortcut Ctrl + R to reload the page quickly.
From the terminal you can simply say
export FLASK_APP=app_name.py
export FLASK_ENV=development
flask run
or in your file
if __name__ == "__main__":
app.run(debug=True)
Enable the reloader in flask 2.2:
flask run --reload
Flask applications can optionally be executed in debug mode. In this mode, two very convenient modules of the development server called the reloader and the debugger are enabled by default.
When the reloader is enabled, Flask watches all the source code files of your project and automatically restarts the server when any of the files are modified.
By default, debug mode is disabled. To enable it, set a FLASK_DEBUG=1 environment variable before invoking flask run:
(venv) $ export FLASK_APP=hello.py for Windows use > set FLASK_APP=hello.py
(venv) $ export FLASK_DEBUG=1 for Windows use > set FLASK_DEBUG=1
(venv) $ flask run
* Serving Flask app "hello"
* Forcing debug mode on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 273-181-528
Having a server running with the reloader enabled is extremely useful during development, because every time you modify and save a source file, the server automatically restarts and picks up the change.
To achieve this in PyCharm set 'Environment Variables' section to:
PYTHONUNBUFFERED=1;
FLASK_DEBUG=1
For Flask 'run / debug configurations'.
To help with fast automatic change in browser:
pip install livereload
from livereload import Server
if __name__ == '__main__':
server = Server(app.wsgi_app)
server.serve()
Next, Start your server again:
eg. your .py file is app.py
python app.py
I believe a better solution is to set the app configuration. For me, I built the tool and then pushed it to a development server where I had to set up a WSGI pipeline to manage the flask web app. I had some data being updated to a template and I wanted it to refresh every X minutes (WSGI deployment for the Flask site through APACHE2 on UBUNTU 18). In your app.py or whatever your main app is, add app.config.update dictionary below and mark TEMPLATES_AUTO_RELOAD=True, you will find that any templates that are automatically updated on the server will be reflected in the browser. There is some great documentation on the Flask site for configuration handling found here.
app = Flask(__name__)
app.config.update(
TEMPLATES_AUTO_RELOAD=True
)
I'm investigating how to develop a decent web app with Python. Since I don't want some high-order structures to get in my way, my choice fell on the lightweight Flask framework. Time will tell if this was the right choice.
So, now I've set up an Apache server with mod_wsgi, and my test site is running fine. However, I'd like to speed up the development routine by making the site automatically reload upon any changes in py or template files I make. I see that any changes in site's .wsgi file causes reloading (even without WSGIScriptReloading On in the apache config file), but I still have to prod it manually (ie, insert extra linebreak, save). Is there some way how to cause reload when I edit some of the app's py files? Or, I am expected to use IDE that refreshes the .wsgi file for me?
Run the flask run CLI command with debug mode enabled, which will automatically enable the reloader. As of Flask 2.2, you can pass --app and --debug options on the command line.
$ flask --app main.py --debug run
--app can also be set to module:app or module:create_app instead of module.py. See the docs for a full explanation.
More options are available with:
$ flask run --help
Prior to Flask 2.2, you needed to set the FLASK_APP and FLASK_ENV=development environment variables.
$ export FLASK_APP=main.py
$ export FLASK_ENV=development
$ flask run
It is still possible to set FLASK_APP and FLASK_DEBUG=1 in Flask 2.2.
If you are talking about test/dev environments, then just use the debug option. It will auto-reload the flask app when a code change happens.
app.run(debug=True)
Or, from the shell:
$ export FLASK_DEBUG=1
$ flask run
http://flask.palletsprojects.com/quickstart/#debug-mode
In test/development environments
The werkzeug debugger already has an 'auto reload' function available that can be enabled by doing one of the following:
app.run(debug=True)
or
app.debug = True
You can also use a separate configuration file to manage all your setup if you need be. For example I use 'settings.py' with a 'DEBUG = True' option. Importing this file is easy too;
app.config.from_object('application.settings')
However this is not suitable for a production environment.
Production environment
Personally I chose Nginx + uWSGI over Apache + mod_wsgi for a few performance reasons but also the configuration options. The touch-reload option allows you to specify a file/folder that will cause the uWSGI application to reload your newly deployed flask app.
For example, your update script pulls your newest changes down and touches 'reload_me.txt' file. Your uWSGI ini script (which is kept up by Supervisord - obviously) has this line in it somewhere:
touch-reload = '/opt/virtual_environments/application/reload_me.txt'
I hope this helps!
If you're running using uwsgi look at the python auto reload option:
uwsgi --py-autoreload 1
Example uwsgi-dev-example.ini:
[uwsgi]
socket = 127.0.0.1:5000
master = true
virtualenv = /Users/xxxx/.virtualenvs/sites_env
chdir = /Users/xxx/site_root
module = site_module:register_debug_server()
callable = app
uid = myuser
chmod-socket = 660
log-date = true
workers = 1
py-autoreload = 1
site_root/__init__.py
def register_debug_server():
from werkzeug.debug import DebuggedApplication
app = Flask(__name__)
app.debug = True
app = DebuggedApplication(app, evalex=True)
return app
Then run:
uwsgi --ini uwsgi-dev-example.ini
Note: This example also enables the debugger.
I went this route to mimic production as close as possible with my nginx setup. Simply running the flask app with it's built in web server behind nginx it would result in a bad gateway error.
For Flask 1.0 until 2.2, the basic approach to hot re-loading is:
$ export FLASK_APP=my_application
$ export FLASK_ENV=development
$ flask run
you should use FLASK_ENV=development (not FLASK_DEBUG=1)
as a safety check, you can run flask run --debugger just to make sure it's turned on
the Flask CLI will now automatically read things like FLASK_APP and FLASK_ENV if you have an .env file in the project root and have python-dotenv installed
app.run(use_reloader=True)
we can use this, use_reloader so every time we reload the page our code changes will be updated.
I got a different idea:
First:
pip install python-dotenv
Install the python-dotenv module, which will read local preference for your project environment.
Second:
Add .flaskenv file in your project directory. Add following code:
FLASK_ENV=development
It's done!
With this config for your Flask project, when you run flask run and you will see this output in your terminal:
And when you edit your file, just save the change. You will see auto-reload is there for you:
With more explanation:
Of course you can manually hit export FLASK_ENV=development every time you need. But using different configuration file to handle the actual working environment seems like a better solution, so I strongly recommend this method I use.
Use this method:
app.run(debug=True)
It will auto-reload the flask app when a code change happens.
Sample code:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "Hello World"
if __name__ == '__main__':
app.run(debug=True)
Well, if you want save time not reloading the webpage everytime when changes happen, then you can try the keyboard shortcut Ctrl + R to reload the page quickly.
From the terminal you can simply say
export FLASK_APP=app_name.py
export FLASK_ENV=development
flask run
or in your file
if __name__ == "__main__":
app.run(debug=True)
Enable the reloader in flask 2.2:
flask run --reload
Flask applications can optionally be executed in debug mode. In this mode, two very convenient modules of the development server called the reloader and the debugger are enabled by default.
When the reloader is enabled, Flask watches all the source code files of your project and automatically restarts the server when any of the files are modified.
By default, debug mode is disabled. To enable it, set a FLASK_DEBUG=1 environment variable before invoking flask run:
(venv) $ export FLASK_APP=hello.py for Windows use > set FLASK_APP=hello.py
(venv) $ export FLASK_DEBUG=1 for Windows use > set FLASK_DEBUG=1
(venv) $ flask run
* Serving Flask app "hello"
* Forcing debug mode on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 273-181-528
Having a server running with the reloader enabled is extremely useful during development, because every time you modify and save a source file, the server automatically restarts and picks up the change.
To achieve this in PyCharm set 'Environment Variables' section to:
PYTHONUNBUFFERED=1;
FLASK_DEBUG=1
For Flask 'run / debug configurations'.
To help with fast automatic change in browser:
pip install livereload
from livereload import Server
if __name__ == '__main__':
server = Server(app.wsgi_app)
server.serve()
Next, Start your server again:
eg. your .py file is app.py
python app.py
I believe a better solution is to set the app configuration. For me, I built the tool and then pushed it to a development server where I had to set up a WSGI pipeline to manage the flask web app. I had some data being updated to a template and I wanted it to refresh every X minutes (WSGI deployment for the Flask site through APACHE2 on UBUNTU 18). In your app.py or whatever your main app is, add app.config.update dictionary below and mark TEMPLATES_AUTO_RELOAD=True, you will find that any templates that are automatically updated on the server will be reflected in the browser. There is some great documentation on the Flask site for configuration handling found here.
app = Flask(__name__)
app.config.update(
TEMPLATES_AUTO_RELOAD=True
)