Your SlideShare is downloading. ×
0
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
Retro - Web Services Made Easy
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

Retro - Web Services Made Easy

807

Published on

A short (5min) presentation of Retro, a Python toolkit that eases the creation of web services.

A short (5min) presentation of Retro, a Python toolkit that eases the creation of web services.

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

  • Be the first to like this

No Downloads
Views
Total Views
807
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
10
Comments
0
Likes
0
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. Retro web services made easy Sébastien Pierre, Datalicious @Montréal Python 7, May. 2009 www.datalicious.ca | github.com/sebastien/retro
  • 2. Why another Framework Toolkit ?
  • 3. Things have Changed The 90s “ Golden Spinning Logo Era” Web = Pages + Animated GIFs 3
  • 4. Things have Changed The 00s “ Social Startup AJAX 2.0 Era” Web = Model +View + Controller 4
  • 5. Things have Changed Now “ The Web of Data Era*” * aka “ semantic linked RDF data 3.0” ;) Web = Data + Interfaces 5
  • 6. Shifting our Perspective Web services are the new interfaces for the “ web of data” 6
  • 7. On Retro : Key Concepts Web services are APIs exposed over HTTP Web Service = HTTP data bus 7
  • 8. Retro : An example Population GDP Land Area (hectares) British Columbia 4,113,487 $164,583.00 91,837,000 Yukon 30,372 $1,452.00 47,890,000 Alberta 3,290,350 $187,493.00 61,400,000 Northwest Territories 41,464 $4,138.00 112,984,000 Exposing data through Saskatchewan 968,157 $39,834.00 58,939,000 Manitoba 1,148,401 $41,662.00 54,029,000 Nunavut 29,474 $1,115.00 192,138,000 Ontario Quebec A web service 12,160,282 7,546,131 $536,340.00 $265,888.00 88,303,000 132,970,000 New Brunswick 729,997 $23,669.00 7,133,000 Prince Edward Island 135,851 $4,149 564,000 Nova Scotia 913,462 $28,803.00 5,277,000 Newfoundland and Labrador 505,469 $19,696.00 35,498,000 8
  • 9. Step 1: Getting the data ;quot;Populationquot;;quot;GDPquot;;quot;Land Area (hectares)quot; quot;British Columbiaquot;;quot;4,113,487quot;;quot;$164,583.00quot;;quot;91,837,000quot; quot;Yukonquot;;quot;30,372quot;;quot;$1,452.00quot;;quot;47,890,000quot; quot;Albertaquot;;quot;3,290,350quot;;quot;$187,493.00quot;;quot;61,400,000quot; quot;Northwest Territoriesquot;;quot;41,464quot;;quot;$4,138.00quot;;quot;112,984,000quot; quot;Saskatchewanquot;;quot;968,157quot;;quot;$39,834.00quot;;quot;58,939,000quot; quot;Manitobaquot;;quot;1,148,401quot;;quot;$41,662.00quot;;quot;54,029,000quot; quot;Nunavutquot;;quot;29,474quot;;quot;$1,115.00quot;;quot;192,138,000quot; quot;Ontarioquot;;quot;12,160,282quot;;quot;$536,340.00quot;;quot;88,303,000quot; quot;Quebecquot;;quot;7,546,131quot;;quot;$265,888.00quot;;quot;132,970,000quot; quot;New Brunswickquot;;quot;729,997quot;;quot;$23,669.00quot;;quot;7,133,000quot; quot;Prince Edward Islandquot;;quot;135,851quot;;quot;$4,149quot;;quot;564,000quot; quot;Nova Scotiaquot;;quot;913,462quot;;quot;$28,803.00quot;;quot;5,277,000quot; quot;Newfoundland and Labradorquot;;quot;505,469quot;;quot;$19,696.00quot;;quot;35,498,000quot; DATA = list(csv.reader(open(quot;provinces.csvquot;),delimiter=quot;;quot;))[1:] 9
  • 10. Step 2: Writing the API class ProvincesAPI: def __init__( self, data ): self.data = data def list( self ): return list(l[0] for l in self.data) def province( self, name ): return ([l for l in self.data if l[0] == name] or [None])[0] def population( self, province ): return self.province(province)[1] def gdp( self, province ): return self.province(province)[2] def landArea( self, province ): return self.province(province)[3] 10
  • 11. Step 3: Testing it if __name__ == quot;__main__quot;: api = ProvincesAPI(DATA) for p in api.list(): print quot;Province:quot;, p print quot;­ gdp :quot;, api.gdp(p) print quot;­ population :quot;, api.population(p) print quot;­ land area :quot;, api.landArea(p) Province: British Columbia Province: Saskatchewan Province: New Brunswick ­ gdp : $164,583.00 ­ gdp : $39,834.00 ­ gdp : $23,669.00 ­ population : 4,113,487 ­ population : 968,157 ­ population : 729,997 ­ land area : 91,837,000 ­ land area : 58,939,000 ­ land area : 7,133,000 Province: Yukon Province: Manitoba Province: Prince Edward Island ­ gdp : $1,452.00 ­ gdp : $41,662.00 ­ gdp : $4,149 ­ population : 30,372 ­ land area : 47,890,000 ­ population : 1,148,401 ­ population : 135,851 Province: Alberta ­ land area : 54,029,000 ­ land area : 564,000 ­ gdp : $187,493.00 Province: Nunavut Province: Nova Scotia ­ population : 3,290,350 ­ gdp : $1,115.00 ­ gdp : $28,803.00 ­ land area : 61,400,000 ­ population : 29,474 ­ population : 913,462 Province: Northwest Territories ­ land area : 192,138,000 ­ land area : 5,277,000 ­ gdp : $4,138.00 Province: Ontario Province: Newfoundland and Labrador ­ population : 41,464 ­ gdp : $536,340.00 ­ gdp : $19,696.00 ­ land area : 112,984,000 ­ population : 12,160,282 ­ population : 505,469 11
  • 12. Step 4 : Exposing it from retro import * class ProvincesAPI(Component): def __init__( self, data ): Component.__init__(self) self.data = data @expose(GET=quot;/api/provinces/allquot;) def list( self ): return list(l[0] for l in self.data) @expose(GET=quot;/api/province/{name:string}quot;) def province( self, name ): name = name.lower().replace(quot; quot;,quot;quot;) return ([l for l in self.data if l[0].lower().replace(quot; quot;,quot;quot;) == name] or [None])[0] 12
  • 13. Step 4 : Exposing it Import retro from retro import * class ProvincesAPI(Component): def __init__( self, data ): Component.__init__(self) self.data = data @expose(GET=quot;/api/provinces/allquot;) def list( self ): return list(l[0] for l in self.data) @expose(GET=quot;/api/province/{name:string}quot;) def province( self, name ): name = name.lower().replace(quot; quot;,quot;quot;) return ([l for l in self.data if l[0].lower().replace(quot; quot;,quot;quot;) == name] or [None])[0] 13
  • 14. Step 4 : Exposing it from retro import * class ProvincesAPI(Component): Decorate the def __init__( self, data ): method to Component.__init__(self) expose it over HTTP self.data = data @expose(GET=quot;/api/provinces/allquot;) def list( self ): return list(l[0] for l in self.data) @expose(GET=quot;/api/province/{name:string}quot;) def province( self, name ): name = name.lower().replace(quot; quot;,quot;quot;) return ([l for l in self.data if l[0].lower().replace(quot; quot;,quot;quot;) == name] or [None])[0] 14
  • 15. Step 4 : Exposing it from retro import * class ProvincesAPI(Component): Use HTTP methodsself, data ): def __init__( as keyword Component.__init__(self) arguments self.data = data @expose(GET=quot;/api/provinces/allquot;) def list( self ): return list(l[0] for l in self.data) @expose(GET=quot;/api/province/{name:string}quot;) def province( self, name ): name = name.lower().replace(quot; quot;,quot;quot;) return ([l for l in self.data if l[0].lower().replace(quot; quot;,quot;quot;) == name] or [None])[0] 15
  • 16. Step 4 : Exposing it from retro import * class ProvincesAPI(Component): def __init__( self, data ): Specify URL to respond to Component.__init__(self) self.data = data @expose(GET=quot;/api/provinces/allquot;) def list( self ): return list(l[0] for l in self.data) @expose(GET=quot;/api/province/{name:string}quot;) def province( self, name ): name = name.lower().replace(quot; quot;,quot;quot;) return ([l for l in self.data if l[0].lower().replace(quot; quot;,quot;quot;) == name] or [None])[0] 16
  • 17. Step 4 : Exposing it from retro import * class ProvincesAPI(Component): def __init__( self, data ): Component.__init__(self) self.data = data @expose(GET=quot;/api/provinces/allquot;)Pass parameters from URL def list( self ): to Python method return list(l[0] for l in self.data) @expose(GET=quot;/api/province/{name:string}quot;) def province( self, name ): name = name.lower().replace(quot; quot;,quot;quot;) return ([l for l in self.data if l[0].lower().replace(quot; quot;,quot;quot;) == name] or [None])[0] 17
  • 18. Step 4 : Exposing it @expose(GET=quot;/api/province/{province:string}/populationquot;) def population( self, province ): return self.province(province)[1] @expose(GET=quot;/api/province/{province:string}/gdpquot;) def gdp( self, province ): return self.province(province)[2] @expose(GET=quot;/api/province/{province:string}/landAreaquot;) def landArea( self, province ): return self.province(province)[3] Don't change a line in your existing code 18
  • 19. Step 5 : Running it if __name__ == quot;__main__quot;: run(components=[ProvincesAPI(DATA)],port=8000) curl localhost:8000/api/provinces/all [quot;British Columbiaquot;,quot;Yukonquot;,quot;Albertaquot;,quot;Northwest Territoriesquot;,quot;Saskatchewanquot;,quot;Manitobaquot;,quot;Nunavutquot;,quot;Ontarioquot;,quot;Quebecquot;,quot;New Brunswickquot;, quot;Prince Edward Islandquot;,quot;Nova Scotiaquot;,quot;Newfoundland and Labradorquot;] curl localhost:8000/api/province/quebec/gdp quot;$265,888.00quot; curl localhost:8000/api/province/quebec/population quot;7,546,131quot; curl localhost:8000/api/province/quebec/landArea quot;132,970,000quot; 19
  • 20. Step 5 : Running it if __name__ == quot;__main__quot;: run(components=[ProvincesAPI(DATA)],port=8000) Runs the Retro embedded curl localhost:8000/api/provinces/all web server [quot;British Columbiaquot;,quot;Yukonquot;,quot;Albertaquot;,quot;Northwest Territoriesquot;,quot;Saskatchewanquot;,quot;Manitobaquot;,quot;Nunavutquot;,quot;Ontarioquot;,quot;Quebecquot;,quot;New Brunswickquot;, quot;Prince Edward Islandquot;,quot;Nova Scotiaquot;,quot;Newfoundland and Labradorquot;] curl localhost:8000/api/province/quebec/gdp quot;$265,888.00quot; curl localhost:8000/api/province/quebec/population quot;7,546,131quot; curl localhost:8000/api/province/quebec/landArea quot;132,970,000quot; 20
  • 21. Step 5 : Running it if __name__ == quot;__main__quot;: run(components=[ProvincesAPI(DATA)],port=8000) curl localhost:8000/api/provinces/all [quot;British Columbiaquot;,quot;Yukonquot;,quot;Albertaquot;,quot;Northwest Territoriesquot;,quot;Saskatchewanquot;,quot;Manitobaquot;,quot;Nunavutquot;,quot;Ontarioquot;,quot;Quebecquot;,quot;New Brunswickquot;, quot;Prince Edward Islandquot;,quot;Nova Scotiaquot;,quot;Newfoundland and Labradorquot;] curl localhost:8000/api/province/quebec/gdp quot;$265,888.00quot; Data is returned as JSON curl localhost:8000/api/province/quebec/population quot;7,546,131quot; curl localhost:8000/api/province/quebec/landArea quot;132,970,000quot; 21
  • 22. Step 6 : Surprise ! if __name__ == quot;__main__quot;: api = ProvincesAPI(DATA) for p in api.list(): print quot;Province:quot;, p print quot;­ gdp :quot;, api.gdp(p) print quot;­ population :quot;, api.population(p) print quot;­ land area :quot;, api.landArea(p) run(components=[api],port=8000) Your API object remains usable as it was before in Python 22
  • 23. Retro in a Nutshell WSGI­based Works with CGI, FCGI, SCGI, WSGI on Apache, Lighttpd, Nginx HTTP Streaming Uses WSGI generator (yield) support Standalone Comes with embedded web server and event reactor Lightweight Minimal API, small footprint 23
  • 24. The end Thank you ! www.github.com/sebastien/retro www.datalicious.ca sebastien@datalicious.ca

×