Flask
From charlesreid1
Contents
Basics
Basic App
Run a Flask app that is bound to all network interfaces on the host, and listens on port 5000:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "Hello, World!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
If host and port are not specified, flask will only listen on the local network interface on port 5000.
if __name__ == '__main__':
app.run(debug=True)
Routes
Simple hello world route
A simple hello world route:
from flask import Flask
...
@app.route('/hello')
def hello():
return "Hello, World!"
Returning HTML
To return HTML, we can return it in a string:
from flask import Flask
...
@app.route('/get_html')
def get_html():
return "<h2>Flask Returns HTML Code</h2>"
Returning JSON
If we are writing an API, we want routes that return JSON. we can use Flask's jsonify function:
from flask import Flask, jsonify
...
@app.route('/list')
def list():
d = {'a' : 1, 'b' : 2, 'c' : 3}
return jsonify(d)
Rendering templates
This example shows how to take an integer variable from the URL and use it on an HTML template page:
from flask import Flask, render_template
...
@app.route('/sample/<int:sample_number>')
def sample(sample_number):
render_template('sample.html', sample_number=sample_number)
The contents of sample.html are given below:
<html>
<head>
<title>Sample {{sample_number}}</title>
</head>
<body>
<h2>{{sample_number}}</h2>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula.</p>
</body>
</html>
Raising errors
To abort with a 400 (server error), use the abort function
from flask import Flask, abort
...
@app.route('/how_to_abort')
def how_to_abort():
import random
if random.random() < 0.5:
abort(400)
else:
return "<h2>Hi there!</h2>"
Exceptions and errors
To write a custom exception that will return abort(YYY) (where YYY is an HTTP code), you can write an exception class that defines a status_code private variable:
class InvalidUsage(Exception):
status_code = 400
def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
Next, we need to create a handler for this type of error, and register it with our application:
from flask import jsonify
...
class InvalidUsage(Exception):
...
@app.errorhandler(InvalidUsage)
def handle_invalid_usage(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
Described here in the flask documentation: http://flask.pocoo.org/docs/1.0/patterns/apierrors/
POST Endpoints
To deal with data sent via a POST request, use the request variable, imported from Flask, and get the POSTed data using request.json:
from flask import Flask, jsonify, abort, request
...
@app.route('/post_something',methods=['POST'])
def post_something():
if not request.json:
abort(400)
post_data = request.json
# Now render a template for the user
# and populate the template variables
# with data that was POSTed
render_template('posted.html',
title = post_data.get('title','A Pretty Boring Title'),
author = post_data.get('author','Anonymous Coward'),
color = post_data.get('color','blue'),
)
# NOTE:
# If you'd rather return json, just do
# return jsonify({'status':'ok'}), 200
Now we can POST data to the server by adding the JSON content type to a curl request, and pass data in using the -d flag. here's the curl request:
$ curl -i -H "Content-Type: application/json" -X POST -d '{"title":"My first post", "author":"Gladys Overwith", "color":"orange"}' http://localhost:5000/post_something
Packaging Flask Apps
Flask/Packaging - a page that covers how to bundle flask apps into a ready-to-distribute Python package
Resources
Flaskadillo
I put together a tutorial on how to use Flask. This is available in the flaskadillo repo:
Links
The Flask mega tutorial is really handy: http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world
Micro blog example: https://stormpath.com/blog/build-a-flask-app-in-30-minutes