Python RESTful webservices with Python: Flask and Django solutions
-
Upload
solution4future -
Category
Technology
-
view
181 -
download
5
description
Transcript of Python RESTful webservices with Python: Flask and Django solutions
![Page 1: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/1.jpg)
RESTful webservices with Python
For lazy developersor
developers with deadlines
![Page 2: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/2.jpg)
source: http://s3-ec.buzzfed.com/static/enhanced/webdr01/2012/12/2/13/enhanced-buzz-wide-18383-1354473319-2.jpg
![Page 3: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/3.jpg)
Who am I?
Justyna Żarna Woman in Django / Python World
JavaScript freak
@Ustinez
http://solution4future.com
![Page 4: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/4.jpg)
1. REST software architecture.
Content
2. Benchmarks - problem analysis.
3. Flask + SQLAlchemy.
4. Django & class-based views. } case study
![Page 5: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/5.jpg)
XML/RPC
API
SOAP REST
based on HTTP protocol
many restriction on data types
synchronous
based on HTTP protocol or other protocols
synchronous
based on XML and all xml defects
???
![Page 6: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/6.jpg)
REpresentational State Transfer
What is so cool?
Resource
Representation Representation Representation
GET PUT POST DELETE
}
THE VERBS
http://a.com/resources/
http://a.com/resources/item1/ http://a.com/resources/item2/ http://a.com/resources/item3/
![Page 7: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/7.jpg)
REpresentational State Transfer
What is so cool?
1. Scalability
2. Generalization of interface
3. Independence
4. Security
5. Simplicity
6. In HTTP context but not limited to this protocol.
7. Good designed interface.
![Page 8: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/8.jpg)
make your API RESTful and go to rest...http://www.2010theyearinbooks.com/2012/12/december-beach-reads-for-australian.html
![Page 9: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/9.jpg)
Benchmark JSON response for frameworks and languages.
Python frameworks:
* Django-stripped 13 269 per second
* Flask - 11 506 per sec
* Django - 7122 per sec
http://www.techempower.com/blog/2013/04/05/frameworks-round-2/
![Page 10: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/10.jpg)
The source code and problems
https://github.com/TechEmpower/FrameworkBenchmarks/http://www.techempower.com/blog/2013/04/05/frameworks-round-2/
In this souce code for flask and django isn't used connection pool - cache of database connection.
database database
connectionconnectionconnection
connection
connection are maintained for future
connection for each request is open and closed.
![Page 11: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/11.jpg)
1. Database optimalization for PostgreSQL:● pgBouncer● pgPool
Solutions?
http://www.askthepony.com/blog/2011/07/django-and-postgresql-improving-the-performance-with-no-effort-and-no-code/
![Page 12: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/12.jpg)
2. JSON standard serialization in Python STD library is slow, so we can improve performance by using module ujson - ultra json.
Solutions?
code profiler can tell us more...
![Page 13: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/13.jpg)
3. Rendering template can be faster with template engine jinja (inspired by Django templates)
Solutions?
![Page 14: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/14.jpg)
● "micro" does not means micro possibilities,● core is light, simple and extensible,● support many extensions in each layer (for
example your database layer can by relational database or non-relational data persistence).
Flask
![Page 15: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/15.jpg)
from sqlalchemy import Column, Integer, Stringfrom newsletter.database import Base
class Member(Base): __tablename__ = 'newsletter_members' id = Column(Integer, primary_key=True) last_name = Column(String(50)) first_name = Column(String(120)) email = Column(String(120), unique=True)
def __init__(self, last_name=None, first_name=None, email=None): self.last_name = last_name self.first_name = first_name self.email = email
def __repr__(self): return '<Member %r>' % (self.last_name)
Case study - micro framework Flask
![Page 16: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/16.jpg)
class API(MethodView):
def get(self, member_id): if member_id is None: return Member.query.all() else: return Member.query.filter_by(id = member_id).first() def post(self, data ): member = Member(first_name = data['first_name'], email=data['email']) db.session.add(member) db.session.commit() return 'OK'
app.add_url_rule('/users/<int:user_id>', view_func=API.as_view('user_api'), methods=['GET', 'POST'])
#class flask.views.MethodView and recognizing each REST methods are based on generic dispatch_request()
Case study - micro framework Flask
![Page 17: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/17.jpg)
It was simple and quick to code?
Case study - micro framework Flask
improve simplicity and spent time with...Flask RESTless
![Page 18: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/18.jpg)
Flask RESTless - full scriptimport flaskimport flask.ext.sqlalchemyimport flask.ext.restlessapp = flask.Flask(__name__)app.config['DEBUG'] = Trueapp.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'db = flask.ext.sqlalchemy.SQLAlchemy(app)
class Member(db/Model): __tablename__ = 'newsletter_members' id = db.Column(Integer, primary_key=True) last_name = db.Column(String(50)) first_name = db.Column(String(120)) email = db.Column(String(120), unique=True)
db.create_all()
manager = flask.ext.restless.APIManager(app, flask_sqlalchemy_db=db)
manager.create_api(Member, methods=['GET', 'POST'])
app.run()
Too simple for real project.. ?
![Page 19: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/19.jpg)
Flask RESTless - more sugar
● versioning:
GET /api/memberGET /api/member/(int: id)GET /api/member?q=<json>POST /api/member
apimanager.create_api(Member, url_prefix='/api/v2')GET /api/v2/member
● validation:
manager.create_api(Member, methods=['GET', 'POST'], validation_exceptions=[ValidationError])
{ "validation_errors": { "email": "Email is not valid..", }}
![Page 20: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/20.jpg)
Flask RESTless - more sugar
● specify columns (include or exclude):
apimanager.create_api(Member, include_columns = ['last_name', 'email'])
● pagination:
manager.create_api(Member, methods=['GET', 'POST'], results_per_page=2)
{ "validation_errors": { "age": "Must be an integer", }{ "num_results": 6, "total_pages": 3, "page": 1, "objects": [ {"last_name": "Kovalsky", "email": "[email protected]", "id": 1}, {"last_name": "Novak", "email": "[email protected]", "id": 2} ]}
![Page 21: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/21.jpg)
Flask RESTless - more and more..
● pre/post-processors:def pre_get_single(instid): # do something pass
def pre_get_many(params): # do something pass
# Create an API for the Member model.manager.create_api(Person, methods=['GET', 'POST'], # A list of preprocessors for each method. preprocessors={'GET_SINGLE': [pre_get_single], 'GET_MANY': [pre_get_many],})
● Authentication:def auth_func(params): if not current_user.is_authenticated(): raise ProcessingException(message='Not authenticated!') return NO_CHANGEmanager.create_api(Person, preprocessors={'GET_SINGLE': [auth_func]})
![Page 22: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/22.jpg)
Flask RESTless - more and more..● filtering:
import requestsimport json
url = 'http://127.0.0.1:5000/api/member'headers = {'Content-Type': 'application/json'}
filters = [dict(email='email', op='like', val='%y%')]params = dict(q=json.dumps(dict(filters=filters)))response = requests.get(url, params=params, headers=headers)
GET /api/member?q={"filters":[{"name":"email", "op":"like", "val": "kovalsky"}]}
OPERATORS examples:○ ==, eq, !=, neq,○ >, gte, <, lte○ in, not_in○ is_null○ like○ has○ any
FOR RELATIONS:● column__column example:
member__group
![Page 23: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/23.jpg)
What about Django?
● Define your model:
from django.db import models
class Member(models.Model): last_name = models.CharField(max_length = 100, verbose_name = "Last name") first_name = models.CharField(max_length = 100, verbose_name = "First name") email = models.EmailField(max_length = 100, verbose_name = "Email")
def __unicode__(self): return self.email class Meta: verbose_name = "Newsletter member" verbose_name_plural = "Newsletter members"
![Page 24: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/24.jpg)
What about Django?● Define your model serializer:
class MemberSerializer(serializers.ModelSerializer): class Meta: model = Member fields = ('last_name', 'first_name', 'email')
● Working with serializers:from newsletter.models import Memberfrom newsletter.serializers import MemberSerializerfrom rest_framework.renderers import JSONRendererfrom rest_framework.parsers import JSONParser
member = Member(last_name='Kovalsky', first_name= 'Johny', 'email' = '[email protected]')member.save()
serializer = MemberSerializer(member)content = JSONRenderer().render(serializer.data)# content: {"pk": 2, "last_name": "Kovalsky", "first_name="Johny", email = "[email protected]"}, more object in format [{'foo': 'bar'}, {'foo': 'bar'}]
![Page 25: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/25.jpg)
What about Django?● Define your class-based views:
class MemberDetail(APIView): """ Retrieve, update or delete a member instance. """ def get_object(self, pk): try: return Member.objects.get(pk=pk) except Member.DoesNotExist: raise Http404
def get(self, request, pk, format=None): member = self.get_object(pk) serializer = MemberSerializer(member) return Response(member.data)
![Page 26: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/26.jpg)
What about Django?● Define your class-based views:
def put(self, request, pk, format=None): member = self.get_object(pk) serializer = MemberSerializer(member, data=request.DATA) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None): member = self.get_object(pk) member.delete() return Response(status=status.HTTP_204_NO_CONTENT)
![Page 27: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/27.jpg)
What about Django?
● Or generic views:from newsletter.models import Memberfrom newsletter.serializers import MemberSerializerfrom rest_framework import generics
class MemberList(generics.ListCreateAPIView): model = Member serializer_class = MemberSerializer
class MemberDetail(generics.RetrieveUpdateDestroyAPIView): model = Member serializer_class = MemberSerializer
● URLs patterns:
urlpatterns = patterns('', url(r'^members/$', views.MeberList.as_view()), url(r'^members/(?P<pk>[0-9]+)/$', views.MemberDetail.as_view()),)
![Page 28: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/28.jpg)
RESTful API - done
http://sarahwmackey.files.wordpress.com/
![Page 29: Python RESTful webservices with Python: Flask and Django solutions](https://reader034.fdocuments.us/reader034/viewer/2022042502/54c6b8934a79597d178b4676/html5/thumbnails/29.jpg)
Thank you for your attention
http://solution4future.com/