traversalkit.resource

Resource

class traversalkit.resource.Resource(name='', parent=None, payload=None, node=None)

Base class of resource.

__nodeclass__

Class of route nodes. Links to traversalkit.route.Node.

__routeclass__

Class of route. Links to traversalkit.route.Route.

__cacheclass__

Class of cache. Links to traversalkit.cache.Cache.

__not_exist__

Exception class or list of ones, that should be treated as a signal that resource does not exist.

These exceptions will be replaced by KeyError within methods __getitem__(), get(), and node().

>>> import re
>>> from traversalkit import Resource

>>> class Files(Resource):
...     ''' Files collection '''

>>> @Files.mount_set(re.compile(r'^[\w\d\.\_]+$'),
...                  metaname='filename')
... class File(Resource):
...     ''' File resource '''
...     __not_exist__ = IOError
...     #               ^^^^^^^
...     def on_init(self, payload):
...         with open(self.__name__) as f:
...             self.content = f.read()

>>> files = Files()
>>> files['nonexistent_file.txt']  # DOCTEST: +ellipsis
Traceback (most recent call last):
...
KeyError: ('nonexistent_file.txt', '/')
__name__

Resource name, which has been passed to parent’s __getitem__() or get() method.

__parent__

Link to a parent resource. It is actually a property, which stores weak reference to the parent.

__cache__

Cache of child resources. It is used by __getitem__() and get() methods. Instance of __cacheclass__.

__node__

Route node, which has been used to create this resource. Instance of __nodeclass__.

__route__

Route, which has been used to create this resource. Instance of __routeclass__.

uri

URI of the resource.

classmethod mount(name, class_=None, complies=None, **kw)

Mounts single named child resource.

Parameters:
Returns:

Unmodified class_.

The method can be used as a decorator.

>>> from traversalkit import Resource

>>> class Root(Resource):
...     ''' Site root '''

>>> @Root.mount('users')
... class Users(Resource):
...     ''' Collection of users '''

>>> root = Root()
>>> root['users']
<Users: /users/>
classmethod mount_set(pattern, class_=None, metaname=None, complies=None, **kw)

Mounts set of child resources.

Parameters:
Returns:

Unmodified class_.

The method can be used as a decorator.

>>> from traversalkit import Resource, DEC_ID

>>> class Users(Resource):
...     ''' Collection of users '''

>>> @Users.mount_set(DEC_ID, metaname='user_id')
... class User(Resource):
...     ''' User resource '''

>>> users = Users()
>>> users['1']
<User: /1/>
>>> users['john']  # DOCTEST: +ellipsis
Traceback (most recent call last):
...
KeyError: ('john', '/')
classmethod routes()

Iterates over all routes available at the current resource.

The method is useful for resource tree introspection and documentation.

Returns:Iterator over available routes, see traversalkit.route.Route.
>>> from traversalkit import Resource, DEC_ID

>>> class Root(Resource):
...     ''' Site root '''

>>> @Root.mount('users')
... class Users(Resource):
...     ''' Collection of users '''

>>> @Users.mount_set(DEC_ID, metaname='user_id')
... class User(Resource):
...     ''' User resource '''

>>> for route in Root.routes():
...     print(route)
<Route: />
<Route: /users/>
<Route: /users/{user_id}/>
on_init(payload)

Initialization callback.

Derived classes should override this method instead of __init__().

Parameters:payload – Some additional data, that can be passed into initialization routine through get() or node(). If resource is created by __getitem__(), the parameter will be None.
__getitem__(name)

Returns child resource by its name.

Child resource class should be mounted using mount() or mount_set() methods.

The method uses cache. Therefore it won’t create child resource, if it’s already created.

Parameters:name (str) – Resource name.
Returns:Child resource.
Return type:Resource
Raises:KeyError – If name does not match any route, or current route does not comply condition.
>>> from traversalkit import Resource, DEC_ID

>>> class Root(Resource):
...     ''' Site root '''

>>> @Root.mount('users')
... class Users(Resource):
...     ''' Collection of users '''

>>> @Users.mount_set(DEC_ID, metaname='user_id')
... class User(Resource):
...     ''' User resource '''

>>> root = Root()
>>> root['users']
<Users: /users/>
>>> root['users']['1']
<User: /users/1/>
get(name, payload=None)

Returns child resource by its name.

Child resource class should be mounted using mount() or mount_set() methods.

The method uses cache. Therefore it won’t create child resource, if it’s already created.

Parameters:
  • name (str) – Resource name.
  • payload – Optional resource payload.
Returns:

Child resource.

Return type:

Resource

Raises:

KeyError – If name does not match any route, or current route does not comply condition.

>>> from traversalkit import Resource, DEC_ID

>>> class Root(Resource):
...     ''' Site root '''

>>> @Root.mount('users')
... class Users(Resource):
...     ''' Collection of users '''

>>> @Users.mount_set(DEC_ID, metaname='user_id')
... class User(Resource):
...     ''' User resource '''
...     def on_init(self, payload):
...         if payload is not None:
...             self.id = payload['id']
...             self.name = payload['name']

>>> root = Root()
>>> root['users']
<Users: /users/>
>>> user = root['users'].get('1', {'id': 1, 'name': 'John'})
>>> user
<User: /users/1/>
>>> user.name
'John'
>>> user.id
1
node(name)

Returns context manager of named route node.

Parameters:name (string) – Name of the route node, i.e. name parameter of mount() or metaname parameter of mount_set().
Raises:KeyError – If node does not exist or current route does not comply condition.

The context manager can be used to create multiple child resources, passing route validation only once. It has the following signature:

def create_child(name, payload=None):
Parameters:
  • name (string) – Name of the resource.
  • payload – Optional resource payload.
Returns:

Child resource.

Return type:

Resource

>>> from traversalkit import Resource, DEC_ID

>>> class Users(Resource):
...     ''' Collection of users '''
...     def index(self):
...         # Let's imagine these data come from DB
...         # and there is a lot of records.
...         users = [{'id': 1, 'name': 'Jonh'},
...                  {'id': 2, 'name': 'Jane'}]
...         with self.node('user_id') as create_child:
...         #    ^^^^^^^^^^^^^^^^^^^^
...         #    here we pass route validation
...             for user in users:
...                 yield create_child(str(user['id']), user)
...                 #     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...                 #     and here create multiple resources

>>> @Users.mount_set(DEC_ID, metaname='user_id')
... class User(Resource):
...     ''' User resource '''
...     def on_init(self, payload):
...         if payload is not None:
...             self.id = payload['id']
...             self.name = payload['name']

>>> users = Users()
>>> john, jane = users.index()
>>> john.name
'Jonh'
>>> jane.name
'Jane'
>>> users['1'] is john
True
>>> users['2'] is jane
True
lineage()

Returns iterator over resource parents.

Lineage chain includes current resource.

>>> from traversalkit import Resource, DEC_ID

>>> class Root(Resource):
...     ''' Site root '''

>>> @Root.mount('users')
... class Users(Resource):
...     ''' Collection of users '''

>>> @Users.mount_set(DEC_ID, metaname='user_id')
... class User(Resource):
...     ''' User resource '''

>>> root = Root()
>>> list(root['users']['1'].lineage())
[<User: /users/1/>, <Users: /users/>, <Root: />]
parent(name=None, cls=None)

Searches particular parent in the resource lineage.

Parameters:
  • name (str) – Optional parent name.
  • cls (Resource,str) – Optional class or class name of parent.
Returns:

Parent resource or None.

>>> from traversalkit import Resource, DEC_ID

>>> class Root(Resource):
...     ''' Site root '''

>>> @Root.mount('users')
... class Users(Resource):
...     ''' Collection of users '''

>>> @Users.mount_set(DEC_ID, metaname='user_id')
... class User(Resource):
...     ''' User resource '''

>>> root = Root()
>>> user = root['users']['1']
>>> user.parent('users')
<Users: /users/>
>>> user.parent(cls='Root')
<Root: />
>>> user.parent(cls=Root)
<Root: />
>>> user.parent()
<Users: /users/>
child(class_, name, payload=None)

Warning

Deprecated in favor of node().

Creates child resource from given class and name.

ResourceMeta

class traversalkit.resource.ResourceMeta(class_name, bases, attrs)

Resource metaclass