patternpythonMinor
A generic REST API consuming Python library
Viewed 0 times
genericrestconsumingpythonlibraryapi
Problem
I wrote this, which essentially acts as a single library for all possible REST services.
Here is the main file, as of alpha version 1:
The rationale and usage is all explained in the README.
Please critique the library, the idea, implem
Here is the main file, as of alpha version 1:
import requests, json
class RestConsumer(object):
def __init__(self,base_url,append_json=False,**kwargs):
self.base_url = base_url
self.uriparts = []
self.append_json = append_json
self.kwargs = kwargs
def __getattr__(self,k):
if k=='spc':
return self.spc
if not k[0] == '_':
self.uriparts.append(k)
else:
if k[1:3]=='in':
self.uriparts.append(k[3:])
elif k[1:3] == 'uh':
self.uriparts.append(k.replace('_','-'))
return self
def spc(self,k):
self.uriparts.append(k)
return self
def __call__(self, **kwargs):
uri_constructed = '/'.join(self.uriparts)
self.uriparts = []
self.uri_constructed = "%s%s"%(uri_constructed,'.json') if self.append_json else uri_constructed
self.url = '/'.join([self.base_url,self.uri_constructed])
return self.get(self.url,**kwargs)
def get(self,url,**kwargs):
print url
r = requests.get(url,**kwargs)
return json.loads(r.content)
def post(self,**kwargs):
r = requests.post(**kwargs)
return json.loads(r.content)
if __name__=='__main__':
from pprint import pprint
t = RestConsumer(base_url='https://api.twitter.com/1',append_json=True)
public_timeline = t.statuses.public_timeline()
pprint(public_timeline)
g = RestConsumer(base_url='https://api.github.com')
repos = g.users.kennethreitz.repos()
pprint(repos)
s = RestConsumer(base_url='http://api.stackoverflow.com/1.1')
sr = s.users.spc('55562').questions.unanswered()
pprint(sr)
sr2 = s.tags.python.spc('top-answerers').spc('all-time')()
pprint(sr2)The rationale and usage is all explained in the README.
Please critique the library, the idea, implem
Solution
import requests, json
class RestConsumer(object):
def __init__(self,base_url,append_json=False,**kwargs):
self.base_url = base_url
self.uriparts = []
self.append_json = append_json
self.kwargs = kwargsSince you treat attributes "special", I recommend putting _ in front of these attributes so that are clearly offset.
def __getattr__(self,k):I recommend not using the random letter
k for the name.if k=='spc':
return self.spc__getattr__ only gets invoked if the attribute cannot be found. Since spc will be found this won't ever get used.if not k[0] == '_':
self.uriparts.append(k)
else:
if k[1:3]=='in':
self.uriparts.append(k[3:])What's the point of this rule?
_infoo means foo? elif k[1:3] == 'uh':
self.uriparts.append(k.replace('_','-'))uh?return selfI don't like the way you've implemented this. Accessing attributes modifying the object's state is deeply counter-intuitive.
def spc(self,k):
self.uriparts.append(k)
return selfspc is not a clear name. Its hard to guess what it means. def __call__(self, **kwargs):
uri_constructed = '/'.join(self.uriparts)
self.uriparts = []
self.uri_constructed = "%s%s"%(uri_constructed,'.json') if self.append_json else uri_constructed
self.url = '/'.join([self.base_url,self.uri_constructed])
return self.get(self.url,**kwargs)
def get(self,url,**kwargs):
print url
r = requests.get(url,**kwargs)
return json.loads(r.content)
def post(self,**kwargs):
r = requests.post(**kwargs)
return json.loads(r.content)get prints while post doesn't. Probably neither should be printing, a log facility might be useful.The way you've designed this, some useful things won't work:
public_timeline = twitter.statuses.public_timeline
while True:
print public_timeline()or
user = s.users.spc(55562)
print user.questions.unanswered()
print user.questions.answered()I suggest that instead of modifying the object, you return new objects. That way it will work in an intuitive manner.
Instead of
spc I suggest that you provide a __getitem__. That way you can do:s.users[55562].questions.unanswered()Which I think will make it cleaner.
Code Snippets
import requests, json
class RestConsumer(object):
def __init__(self,base_url,append_json=False,**kwargs):
self.base_url = base_url
self.uriparts = []
self.append_json = append_json
self.kwargs = kwargsdef __getattr__(self,k):if k=='spc':
return self.spcif not k[0] == '_':
self.uriparts.append(k)
else:
if k[1:3]=='in':
self.uriparts.append(k[3:])elif k[1:3] == 'uh':
self.uriparts.append(k.replace('_','-'))Context
StackExchange Code Review Q#8455, answer score: 4
Revisions (0)
No revisions yet.