20

Click here to load reader

Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

Embed Size (px)

DESCRIPTION

On Saturday, 12 of April, regular quarterly meeting of Tech Hangout Community took place in Creative Space 12, the cultural and educational center based in Kiev! The event was held under the motto «One day of inspiring talks on Web Back-End». This time Python, Ruby and PHP developers gathered to make peace and learn the Force. *TECH HANGOUT COMMUNITY was found in 2012 by the developers for the developers for knowledge and experience sharing. Such meetings are the part of Innovecs Educational Project that actively develops sphere of internal trainings and knowledge exchange program among professionals. This Initiative was born within the walls of Innovecs and has proved to be extremely popular and high-demand. In a short period of time it gained its own Facebook group with more than 90 members, blog with more than 40 posts and constant quarterly external meeting of Tech hangout community with more than 80 participants. The concept of the event proposes a 30-minute report on the topic previously defined, and the discussion in a roundtable session format. Join to discuss - https://www.facebook.com/groups/techhangout/

Citation preview

Page 1: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

REST APIs for Cruel World

(using Python)

April 12, 2004

Page 2: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12
Page 3: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

What is REST?• Client-Server

• Stateless

• Cacheable

• Layered System

• Uniform Interface

• Code on demand (optional)

Page 4: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

Why REST

• REST is awesome

• SOAP is ugly

• all others are even uglier

Page 5: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

REST ==* JSON

* at least let’s wish this

Page 6: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

REST verbsHTTP Method Action Examples

GET Obtain information about a resource

http://example.com/api/orders/ (retrieve list of orders)

GET Obtain information about a resource

http://example.com/api/orders/123 (retrieve order #123)

POST Create a new resource

http://example.com/api/orders (create a new order, from data

provided with the request)

PUT Update a resourcehttp://example.com/api/orders/123

(update order #123, from data provided with the request)

DELETE Delete a resource http://example.com/api/orders/123 (delete order #123)

Page 7: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

API versions• Always use version

• Versions in URLs:

• /api/v1.0

• /api/20140412/

• Versions in headers

Page 8: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

Authentication

• End-client to API server (oAuth)

• Server-to-Server

Page 9: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

Server-to-Server

• API key identification

• Signing with API secret

• Timestamp (servers should be ntp synced)

• Whitelists (optional)

Page 10: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

import hashlib!import hmac!!def get_signature(data, secret_key):! if isinstance(data, dict):! data = u'&'.join(! (u'='.join((key, value))! for (key, value) in sorted(data.iteritems())))! hash_key = hmac.new(!! ! secret_key, !! ! data.encode('utf-8'), !! ! hashlib.sha256)! return hash_key.hexdigest()

Page 11: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

timestamp = get_utc_timestamp()!!data = 'api_key=test&key=test&timestamp=%s' % timestamp!!signature = get_signature(data, TEST_SECRET_KEY)!!resp = (!! self.client.get(“/test?%s&signature=%s" % (!! ! data, signature))!)

Page 12: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

REST and Django

• Django-tastypie

• Django-rest-framework

Page 13: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

Django-tastypie

• Django model is resource

• All actions are hardly linked with models

• http://tastypieapi.org/

Page 14: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

Django-rest-framework• The Web browseable API

• Authentication policies including OAuth1a and OAuth2 out of the box.

• Serialization that supports both ORM and non-ORM data sources.

• Customizable all the way down

• http://www.django-rest-framework.org/

Page 15: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

from rest_framework.views import APIView!from rest_framework.response import Response!from rest_framework import (!! authentication, permissions!)!!class ListUsers(APIView):!! authentication_classes = (!! ! authentication.TokenAuthentication,)! permission_classes = (permissions.IsAdminUser,)!! def get(self, request, format=None):! usernames = [!! ! ! user.username for user in User.objects.all()]! return Response(usernames)

Page 16: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

django-rest-swagger!

!

!

!

• https://github.com/marcgibbons/django-rest-swagger

Page 17: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

Flask-RESTful

• http://flask-restful.readthedocs.org/en/latest/

Page 18: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

from flask import Flask!from flask.ext.restful import Api, Resource!!app = Flask(__name__)!api = Api(app)!!class UserAPI(Resource):! def get(self, id):! pass!! def put(self, id):! pass!! def delete(self, id):! pass!!api.add_resource(UserAPI, '/users/<int:id>', endpoint = 'user')

Page 19: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

API testingclass ApiAuthTestCase(BaseApiTestCase):! def test_get_without_params(self):! resp = self.client.get('/test')! self.assertEquals(resp.status_code, 400)!! def test_post_without_params(self):! resp = self.client.post('/test')! self.assertEquals(resp.status_code, 400)!! def test_get_bad_signature(self):! timestamp = get_utc_timestamp()! resp = self.client.get(! '/test?key=test&api_key=test&signature=bad&timestamp=%s' %! timestamp)! self.assertEquals(resp.status_code, 403)!

Page 20: Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - 2014.04.12

Volodymyr Hotsyk https://github.com/hotsyk/

@hotsyk

Questions?