Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Libsaas: one API to rule them all
Search
Aitor Guevara
May 29, 2014
Technology
220
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Libsaas: one API to rule them all
APIdays Mediterranea May 2014, Barcelona
Aitor Guevara
May 29, 2014
More Decks by Aitor Guevara
See All by Aitor Guevara
Concurrent IO & Python
aitorciki
8
1.1k
From pull to push: towards a real-time web
aitorciki
4
350
Ducksboard's architecture, a real-time online dashboard
aitorciki
12
2.7k
Ducksboard - Betabeers BCN
aitorciki
1
220
Other Decks in Technology
See All in Technology
触りたくないデータに、どう触るか AI時代のRBACアクセスガバナンス
ivry_presentationmaterials
0
310
CTO Night|NotionのAIエージェントとFDE
kzkhykw1991
0
290
AIにシークレットを見せない、WSL2で安全な開発環境
yazm
0
330
React改造してみた
tsukina_7mochi
0
140
Rustuna: Rustによる高速なOptuna実装
pfn
PRO
0
210
freeeにおけるSoftware Factory
freee
PRO
0
220
『SAR衛星データ解析入門』のご紹介とその応用
syuchimu
0
140
OptunaHub: ブラックボックス最適化のためのプラットフォーム
pfn
PRO
0
150
Persisting Massive Data with Rails ~Designing for 60 billion rows, and fighting the bottlenecks~ Railsで挑む大量データ永続化 〜600億件を永続化するための設計とボトルネックとの戦い〜
occhi
0
770
Kiro Crewで「みのるん式」仕事術やってみた
minorun365
PRO
3
960
Getting Started with Google Antigravity
glaforge
0
340
野蛮なアジャイル [サイボウズ発!]組織の常識を覆した反骨のスクラム実践記 / Barbaric Agile - Enterprise Agile Study Group
ama_ch
0
120
Featured
See All Featured
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Google's AI Overviews - The New Search
badams
0
1.6k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
22k
From π to Pie charts
rasagy
1
400
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
860
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
930
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
450
Practical Orchestrator
shlominoach
192
12k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
Designing for humans not robots
tammielis
254
26k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Transcript
libsaas one API to rule them all Aitor Guevara •
@aitorciki
Context
business data spread across cloud services
Ducksboard consumes SaaS APIs to collect and visualize data
None
None
REST APIs
heterogeneous implementations headers, query params, auth, mime types, versioning, error
handling…
ad-hoc vendor libraries data structures, HTTP handling, sync/async IO, Python
versions
Enter libsaas
abstraction layer on top of heterogeneous SaaS APIs URLs generation,
parameters serialization, authentication, …
uniform interface Python methods and objects supports Python 2.x, Python
3.x, PyPy
extensible implement services as modules base classes, decorators, helpers, documentation
auto-generation
agnostic isolates modelling from networking
Architecture
service / resources hierarchy of Python classes
filters reusable requests modifiers e.g. pre-built authentication mechanisms
executors pluggable HTTP handlers urllib2, Requests, Twisted
parsers know how to deserialize responses JSON, XML
Example: service definition
1 import json 2 from libsaas import http 3 from
libsaas.filters import auth 4 from libsaas.services import base 5 from . import repos 6 7 class GitHub(base.Resource): 8 9 def __init__(self, token_or_username, password=None): 10 self.apiroot = 'https://api.github.com' 11 12 self.add_filter(self.use_json) 13 14 if password is None: 15 self.oauth_token = token_or_username 16 self.add_filter(self.add_authorization) 17 else: 18 self.add_filter(auth.BasicAuth(token_or_username, password)) 19 20 def add_authorization(self, request): 21 request.headers['Authorization'] = 'token {0}'.format(self.oauth_token) 22 23 def use_json(self, request): 24 if request.method.upper() not in http.URLENCODE_METHODS: 25 request.params = json.dumps(request.params) 26 27 def get_url(self): 28 return self.apiroot 29 30 @base.resource(repos.Repo) 31 def repo(self, user, repo): 32 return repos.Repo(self, user, repo) filters definition child resource
1 from libsaas import http 2 from libsaas.services import base
3 from . import resource, repocommits 4 5 class Repo(resource.GitHubResource): 6 7 def __init__(self, parent, user, repo): 8 self.parent = parent 9 self.user = http.quote_any(user) 10 self.repo = http.quote_any(repo) 11 12 def get_url(self): 13 return '{0}/repos/{1}/{2}'.format(self.parent.get_url(), 14 self.user, self.repo) 15 16 def require_collection(self): 17 return False 18 19 def require_item(self): 20 return True 21 22 @base.resource(repocommits.RepoCommits) 23 def commits(self): 24 return repocommits.RepoCommits(self) child resource resource URL
1 from libsaas import http, parsers 2 from libsaas.services import
base 3 4 class GitHubResource(base.RESTResource): 5 6 @base.apimethod 7 def get(self, page=None, per_page=None): 8 params = base.get_params(('page', 'per_page'), locals()) 9 request = http.Request('GET', self.get_url(), params) 10 11 return request, parsers.parse_json 12 13 @base.apimethod 14 def update(self, obj): 15 self.require_item() 16 # GitHub uses PATCH for updates 17 request = http.Request('PATCH', self.get_url(), self.wrap_object(obj)) 18 19 return request, parsers.parse_json parse response as JSON
1 from __future__ import print_function 2 from libsaas.services import github
3 4 gh = github.GitHub('my_token') 5 6 repo = gh.repo('aitorciki', 'apidays-demo') 7 8 for commit in repo.commits().get(): 9 msg = commit['commit']['message'] 10 author = commit['commit']['author']['name'] 11 date = commit['commit']['author']['date'] 12 13 print('{0} by {1} on {2}'.format(msg, author, date)) resources tree Python dict HTTP method
Questions? Thanks! Aitor Guevara • @aitorciki http://libsaas.net/