Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Libsaas: one API to rule them all
Search
Aitor Guevara
May 29, 2014
Technology
210
0
Share
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
1k
From pull to push: towards a real-time web
aitorciki
4
340
Ducksboard's architecture, a real-time online dashboard
aitorciki
12
2.7k
Ducksboard - Betabeers BCN
aitorciki
1
200
Other Decks in Technology
See All in Technology
多角的な視点から見たAGI
terisuke
0
120
Building a Study Buddy AI Agent from Scratch: From Passive Chatbots to Autonomous Systems
itchimonji
0
140
AI対話分析の夢と、汚いデータの現実 Looker / Dataplex / Dataform で実現する品質ファーストな基盤設計
waiwai2111
0
170
会社説明資料|株式会社ギークプラス ソフトウェア事業部
geekplus_tech
0
200
アクセシビリティはすべての人のもの
tomokusaba
0
290
サービスの信頼性を高めるため、形骸化した「プロダクションミーティング」を立て直すまでの取り組み
stefafafan
1
250
Sociotechnical Architecture Reviews: Understanding Teams, not just Artefacts
ewolff
1
140
Agent の「自由」と「安全」〜未来に向けて今できること〜
katayan
0
340
ハーネスエンジニアリング入門
knishioka
0
130
AIが自律的に働く時代へ Amazon Quick で実現するAIエージェント紹介
koheiyoshikawa
0
190
ハーネスエンジニアリング入門
hatyibei
0
110
Modernizing Your HCL Connections Experience: Visual Report to chain, Profile Enhancements, and AI Integration
wannesrams
0
290
Featured
See All Featured
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
400
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.4k
A designer walks into a library…
pauljervisheath
211
24k
Discover your Explorer Soul
emna__ayadi
2
1.1k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
160
Google's AI Overviews - The New Search
badams
0
1k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
540
Code Reviewing Like a Champion
maltzj
528
40k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
1.9k
How to build a perfect <img>
jonoalderson
1
5.5k
Art, The Web, and Tiny UX
lynnandtonic
304
21k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.2k
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/