def deep_map_values(obj, callback=None, property_path=NoValue): """Map all non-object values in `obj` with return values from `callback`. The callback is invoked with two arguments: ``(obj_value, property_path)`` where ``property_path`` contains the list of path keys corresponding to the path of ``obj_value``. Args: obj (list|dict): Object to map. callback (callable): Callback applied to each value. Returns: mixed: The modified object. Warning: `obj` is modified in place. Example: >>> x = {'a': 1, 'b': {'c': 2}} >>> y = deep_map_values(x, lambda val: val * 2) >>> y == {'a': 2, 'b': {'c': 4}} True >>> z = deep_map_values(x, lambda val, props: props) >>> z == {'a': ['a'], 'b': {'c': ['b', 'c']}} True .. versionadded: 2.2.0 .. versionchanged:: 3.0.0 Allow callbacks to accept partial arguments. """ properties = path_keys(property_path) if pyd.is_object(obj): deep_callback = ( lambda value, key: deep_map_values(value, callback, pyd.flatten([properties, key]))) return pyd.extend(obj, map_values(obj, deep_callback)) else: return call_callback(callback, obj, properties)
def deep_map_values(obj, callback=None, property_path=NoValue): """Map all non-object values in `obj` with return values from `callback`. The callback is invoked with two arguments: ``(obj_value, property_path)`` where ``property_path`` contains the list of path keys corresponding to the path of ``obj_value``. Args: obj (list|dict): Object to map. callback (function): Callback applied to each value. Returns: mixed: The modified object. Warning: `obj` is modified in place. Example: >>> x = {'a': 1, 'b': {'c': 2}} >>> y = deep_map_values(x, lambda val: val * 2) >>> y == {'a': 2, 'b': {'c': 4}} True >>> z = deep_map_values(x, lambda val, props: props) >>> z == {'a': ['a'], 'b': {'c': ['b', 'c']}} True .. versionadded: 2.2.0 .. versionchanged:: 3.0.0 Allow callbacks to accept partial arguments. """ properties = path_keys(property_path) if pyd.is_object(obj): deep_callback = ( lambda value, key: deep_map_values(value, callback, pyd.flatten([properties, key]))) return pyd.extend(obj, map_values(obj, deep_callback)) else: return callit(callback, obj, properties)
def make_response(items, next_cursor, more, total, extra=None): """Creates reponse with list of items and also meta data useful for pagination Args: reponse_list (list): list of items to be in helpers cursor (Cursor, optional): ndb query cursor more (bool, optional): whether there's more items in terms of pagination total_count (int, optional): Total number of items Returns: dict: helpers to be serialized and sent to client """ return { 'list': items, 'meta': _.extend( { 'next_cursor': next_cursor.urlsafe() if next_cursor else '', 'more': more, 'total_count': total }, (extra or {})) }