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()
, andnode()
.>>> 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__()
orget()
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__()
andget()
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: - name (str) – Name of the child resource.
- class (Resource) – Child resource class.
- complies (Condition) – Condition of the route.
See examples of
traversalkit.condition.Under
andtraversalkit.condition.Recursion
for details.
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: - pattern (regex) – Regular expression to match child name.
- class (Resource) – Child resource class.
- metaname (str) – Name of the route. It is used by
node()
. - complies (Condition) – Condition of the route.
See examples of
traversalkit.condition.Under
andtraversalkit.condition.Recursion
for details.
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()
ornode()
. If resource is created by__getitem__()
, the parameter will beNone
.
-
__getitem__
(name)¶ Returns child resource by its name.
Child resource class should be mounted using
mount()
ormount_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()
ormount_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: 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 ofmount()
ormetaname
parameter ofmount_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: >>> 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/>
-