/usr/lib/python3/dist-packages/restless/preparers.py is in python3-restless 2.0.1-6.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | class Preparer(object):
"""
A plain preparation object which just passes through data.
It also is relevant as the protocol subclasses should implement to work with
Restless.
"""
def __init__(self):
super(Preparer, self).__init__()
def prepare(self, data):
"""
Handles actually transforming the data.
By default, this does nothing & simply returns the data passed to it.
"""
return data
class FieldsPreparer(Preparer):
"""
A more complex preparation object, this will return a given set of fields.
This takes a ``fields`` parameter, which should be a dictionary of
keys (fieldnames to expose to the user) & values (a dotted lookup path to
the desired attribute/key on the object).
Example::
preparer = FieldsPreparer(fields={
# ``user`` is the key the client will see.
# ``author.pk`` is the dotted path lookup ``FieldsPreparer``
# will traverse on the data to return a value.
'user': 'author.pk',
})
"""
def __init__(self, fields):
super(FieldsPreparer, self).__init__()
self.fields = fields
def prepare(self, data):
"""
Handles transforming the provided data into the fielded data that should
be exposed to the end user.
Uses the ``lookup_data`` method to traverse dotted paths.
Returns a dictionary of data as the response.
"""
result = {}
if not self.fields:
# No fields specified. Serialize everything.
return data
for fieldname, lookup in self.fields.items():
result[fieldname] = self.lookup_data(lookup, data)
return result
def lookup_data(self, lookup, data):
"""
Given a lookup string, attempts to descend through nested data looking for
the value.
Can work with either dictionary-alikes or objects (or any combination of
those).
Lookups should be a string. If it is a dotted path, it will be split on
``.`` & it will traverse through to find the final value. If not, it will
simply attempt to find either a key or attribute of that name & return it.
Example::
>>> data = {
... 'type': 'message',
... 'greeting': {
... 'en': 'hello',
... 'fr': 'bonjour',
... 'es': 'hola',
... },
... 'person': Person(
... name='daniel'
... )
... }
>>> lookup_data('type', data)
'message'
>>> lookup_data('greeting.en', data)
'hello'
>>> lookup_data('person.name', data)
'daniel'
"""
value = data
parts = lookup.split('.')
if not parts or not parts[0]:
return value
part = parts[0]
remaining_lookup = '.'.join(parts[1:])
if hasattr(data, 'keys') and hasattr(data, '__getitem__'):
# Dictionary enough for us.
value = data[part]
else:
# Assume it's an object.
value = getattr(data, part)
if not remaining_lookup:
return value
# There's more to lookup, so dive in recursively.
return self.lookup_data(remaining_lookup, value)
|