Python: Flask
WSGI
- The Web Server Gateway Interface (WSGI, pronounced whiskey) is a Python specification
which specifies how a web server can communicate with web applications in order to satisfy requests.
Flask
is a WSGI application
- A WSGI server is used to run the application. It converts incoming HTTP requests
to WSGI requests and WSGI responses to HTTP responses.
- WSGI servers have HTTP servers built-in.
- However, for a multitude of reasons (security, etc.) WSGI servers are usually fronted by a dedicated HTTP server
such as Apache or Nginx
Gunicorn - a WSGI Server
- Gunicorn is a WSGI server with a simple configuration which supports multiple worker implementations for performance tuning
- Here is how you start Gunicorn
# -w = number of workers (rule of thumb - #cpu*2)
gunicorn -w 4 'hello:app' # equivalent to 'from hello import app' - 4 workers
- Gunicorn should not be run as
root
, because that would cause your applicaiton code to also run as root
- which is not secure
- However, this means you will not be able to bind to port 80 or 443
- If you need to be listening on these ports, a reverse proxy such as nginx or Apache should be used in front of gunicorn
- A Flask application is an instance of the
Flask
class.
- The recommended method to create a Flask object is inside a factory method
Minimal Application
# hello_world.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
- To execute
hello_world.py
, use the flask
command or python3 -m flask
,
ensuring you set and export the FLASK_APP
environment variable
$ export FLASK_APP="$PWD/hello_world.py"
$ flask run &
* Running on http://127.0.0.1:5000
$ curl 127.0.0.1:5000
...
#
# flask_hello_world.py
#
import Flask
# Flask needs to
app = Flask(__name__)
# "/" should trigger hello_world()
@app.route("/")
def index()
return <"p>index</p>"
@app.route("/hello_world")
def hello_world()
return "<p>Hello, World!</p>"
export FLASK_APP=flask_hello_world.py; flask run
curl http://127.0.0.1:5000
- To have an externally visible URL, use
flask run --host=0.0.0.0
- which instructs Flask to listen on all IP addresses
[Suggested] Directory Structure
application
|-flaskr/ # application code boes here
| __init__.py
Acknowledgements