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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Aitor Guevara
May 29, 2014
Technology
0
200
Libsaas: one API to rule them all
APIdays Mediterranea May 2014, Barcelona
Aitor Guevara
May 29, 2014
Tweet
Share
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
Data Hubグループ 紹介資料
sansan33
PRO
0
2.7k
レガシー共有バッチ基盤への挑戦 - SREドリブンなリアーキテクチャリングの取り組み
tatsukoni
0
220
SRE Enabling戦記 - 急成長する組織にSREを浸透させる戦いの歴史
markie1009
0
130
茨城の思い出を振り返る ~CDKのセキュリティを添えて~ / 20260201 Mitsutoshi Matsuo
shift_evolve
PRO
1
330
今日から始めるAmazon Bedrock AgentCore
har1101
4
410
Sansan Engineering Unit 紹介資料
sansan33
PRO
1
3.9k
仕様書駆動AI開発の実践: Issue→Skill→PRテンプレで 再現性を作る
knishioka
2
670
登壇駆動学習のすすめ — CfPのネタの見つけ方と書くときに意識していること
bicstone
3
120
20260204_Midosuji_Tech
takuyay0ne
1
160
ランサムウェア対策としてのpnpm導入のススメ
ishikawa_satoru
0
180
Oracle Cloud Observability and Management Platform - OCI 運用監視サービス概要 -
oracle4engineer
PRO
2
14k
Context Engineeringの取り組み
nutslove
0
360
Featured
See All Featured
WCS-LA-2024
lcolladotor
0
450
Art, The Web, and Tiny UX
lynnandtonic
304
21k
It's Worth the Effort
3n
188
29k
Making the Leap to Tech Lead
cromwellryan
135
9.7k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
0
150
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
0
2.3k
HDC tutorial
michielstock
1
380
Between Models and Reality
mayunak
1
190
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
180
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
67
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/