From 9066ed49dbdb47b2245507eb2c25acd97984be54 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Thu, 1 Sep 2022 19:27:59 -0400 Subject: [PATCH 1/3] chore(python): update .kokoro/requirements.txt (#431) Source-Link: https://github.com/googleapis/synthtool/commit/703554a14c7479542335b62fa69279f93a9e38ec Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-python:latest@sha256:94961fdc5c9ca6d13530a6a414a49d2f607203168215d074cdb0a1df9ec31c0b Co-authored-by: Owl Bot --- .github/.OwlBot.lock.yaml | 2 +- .kokoro/requirements.txt | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 0d9eb2af..2fa0f7c4 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -13,4 +13,4 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:1f0dbd02745fb7cf255563dab5968345989308544e52b7f460deadd5e78e63b0 + digest: sha256:94961fdc5c9ca6d13530a6a414a49d2f607203168215d074cdb0a1df9ec31c0b diff --git a/.kokoro/requirements.txt b/.kokoro/requirements.txt index 92b2f727..385f2d4d 100644 --- a/.kokoro/requirements.txt +++ b/.kokoro/requirements.txt @@ -241,6 +241,10 @@ importlib-metadata==4.12.0 \ # via # -r requirements.in # twine +jaraco-classes==3.2.2 \ + --hash=sha256:6745f113b0b588239ceb49532aa09c3ebb947433ce311ef2f8e3ad64ebb74594 \ + --hash=sha256:e6ef6fd3fcf4579a7a019d87d1e56a883f4e4c35cfe925f86731abc58804e647 + # via keyring jeepney==0.8.0 \ --hash=sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806 \ --hash=sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755 @@ -299,6 +303,10 @@ markupsafe==2.1.1 \ --hash=sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a \ --hash=sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7 # via jinja2 +more-itertools==8.14.0 \ + --hash=sha256:1bc4f91ee5b1b31ac7ceacc17c09befe6a40a503907baf9c839c229b5095cfd2 \ + --hash=sha256:c09443cd3d5438b8dafccd867a6bc1cb0894389e90cb53d227456b0b0bccb750 + # via jaraco-classes nox==2022.8.7 \ --hash=sha256:1b894940551dc5c389f9271d197ca5d655d40bdc6ccf93ed6880e4042760a34b \ --hash=sha256:96cca88779e08282a699d672258ec01eb7c792d35bbbf538c723172bce23212c From 83678e94e1081f9087b19c43f26fad4774184d66 Mon Sep 17 00:00:00 2001 From: Victor Chudnovsky Date: Thu, 1 Sep 2022 17:27:04 -0700 Subject: [PATCH 2/3] feat: add 'strict' to flatten_query_params to lower-case bools (#433) * feat: add 'strict' to flatten_query_params to lower-case bools * pylint Co-authored-by: Anthonios Partheniou --- google/api_core/rest_helpers.py | 49 +++++++++++++++++++++------------ tests/unit/test_rest_helpers.py | 19 ++++++++++++- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/google/api_core/rest_helpers.py b/google/api_core/rest_helpers.py index 23fb614f..a78822f1 100644 --- a/google/api_core/rest_helpers.py +++ b/google/api_core/rest_helpers.py @@ -18,8 +18,8 @@ import operator -def flatten_query_params(obj): - """Flatten a nested dict into a list of (name,value) tuples. +def flatten_query_params(obj, strict=False): + """Flatten a dict into a list of (name,value) tuples. The result is suitable for setting query params on an http request. @@ -28,9 +28,10 @@ def flatten_query_params(obj): >>> obj = {'a': ... {'b': ... {'c': ['x', 'y', 'z']} }, - ... 'd': 'uvw', } - >>> flatten_query_params(obj) - [('a.b.c', 'x'), ('a.b.c', 'y'), ('a.b.c', 'z'), ('d', 'uvw')] + ... 'd': 'uvw', + ... 'e': True, } + >>> flatten_query_params(obj, strict=True) + [('a.b.c', 'x'), ('a.b.c', 'y'), ('a.b.c', 'z'), ('d', 'uvw'), ('e', 'true')] Note that, as described in https://github.com/googleapis/googleapis/blob/48d9fb8c8e287c472af500221c6450ecd45d7d39/google/api/http.proto#L117, @@ -38,7 +39,9 @@ def flatten_query_params(obj): This is enforced in this function. Args: - obj: a nested dictionary (from json), or None + obj: a possibly nested dictionary (from json), or None + strict: a bool, defaulting to False, to enforce that all values in the + result tuples be strings and, if boolean, lower-cased. Returns: a list of tuples, with each tuple having a (possibly) multi-part name and a scalar value. @@ -51,17 +54,17 @@ def flatten_query_params(obj): if obj is not None and not isinstance(obj, dict): raise TypeError("flatten_query_params must be called with dict object") - return _flatten(obj, key_path=[]) + return _flatten(obj, key_path=[], strict=strict) -def _flatten(obj, key_path): +def _flatten(obj, key_path, strict=False): if obj is None: return [] if isinstance(obj, dict): - return _flatten_dict(obj, key_path=key_path) + return _flatten_dict(obj, key_path=key_path, strict=strict) if isinstance(obj, list): - return _flatten_list(obj, key_path=key_path) - return _flatten_value(obj, key_path=key_path) + return _flatten_list(obj, key_path=key_path, strict=strict) + return _flatten_value(obj, key_path=key_path, strict=strict) def _is_primitive_value(obj): @@ -74,21 +77,33 @@ def _is_primitive_value(obj): return True -def _flatten_value(obj, key_path): - return [(".".join(key_path), obj)] +def _flatten_value(obj, key_path, strict=False): + return [(".".join(key_path), _canonicalize(obj, strict=strict))] -def _flatten_dict(obj, key_path): - items = (_flatten(value, key_path=key_path + [key]) for key, value in obj.items()) +def _flatten_dict(obj, key_path, strict=False): + items = ( + _flatten(value, key_path=key_path + [key], strict=strict) + for key, value in obj.items() + ) return functools.reduce(operator.concat, items, []) -def _flatten_list(elems, key_path): +def _flatten_list(elems, key_path, strict=False): # Only lists of scalar values are supported. # The name (key_path) is repeated for each value. items = ( - _flatten_value(elem, key_path=key_path) + _flatten_value(elem, key_path=key_path, strict=strict) for elem in elems if _is_primitive_value(elem) ) return functools.reduce(operator.concat, items, []) + + +def _canonicalize(obj, strict=False): + if strict: + value = str(obj) + if isinstance(obj, bool): + value = value.lower() + return value + return obj diff --git a/tests/unit/test_rest_helpers.py b/tests/unit/test_rest_helpers.py index 5932fa55..ff1a43f0 100644 --- a/tests/unit/test_rest_helpers.py +++ b/tests/unit/test_rest_helpers.py @@ -36,9 +36,26 @@ def test_flatten_empty_dict(): def test_flatten_simple_dict(): - assert rest_helpers.flatten_query_params({"a": "abc", "b": "def"}) == [ + obj = {"a": "abc", "b": "def", "c": True, "d": False, "e": 10, "f": -3.76} + assert rest_helpers.flatten_query_params(obj) == [ ("a", "abc"), ("b", "def"), + ("c", True), + ("d", False), + ("e", 10), + ("f", -3.76), + ] + + +def test_flatten_simple_dict_strict(): + obj = {"a": "abc", "b": "def", "c": True, "d": False, "e": 10, "f": -3.76} + assert rest_helpers.flatten_query_params(obj, strict=True) == [ + ("a", "abc"), + ("b", "def"), + ("c", "true"), + ("d", "false"), + ("e", "10"), + ("f", "-3.76"), ] From cea67dafecc71481b0c362763da354a541966c79 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 1 Sep 2022 17:43:34 -0700 Subject: [PATCH 3/3] chore(main): release 2.10.0 (#434) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ google/api_core/version.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90826869..268cb4d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-api-core/#history +## [2.10.0](https://github.com/googleapis/python-api-core/compare/v2.9.0...v2.10.0) (2022-09-02) + + +### Features + +* Add 'strict' to flatten_query_params to lower-case bools ([#433](https://github.com/googleapis/python-api-core/issues/433)) ([83678e9](https://github.com/googleapis/python-api-core/commit/83678e94e1081f9087b19c43f26fad4774184d66)) + ## [2.9.0](https://github.com/googleapis/python-api-core/compare/v2.8.2...v2.9.0) (2022-09-01) diff --git a/google/api_core/version.py b/google/api_core/version.py index b2a8c553..13e710fc 100644 --- a/google/api_core/version.py +++ b/google/api_core/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.9.0" +__version__ = "2.10.0"