A collection of computer, gaming and general nerdy things.

Saturday, February 22, 2014

Flask-{Classy,Restful,Restless} Presentation draft.

Todo (the irony):
  • Actually make a slideshow.
  • Create code examples (keep it simple, a todo for example).
    • Simple SQLAlchemy todo example.
    • Not auth or users.
  • Practice giving the presentation to folks.

Overview

All allow for class based API design and varying degrees of control over endpoints.
  • Classy allows the most granular control and is designed specifically to be an extension to Flask.views.MethodView and Flask.view.View rather than strictly an API tool.
  • Restful allows for a less fine tuned experience than Classy but is designed specifically with designing APIs in mind.
  • Restless allows the least amount of control over the API and is heavy handed in it's configuration.

Classy

  • pip install flask-classy
  • Docs are located at http://pythonhosted.org/Flask-Classy/
  • Views are defined like: ExampleView(FlaskView) -> localhost:5000/example/
  • Has magic routes: get, post, put, delete, patch, etc.
  • Will return a 405 Method Not Allowed if a HTTP verb isn't defined.
  • Extra arguments are also automatically pulled from the URL:
    def get(self, id)
        pass
    /example/<arg1>/<arg2>/
  • However, extra arguments aren't explicitly typed
  • Can also define custom routes: simply define a new method, def custom(self): pass -> localhost:5000/example/custom
  • Endpoints: url_for('Example:custom')
  • Allows for custom routes with the route decorator (located in flask.ext.classy)
    @route('/notcustom/')
    def custom(self):
        pass
  • Route decorator can also define custom endpoints and do all things that the regular Flask.route decorator can.
  • Including explicitly typing arguments: @route('/<int:id>/)
  • Stacking route decorators doesn't cause collisions, rather Classy resolves them by adding identifiers.
  • Want a custom endpoint? Sure thing, brah. @route(endpoint='bro'). Classy also passes these straight to Flask. url_for('bro') instead of url_for('Example:bro')
  • Classy also allows changing the route base and route prefix. Add either route_base or route_prefix as a class variable to the view. OR when you're registering it, add the route_prefix or route_base keyword option.
  • Pre and post processors? Got those, too. before_request and after_request run before all requests. Care about only certain routes? before_custom and after_custom.
  • Order of resolution: @app.before_request, ExampleView.before_request, before_custom, custom, after_custom, ExampleView.after_request, @app.after_request
  • Tired of decoratoring a bunch of routes by hand? Gotcha back. Either decorate by hand OR define decorator as a list of decorators.
  • Need a subdomain? Done. You guessed it: subdomain class variable or when registering use the subdomain keyword.
  • Flask-Classy is not tied to a specific mimetype or data model -- use it to return XML from Mongo or SOAP from SQLAlchemy, render a template from a cache or send raw files that your cat typed when she jumped on your keyboard.
  • Makes it great for building on Blueprints OR building APIs.
  • Suggested companion libraries: Marshmallow (data marshalling) and mimerender (render different output for different mimetypes), WTForms (data validation).
  • Cons: Currently no error handling. Register FlaskView on a Blueprint to handle errors.

Flask-Restful

  • Developed by Twilio for their API (which is a fun service capable of cool things).
  • Designed specifically with APIs in mind.
  • Comes with native JSON support, but allows you to support other mimetypes by defining a data processor -- support XML, SOAP, CSV, plain text.
  • Methods should return a dictionary.
  • Comes with a request parser (built like argparse or optparse) (located at flask.ext.restful.reqparse.RequestParser) AND marshalling (that allows for nested and custom fields, feels like Marshmallow) located at flask.ext.restful.marshal_with and flask.ext.restful.fields
  • API resources are derived from flask.ext.restful.Resource and the API manager is located at flask.ext.restful.Api.
  • Allows wrapping of all resources with the method_decorators class variable.
  • Doesn't allow custom routes (i.e. adding /example/custom/) and requires explicit definition of variables upon registration.
  • However, it does allow one Resource to manage multiple URI endpoints.
  • More on RequestParser, marshals_with and fields here.

Flask-Restless

  • Explicitly bound not only to SQLAlchemy but also to JSON -- input AND output.
  • Almost completely configuration based.
  • Where Classy has FlaskView and Restful has Resource, Flask-Restless lies directly atop your models.
  • Other restrictions: models must have an id field that's the primary key AND is an integer (though, that's almost the default) AND the model must have an __init__ method that accepts all fields (SQLAlchemy does that by default, though). Supports BOTH flask-sqlalchemy AND vanilla SQLAlchemy.
  • You define which methods are allowed on a resource like a regular Flask route: ['GET', 'POST'] -- a list of verbs.
  • A note on verbs: PUT is aliased to PATCH. I disagree with this because PUT is to create or modify an entire resource at the endpoint (think UPSERT in SQL) and PATCH is a partial modification of a resource at an endpoint. Semantics, but semantics are important.
  • Good news: API-Model bridges are registered automatically (though, you can also return them for inspection).
  • Has a built in search feature.
  • Customization is painful. You must specify individual wrappers and processors for EACH verb.
  • Other cons: No built in validation. Documentation suggests validation in the models.
  • Project layout ends up with fat, fat models and almost non-existent controllers.