Click here to load reader
Upload
innovecs
View
1.648
Download
4
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
REST APIs for Cruel World
(using Python)
April 12, 2004
What is REST?• Client-Server
• Stateless
• Cacheable
• Layered System
• Uniform Interface
• Code on demand (optional)
Why REST
• REST is awesome
• SOAP is ugly
• all others are even uglier
REST ==* JSON
* at least let’s wish this
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)
API versions• Always use version
• Versions in URLs:
• /api/v1.0
• /api/20140412/
• Versions in headers
Authentication
• End-client to API server (oAuth)
• Server-to-Server
Server-to-Server
• API key identification
• Signing with API secret
• Timestamp (servers should be ntp synced)
• Whitelists (optional)
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()
timestamp = get_utc_timestamp()!!data = 'api_key=test&key=test×tamp=%s' % timestamp!!signature = get_signature(data, TEST_SECRET_KEY)!!resp = (!! self.client.get(“/test?%s&signature=%s" % (!! ! data, signature))!)
REST and Django
• Django-tastypie
• Django-rest-framework
Django-tastypie
• Django model is resource
• All actions are hardly linked with models
• http://tastypieapi.org/
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/
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)
django-rest-swagger!
!
!
!
• https://github.com/marcgibbons/django-rest-swagger
Flask-RESTful
• http://flask-restful.readthedocs.org/en/latest/
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')
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×tamp=%s' %! timestamp)! self.assertEquals(resp.status_code, 403)!