beanbag.v2 – REST API access¶
A quick example:
>>> from beanbag.v2 import BeanBag, GET
>>> gh = BeanBag("https://api.github.com/")
>>> watchers = GET(gh.repos.ajtowns.beanbag.watchers)
>>> for w in watchers:
... print(w.login)
Setup:
>>> import beanbag.v2 as beanbag
>>> from beanbag.v2 import GET, POST, PUT, PATCH, DELETE
>>> myapi = beanbag.BeanBag("http://hostname/api/")
To constuct URLs, you can use attribute-style access or dict-style access:
>>> print(myapi.foo)
http://hostname/api/foo
>>> print(myapi["bar"])
http://hostname/api/bar
You can chain paths as well:
>>> print(myapi.foo.bar["baz"][3].xyzzy)
http://hostname/api/foo/bar/baz/3/xyzzy
To do a request on a resource that requires a trailing slash:
>>> print(myapi.foo._)
http://hostname/api/foo/
>>> print(myapi.foo[""])
http://hostname/api/foo/
>>> print(myapi.foo["/"])
http://hostname/api/foo/
>>> print(myapi["foo/"])
http://hostname/api/foo/
>>> print(myapi.foo._.x == myapi.foo.x)
True
>>> print(myapi.foo["_"])
http://hostname/api/foo/_
You can add URL parameters using function calls:
>>> print(myapi.foo(a=1, b="foo"))
http://hostname/api/foo?a=1;b=foo
Finally, to actually do REST queries on these queries you can use the GET, POST, PUT, PATCH and DELETE functions. The first argument should be a BeanBag url, and the second argument (if provided) should be the request body, which will be json encoded before being sent. The return value is the request’s response (decoded from json).
>>> res = GET( foo.resource )
>>> res = POST( foo.resource, {"a": 12} )
>>> DELETE( foo.resource )
To access REST interfaces that require authentication, you need to specify a session object when instantiating the BeanBag initially. BeanBag supplies helpers to make Kerberos and OAuth 1.0a authentication easier.
BeanBag class¶
The BeanBag class does all the magic described above, using beanbag.namespace.
- class beanbag.v2.BeanBag(base_url, ext='', session=None, use_attrdict=True)¶
- __init__(base_url, ext='', session=None, use_attrdict=True)¶
Create a BeanBag referencing a base REST path.
Parameters: - base_url – the base URL prefix for all resources
- ext – extension to add to resource URLs, eg ”.json”
- session – requests.Session instance used for this API. Useful to set an auth procedure, or change verify parameter.
- use_attrdict – if true, decode() will wrap dicts and lists in a beanbag.attrdict.AttrDict for syntactic sugar.
- __call__(*args, **kwargs)¶
Set URL parameters
- __eq__(other)¶
self == other
- __getattr__(attr)¶
self.attr
- __getitem__(item)¶
self[attr]
- __invert__()¶
Provide access to the base/path via the namespace object
bb = BeanBag(...) base, path = ~bb.foo assert isinstance(base, BeanBagBase)
This is the little bit of glue needed so that it’s possible to call methods defined in BeanBagBase directly rather than just the operators BeanBag supports.
- __ne__(other)¶
self != other
- __repr__()¶
Human readable representation of object
- __str__()¶
Obtain the URL of a resource
This class can be subclassed. In particular, if you need to use something other than JSON for requests or responses, subclassing BeanBagBase and overriding the encode and decode methods is probably what you want to do. One caveat: due to the way beanbag.namespace works, if you wish to invoke the parent classes method, you’ll usually need the parent base class, accessed via ~BeanBag or super(~SubClass, self).
HTTP Verbs¶
Functions are provided for the standard set of HTTP verbs.
- beanbag.v2.GET(url, body=None)¶
GET verb function
- beanbag.v2.HEAD(url, body=None)¶
HEAD verb function
- beanbag.v2.POST(url, body=None)¶
POST verb function
- beanbag.v2.PUT(url, body=None)¶
PUT verb function
- beanbag.v2.PATCH(url, body=None)¶
PATCH verb function
- beanbag.v2.DELETE(url, body=None)¶
DELETE verb function
The verb function is used to create BeanBag compatible verbs. It is used as:
GET = verb("GET")
- beanbag.v2.verb(verbname)¶
Construct a BeanBag compatible verb function
Parameters: verbname – verb to use (GET, POST, etc)
Request¶
The Request class serves as a place holder for arguments to requests.Session.request. Normally this is constructed from a dict object passed to POST or PUT via json.dumps() however a Request object can also be created by hand and passed in as the body parameter in a POST or similar BeanBag request. For example to make a POST request with a body that isn’t valid JSON:
POST(bbexample.path.to.resource, Request(body="MAGIC STRING"))
This can be useful with GET requests as well, even though GET requests don’t have a body per se:
GET(bbexample.path.to.resource, Request(headers={"X-Magic": "String"}))
- class beanbag.v2.Request(**kwargs)¶
Bases: beanbag.attrdict.AttrDict
- __init__(**kwargs)¶
Create a Request object
Request objects act as placeholders for the arguments to the requests() function of the requests.Session being used. They are used as the interface between the encode() and make_request() functions, and may also be used by the API caller.
NB: A Request object is only suitable for one use, as it may be modified in-place during the request. For this reason, __init__ makes a (shallow) copy of all the keyword arguments supplied rather than using them directly.
BeanBagException¶
- exception beanbag.v2.BeanBagException(response, msg)¶
Exception thrown when a BeanBag request fails.
- Data members:
- msg – exception string, brief and human readable
- response – response object
You can get the original request via bbe.response.request.
- __init__(response, msg)¶
Create a BeanBagException