Retro - Web Services Made Easy

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    Favorites, Groups & Events

    Retro - Web Services Made Easy - Presentation 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 ;\"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\" \"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\";\"12,160,282\";\"$536,340.00\";\"88,303,000\" \"Quebec\";\"7,546,131\";\"$265,888.00\";\"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\" DATA = list(csv.reader(open(\"provinces.csv\"),delimiter=\";\"))[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__ == \"__main__\": api = ProvincesAPI(DATA) for p in api.list(): print \"Province:\", p print \"­ gdp :\", api.gdp(p) print \"­ population :\", api.population(p) print \"­ land area :\", 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=\"/api/provinces/all\") def list( self ): return list(l[0] for l in self.data) @expose(GET=\"/api/province/{name:string}\") def province( self, name ): name = name.lower().replace(\" \",\"\") return ([l for l in self.data if l[0].lower().replace(\" \",\"\") == 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=\"/api/provinces/all\") def list( self ): return list(l[0] for l in self.data) @expose(GET=\"/api/province/{name:string}\") def province( self, name ): name = name.lower().replace(\" \",\"\") return ([l for l in self.data if l[0].lower().replace(\" \",\"\") == 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=\"/api/provinces/all\") def list( self ): return list(l[0] for l in self.data) @expose(GET=\"/api/province/{name:string}\") def province( self, name ): name = name.lower().replace(\" \",\"\") return ([l for l in self.data if l[0].lower().replace(\" \",\"\") == 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=\"/api/provinces/all\") def list( self ): return list(l[0] for l in self.data) @expose(GET=\"/api/province/{name:string}\") def province( self, name ): name = name.lower().replace(\" \",\"\") return ([l for l in self.data if l[0].lower().replace(\" \",\"\") == 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=\"/api/provinces/all\") def list( self ): return list(l[0] for l in self.data) @expose(GET=\"/api/province/{name:string}\") def province( self, name ): name = name.lower().replace(\" \",\"\") return ([l for l in self.data if l[0].lower().replace(\" \",\"\") == 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=\"/api/provinces/all\")Pass parameters from URL def list( self ): to Python method return list(l[0] for l in self.data) @expose(GET=\"/api/province/{name:string}\") def province( self, name ): name = name.lower().replace(\" \",\"\") return ([l for l in self.data if l[0].lower().replace(\" \",\"\") == name] or [None])[0] 17
    18. Step 4 : Exposing it @expose(GET=\"/api/province/{province:string}/population\") def population( self, province ): return self.province(province)[1] @expose(GET=\"/api/province/{province:string}/gdp\") def gdp( self, province ): return self.province(province)[2] @expose(GET=\"/api/province/{province:string}/landArea\") 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__ == \"__main__\": run(components=[ProvincesAPI(DATA)],port=8000) curl localhost:8000/api/provinces/all [\"British Columbia\",\"Yukon\",\"Alberta\",\"Northwest Territories\",\"Saskatchewan\",\"Manitoba\",\"Nunavut\",\"Ontario\",\"Quebec\",\"New Brunswick\", \"Prince Edward Island\",\"Nova Scotia\",\"Newfoundland and Labrador\"] curl localhost:8000/api/province/quebec/gdp \"$265,888.00\" curl localhost:8000/api/province/quebec/population \"7,546,131\" curl localhost:8000/api/province/quebec/landArea \"132,970,000\" 19
    20. Step 5 : Running it if __name__ == \"__main__\": run(components=[ProvincesAPI(DATA)],port=8000) Runs the Retro embedded curl localhost:8000/api/provinces/all web server [\"British Columbia\",\"Yukon\",\"Alberta\",\"Northwest Territories\",\"Saskatchewan\",\"Manitoba\",\"Nunavut\",\"Ontario\",\"Quebec\",\"New Brunswick\", \"Prince Edward Island\",\"Nova Scotia\",\"Newfoundland and Labrador\"] curl localhost:8000/api/province/quebec/gdp \"$265,888.00\" curl localhost:8000/api/province/quebec/population \"7,546,131\" curl localhost:8000/api/province/quebec/landArea \"132,970,000\" 20
    21. Step 5 : Running it if __name__ == \"__main__\": run(components=[ProvincesAPI(DATA)],port=8000) curl localhost:8000/api/provinces/all [\"British Columbia\",\"Yukon\",\"Alberta\",\"Northwest Territories\",\"Saskatchewan\",\"Manitoba\",\"Nunavut\",\"Ontario\",\"Quebec\",\"New Brunswick\", \"Prince Edward Island\",\"Nova Scotia\",\"Newfoundland and Labrador\"] curl localhost:8000/api/province/quebec/gdp \"$265,888.00\" Data is returned as JSON curl localhost:8000/api/province/quebec/population \"7,546,131\" curl localhost:8000/api/province/quebec/landArea \"132,970,000\" 21
    22. Step 6 : Surprise ! if __name__ == \"__main__\": api = ProvincesAPI(DATA) for p in api.list(): print \"Province:\", p print \"­ gdp :\", api.gdp(p) print \"­ population :\", api.population(p) print \"­ land area :\", 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

    + spierrespierre, 5 months ago

    custom

    718 views, 0 favs, 3 embeds more stats

    A short (5min) presentation of Retro, a Python tool more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 718
      • 650 on SlideShare
      • 68 from embeds
    • Comments 0
    • Favorites 0
    • Downloads 8
    Most viewed embeds
    • 50 views on http://www.ivy.fr
    • 17 views on http://ivy.fr
    • 1 views on http://209.85.227.132

    more

    All embeds
    • 50 views on http://www.ivy.fr
    • 17 views on http://ivy.fr
    • 1 views on http://209.85.227.132

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories