Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Creating a REST API with Python and Flask - PyD...

Creating a REST API with Python and Flask - PyDX 2015

Flask is a small, lightweight and very flexible web framework for Python. In this talk I want to show you how Flask makes it easy to build an Application Programming Interface (API). I will begin with a brief overview of the REST architecture for APIs, and then show you how the Flask routing mechanism fits the REST model so nicely that writing an API becomes simple and even fun.

Miguel Grinberg

October 06, 2015
Tweet

More Decks by Miguel Grinberg

Other Decks in Programming

Transcript

  1. About Me OpenStack Engineer @ Rackspace Author of the O’Reilly

    book “Flask Web Development” Author of Flask-SocketIO, Flask-Migrate, Flask- HTTPAuth and a few more Flask extensions My blog: http://blog.miguelgrinberg.com
  2. API A set of rules and protocols by which two

    components agree to communicate.
  3. Fat Server API Model Client • User interaction Server •

    Application logic • Rendering • User input handling • Data management
  4. Fat Client API Model Client • User interaction • Application

    logic • Rendering • User input handling Server • Data management
  5. The Six REST Principles • Client-Server • Uniform Interface ◦

    Identification of Resources ◦ Manipulation of Resources Through Representations ◦ Self-Descriptive Messages ◦ Hypermedia as the Engine of Application State (HATEOAS) • Stateless • Layered System • Cacheable • Code-on-Demand (optional) Watch my PyCon 2015 talk “Is your REST API RESTful?” to learn what these are.
  6. Resources • Resources represent the entities in the application’s domain

    ◦ Customers, Invoices, Products, Players, Games, etc. ◦ Can also represent physical objects: Garage doors, cameras, sensors, etc. • Each resource or collection of resources has a unique URL ◦ https://api.example.com/customers ◦ https://api.example.com/customers/123 ◦ https://api.example.com/customers/123/invoices • Clients work with resource representations ◦ JSON {“first”: “Susan”, “last”: “Smith”, “phone”: “503-111-2222”} ◦ XML <?xml version=”1.0”?><first>Susan</first><last>Smith</last><phone>503-111-2222</phone>
  7. • The client sends a HTTP request to the server

    ◦ The request method specifies the action to perform. Examples: GET(read), POST(create), PUT(edit), DELETE ◦ The URL specifies the target resource ◦ The request body specifies a resource representation (POST and PUT only) ◦ The request headers contain metadata (content types, caching details, etc.) • The server sends a HTTP response back to the client ◦ The status code specifies the result of the operation 200 (OK), 201 (Created), 202 (Accepted), 400 (Bad Request), 404 (Not Found), etc. ◦ The response body specifies a resource representation ◦ The response headers contain metadata Requests and Responses
  8. What’s in the (Flask) Box? • Built in development server

    and debugger • Integrated unit testing support • RESTful request dispatching • Uses Jinja2 templating • Support for secure cookies (client side sessions) • 100% WSGI 1.0 compliant • Unicode based • Extensively documented • Built in development server and debugger • Integrated unit testing support • RESTful request dispatching • Uses Jinja2 templating • Support for secure cookies (client side sessions) • 100% WSGI 1.0 compliant • Unicode based • Extensively documented
  9. @app.route('/customers', methods=['GET']) def a_function(): pass RESTful Request Dispatching @app.route('/customers', methods=['POST'])

    def another_function(): pass @app.route('/customers', methods=['GET']) @app.route('/customers', methods=['GET']) @app.route('/customers/<int:id>', methods=['DELETE']) def yet_another_function(id): pass
  10. The 90-90 Rule The first 90% of the code accounts

    for 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time. Tom Cargill, Bell Labs
  11. • Use Flask’s native dispatching to implement your base API

    endpoints • Manage the actual resources: the choice is yours! ◦ Database resources: SQLAlchemy, Peewee, direct DB access, etc. ◦ Physical devices: Use the appropriate Python package to control the device • Handle resource representations ◦ Manually through dictionaries and the native JSON/XML packages ◦ Using more sophisticated third party packages: Flask-RESTful, Marshmallow, etc. • Add token based authentication ◦ Flask-HTTPAuth wraps authentication at the HTTP protocol level • Return appropriate error responses • Encapsulate resources in Python modules to keep things organized The First 90%
  12. • Filtering • Sorting • Pagination • Asynchronous requests •

    Caching • Rate Limiting • Hypermedia • … WTF??? None of these things are directly related to specific resources in your application, so they should not clutter your resources! The Other 90%
  13. @api.route('/customers/<int:id>/invoices', methods=['GET']) @etag @json @collection(Invoice) def get_customer_invoices(id): return Customer.query.get_or_404(id).invoices Decorators

    To The Rescue! @api.route('/cameras/<int:id>/movies', methods=['POST']) @async def capture_movie(id): camera = get_camera_from_id(id) movie_id = camera.start_recording() return url_for('get_movie', id=movie_id)