Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
rest_helpers.py110 linesDownload Raw Back to api_core
1# Copyright 2021 Google LLC2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7#     http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14 15"""Helpers for rest transports."""16 17import functools18import operator19 20 21def flatten_query_params(obj, strict=False):22    """Flatten a dict into a list of (name,value) tuples.23 24    The result is suitable for setting query params on an http request.25 26    .. code-block:: python27 28        >>> obj = {'a':29        ...         {'b':30        ...           {'c': ['x', 'y', 'z']} },31        ...      'd': 'uvw',32        ...      'e': True, }33        >>> flatten_query_params(obj, strict=True)34        [('a.b.c', 'x'), ('a.b.c', 'y'), ('a.b.c', 'z'), ('d', 'uvw'), ('e', 'true')]35 36    Note that, as described in37    https://github.com/googleapis/googleapis/blob/48d9fb8c8e287c472af500221c6450ecd45d7d39/google/api/http.proto#L117,38    repeated fields (i.e. list-valued fields) may only contain primitive types (not lists or dicts).39    This is enforced in this function.40 41    Args:42      obj: a possibly nested dictionary (from json), or None43      strict: a bool, defaulting to False, to enforce that all values in the44              result tuples be strings and, if boolean, lower-cased.45 46    Returns: a list of tuples, with each tuple having a (possibly) multi-part name47      and a scalar value.48 49    Raises:50      TypeError if obj is not a dict or None51      ValueError if obj contains a list of non-primitive values.52    """53 54    if obj is not None and not isinstance(obj, dict):55        raise TypeError("flatten_query_params must be called with dict object")56 57    return _flatten(obj, key_path=[], strict=strict)58 59 60def _flatten(obj, key_path, strict=False):61    if obj is None:62        return []63    if isinstance(obj, dict):64        return _flatten_dict(obj, key_path=key_path, strict=strict)65    if isinstance(obj, list):66        return _flatten_list(obj, key_path=key_path, strict=strict)67    return _flatten_value(obj, key_path=key_path, strict=strict)68 69 70def _is_primitive_value(obj):71    if obj is None:72        return False73 74    if isinstance(obj, (list, dict)):75        raise ValueError("query params may not contain repeated dicts or lists")76 77    return True78 79 80def _flatten_value(obj, key_path, strict=False):81    return [(".".join(key_path), _canonicalize(obj, strict=strict))]82 83 84def _flatten_dict(obj, key_path, strict=False):85    items = (86        _flatten(value, key_path=key_path + [key], strict=strict)87        for key, value in obj.items()88    )89    return functools.reduce(operator.concat, items, [])90 91 92def _flatten_list(elems, key_path, strict=False):93    # Only lists of scalar values are supported.94    # The name (key_path) is repeated for each value.95    items = (96        _flatten_value(elem, key_path=key_path, strict=strict)97        for elem in elems98        if _is_primitive_value(elem)99    )100    return functools.reduce(operator.concat, items, [])101 102 103def _canonicalize(obj, strict=False):104    if strict:105        value = str(obj)106        if isinstance(obj, bool):107            value = value.lower()108        return value109    return obj110