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