Flask RESTful Services
There is an alternative to DJango
http://flask.pocoo.org/
Who Am I?
Why Flask?
Simple
Intuitive
Loads of Extensions
Pythonic
Hello World in 3 Steps
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def root():
msg = {"message": "Hello World"}
return jsonify(msg)
if __name__ == "__main__":
app.run()
1. Creation of the Flask App
2. Define Route
3. Return dictionary as JSON
1. Response
Simple Response
@app.route("/simple/")
def return_simple():
return "I lost it", 404
Returning a Generator
@app.route("/generator/")
def return_generator():
def loads_of_data():
yield "["
for i in xrange(5):
if i:
yield ","
yield '{ "key%d": "Entry Number %d"}' % (i, i)
yield "]"
return Response(loads_of_data(), content_type="application/json")
Generator Function
Returning a Response
@app.route("/response/")
def return_response():
msg = {"message": "I am working on that..."}
msg_json = json.dumps(msg)
return Response(msg_json, content_type="application/json",
status=202)
class flask.Response(response=None, status=None, headers=None,
mimetype=None,content_type=None, direct_passthrough=False)
Returning a File
@app.route("/file/")
def return_file():
return send_file('flask_logo.png')
flask.send_file(filename_or_fp, mimetype=None,
as_attachment=False,attachment_filename=None, add_etags=True,
cache_timeout=None,conditional=False)
2. Routing
Dynamic Route
@app.route("/car/<make>/<model>")
def car(make, model):
car = {
"make": make,
"model": model
}
return jsonify(car)
Dynamic Route - Set Type
@app.route("/car/<string:make>/<int:model>")
def car(make, model):
car = {
"make": make,
"model": model
}
return jsonify(car)
Specify type of params
Dynamic Route - Set Default
@app.route("/car/<string:make>/<int:model>")
@app.route("/car/<string:make>/", defaults={"model": 500})
@app.route("/car/", defaults={"make": "Fiat", "model": 500})
def car(make, model):
car = {
"make": make,
"model": model
}
return jsonify(car)
REST Verbs
@app.route("/inventory/", methods=['POST'])
def inventory_post():
data = request.json
resp = jsonify({"idinput": data.get("id")})
resp.status_code = 201
return resp
methods allow a list of verbs
jsonify returns a Response object
Talk is Cheap...
3. Advance-ish
Static File Server
@app.route('/<path:path>')
def send_app(path):
return send_from_directory('www/', path)
@app.route('/')
def send_app_index():
return send_from_directory('www/', 'index.html')
Database Connection
from flask import g
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = connect_to_database()
return db
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
http://flask.pocoo.org/docs/0.10/patterns/sqlite3/
Use Flask’s Global Object
Open connection if not connected
Close connection when request is done
Exception Handling
def restful_error_handler(ex):
resp = jsonify(error_message=str(ex))
if isinstance(ex, HTTPException):
resp.status_code = ex.code
else:
resp.status_code = 500
return resp
for code in default_exceptions.iterkeys():
app.error_handler_spec[None][code] = restful_error_handler
http://flask.pocoo.org/snippets/83/
Set Response Code
[<blueprint name>][<http code>]
Blueprint
bp = Blueprint('car', __name__)
@bp.route("/<make>/<model>"):
def return_car(make, model):
return jsonify({ "make": make, "model": model})
app.register_blueprint(bp, url_prefix='/car')
Create a Blueprint object
Declare route of the blueprint
Register blueprint
Putting it all together
More Info
http://flask.pocoo.org/
http://flask.pocoo.org/extensions/
http://docs.python-requests.org/en/latest/
https://github.com/marcoslin/flask-restful-into
@marcoseu
marcos.lin@farport.co.uk

Flask restfulservices