Your SlideShare is downloading. ×
0
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
RESTful Web Services with Python - Dynamic Languages conference
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

RESTful Web Services with Python - Dynamic Languages conference

20,440

Published on

Published in: Technology
0 Comments
22 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
20,440
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
272
Comments
0
Likes
22
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. ‎RESTful Web Services with Python<br />Juozas“Joe”Kaziukėnas<br />http://juokaz.com / juozas@juokaz.com / @juokaz<br />
  • 2. Who is this guy?<br />JuozasKaziukėnas, Lithuanian<br />You can call me Joe<br />3 years in Edinburgh, UK<br />CEO of Web Species<br />Occasional open source developer<br />Conferences speaker<br />More info in http://juokaz.com<br />Tweet me @juokaz<br />
  • 3. What is a RESTful API?<br />
  • 4. What is an API?<br />Web service is a type of web application<br />Integrate different apps together<br />Mashups<br />Content is in multiple formats<br />JSON<br />XML<br />HTML?<br />Used by other apps mainly<br />Not necessary<br />
  • 5. REST<br />REpresentational State Transfer<br />99% HTTP, 1% conventions/ideas<br />Stateless<br />Resources<br />Name -&gt; URI<br />http://apple.com/devices/iphone<br />Hierarchy<br />Operations<br />Not in the URL, but via HTTP terms<br />Trivial to cache<br />Cache-control, Last-Modified, Expires, Etag<br />
  • 6. Difference from other web services<br />XML-RPC<br />Single url as a front controller <br />Calling methods on a remote app<br />Most of the actions are via POST<br />SOAP<br />No comments…<br />
  • 7. Difference from web apps<br />PUT and DELETE HTTP verbs<br />POST and GET only supported by browsers today<br />Create: POST<br />Update: PUT<br />Delete: DELETE<br />View: GET<br />Status codes<br />Not just 404 and 500<br />Meaning of the response without analyzing the returned data<br />And many other headers<br />Web page is not a resource, it’s a representation of a resource<br />
  • 8. Accept header means the format<br />$ curl -H &quot;Accept: application/html&quot; localhost/products/iphone&lt;html&gt;&lt;body&gt;Iphone 5&lt;/body&gt;&lt;/html&gt;$ curl -H &quot;Accept: application/xml&quot; localhost/products/iphone&lt;name&gt;Iphone 5&lt;/name&gt;$ curl -H &quot;Accept: application/json“ localhost/products/iphone{‘name’:‘Iphone 5’} $ curl -H &quot;Accept: text/plain&quot; localhost/products/iphoneIphone 5<br />
  • 9. Doing it wrong<br />
  • 10. URLs<br />Before we had:<br />http://www.example.com/videos.py?by=joe&amp;type=funny<br />Now we have:<br />http://www.example.com/videos/funny/joe/offset/0/10<br />This is wrong<br />
  • 11. REST + XML-RPC<br />What is new?<br />http://www.example.com/clients/new<br />Unclear hierarchy<br />http://www.example.com/clients/photos/32723<br />Filtering<br />http://www.example.com/clients/name/john/offset/10/sort/name<br />
  • 12. Wrong<br />Everything is REST now<br />But it’s not<br />Twitter, Facebook, Google all inventing their own @$^&amp;$s<br />“Users are stupid”, ditching standards<br />How to figure out the URIs?<br />To fix this you need…<br />
  • 13. HATEOAS<br />Hypermedia as the Engine of Application State<br />
  • 14. The steps to being REST<br />“The Swamp of POX.” You’re using HTTP to make RPC calls. HTTP is only really used as a tunnel.<br />Resources. Rather than making every call to a service endpoint, you have multiple endpoints that are used to represent resources, and you’re talking to them. This is the very beginnings of supporting REST.<br />HTTP Verbs. This is the level that something like Rails gives you out of the box: You interact with these Resources using HTTP verbs, rather than always using POST.<br />Hypermedia Controls. HATEOAS. You’re 100% REST compliant.<br />From Richardson Maturity Model<br />
  • 15. HATEOAS<br />A requirement for REST<br />One url, everything else is discoverable<br />What to<br />Do next?<br />Do with the resource?<br />Reduces code errors<br />Invalid URLS<br />Invalid state transfers<br />Documentation is not needed<br />Evolution<br />
  • 16. XML example<br />&lt;appointment&gt;<br /> &lt;slot id=&quot;1234&quot; doctor=&quot;mjones&quot; start=&quot;1400&quot; end=&quot;1450“/&gt;<br /> &lt;patient id=&quot;jsmith“/&gt;<br /> &lt;link rel=&quot;cancel&quot; uri=&quot;/slots/1234/appointment&quot;/&gt;<br /> &lt;link rel=&quot;addTest&quot; uri=&quot;/slots/1234/appointment/tests&quot;/&gt;<br /> &lt;link rel=&quot;updateContactInfo&quot; uri=&quot;/patients/jsmith/contactInfo&quot;/&gt;<br />&lt;/appointment&gt;<br />
  • 17. Accept header means the format<br />Media type<br />Versioning<br />$ curl -H &quot;Accept: application/vnd.demo.v1+json“ localhost/products/iphone{‘name’:‘Iphone 5’}$ curl -H &quot;Accept: application/vnd.demo.v2+json&quot; localhost/products/iphone{‘product_name’:‘Iphone 5’}<br />
  • 18. Solving the problems with Python<br />
  • 19. How to create a REST protocol<br />What are the URIs?<br />What&apos;s the format?<br />What methods are supported at each URI?<br />What status codes could be returned?<br />By Joe Gregorio<br />
  • 20. Why Python?<br />Fast, relatively <br />Robust to develop<br />New code live in seconds<br />Huge selection of web frameworks<br />Interfaces with databases, servers etc.<br />APIs do not need much else<br />
  • 21. Python<br />As long as it’s WSGI it’s OK<br />Simple code<br />Different feature sets<br />Talking here about<br />Django<br />Bottle, similar to Flask<br />Web.py<br />Tornado (asynchronous)<br />Render content in the request format<br />
  • 22. Sample API with Django<br />xml_poll_resource= Collection( <br />queryset= Poll.objects.all(), <br />permitted_methods= (&apos;GET&apos;, &apos;POST&apos;, &apos;PUT&apos;, &apos;DELETE&apos;), <br />expose_fields= (&apos;id&apos;, &apos;question&apos;, &apos;pub_date&apos;), <br /> responder = XMLResponder(paginate_by = 10) <br />) <br />xml_choice_resource= Collection( <br />queryset= Choice.objects.all(), <br />permitted_methods= (&apos;GET&apos;,), <br />expose_fields= (&apos;id&apos;, &apos;poll_id&apos;, &apos;choice&apos;), <br /> responder = XMLResponder(paginate_by = 5) <br />)<br />urlpatterns= patterns(&apos;&apos;, <br />url(r&apos;^xml/polls/(.*?)/?$&apos;, xml_poll_resource), <br />url(r&apos;^xml/choices/(.*?)/?$&apos;, xml_choice_resource) <br />) <br />
  • 23. Sample API with Bottle<br />importbottlefrombottleimport route, run <br />@route(&apos;/&apos;, method=&apos;GET&apos;) <br />defhomepage(): <br /> return&apos;Hello world!&apos; <br />@route(&apos;/events/:id&apos;, method=&apos;GET&apos;) <br />defget_event(id): <br /> returndict(name = &apos;Event &apos; + str(id)) <br />bottle.debug(True) <br />run()<br />
  • 24. Sample API with Tornado<br />class PlaceHandler(tornado.web.RequestHandler):<br />    def get(self, id):<br />        self.write(&apos;GETting something&apos;)<br /> <br />    def post(self):<br />        self.write(&apos;POSTing something&apos;)<br />application = tornado.web.Application([<br />    (r&quot;/place&quot;, PlaceHandler),<br />    (r&quot;/place/([0-9]+)&quot;, PlaceHandler)<br />])<br /> <br />if __name__ == &quot;__main__&quot;:<br />    http_server = tornado.httpserver.HTTPServer(application)<br />    tornado.ioloop.IOLoop.instance().start()<br />
  • 25. MIME types<br />Detect which format to use from Accept header<br />Content negotiation<br />Mimeparse - http://code.google.com/p/mimeparse/<br />Use it, works great<br />&gt; mimeparse:best_match([&quot;application/xbel+xml&quot;, &quot;text/xml&quot;], &quot;text/*;q=0.5,*/*; q=0.1&quot;).&gt; &quot;text/xml&quot;<br />
  • 26. Mimerender<br />render_xml= lambda message: &apos;&lt;message&gt;%s&lt;/message&gt;&apos;%messagerender_json = lambda **args: json.dumps(args)render_html = lambda message: &apos;&lt;html&gt;&lt;body&gt;%s&lt;/body&gt;&lt;/html&gt;&apos;%messageurls = (&apos;/(.*)&apos;, &apos;greet&apos;)app = web.application(urls, globals())<br />class greet:    @mimerender(default = &apos;html&apos;, html = render_html, xml = render_xml, json= render_json)    def GET(self, name):        if not name:             name = &apos;world&apos;        return {&apos;message&apos;: &apos;Hello, &apos; + name + &apos;!&apos;}if __name__ == &quot;__main__&quot;:    app.run()<br />
  • 27. Return formats<br />Rendering XML takes a lot of code<br />doc =xml.dom.minidom.Document()# Something happensreturn doc.toxml()<br />JSON is as easy as<br />json_dumps(data, sort_keys=True)<br />Maybe allow human readable output<br />json_dumps(data, sort_keys=True, indent=4)<br />JSON is great for Ajax, if not XML brings huge advantages<br />
  • 28. Which framework to choose<br />Django for existing apps<br />Different sub-frameworks for REST<br />Bottle or similar<br />Small<br />Effective<br />Build your own logic<br />Asynchronous Tornado <br />If API needs to be asynchronous<br />
  • 29. What’s missing<br />Cache headers<br />Authentication<br />Different types<br />No real REST framework<br />
  • 30. Applying it practically for Edinburgh Festivals<br />
  • 31. Applying it practically for Edinburgh Festivals<br />Start at http://api.festivalslab.com<br />7 summer festivals<br />Built in 100% Python<br />Fast<br />Very stable<br />Some bad decisions<br />Works awesome<br />More info in the blog<br />
  • 32. Structure<br />
  • 33. Inside<br />Whole API – 100 LoC of Python code<br />Mainly interacting with the ElasticSearch server<br />Scheduled data imports – main task<br />Nginx as a reverse proxy<br />Supervisor to manage the processes<br />
  • 34. Conclusion<br />
  • 35. Conclusion<br />REST is awesome<br />Support different formats<br />Follow HATEOAS<br />Try to create as little as possible custom behaviour<br />Go with light Python code<br />
  • 36. Keep in touch: http://juokaz.com / juozas@juokaz.com / @juokaz<br />Thank you!<br />We can help you build them, talk to us!<br />

×