From a7c01346d106048b0b3bf23fdc1e84c010848661 Mon Sep 17 00:00:00 2001 From: Thomas Anglaret Date: Sat, 3 Sep 2022 01:54:21 +0200 Subject: [PATCH 01/10] address-validation-api --- README.md | 4 ++ googlemaps/addressvalidation.py | 75 +++++++++++++++++++++++++++++++++ googlemaps/client.py | 2 + tests/test_addressvalidation.py | 48 +++++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 googlemaps/addressvalidation.py create mode 100644 tests/test_addressvalidation.py diff --git a/README.md b/README.md index 54c024b3..c5d8b18e 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ APIs: - Roads API - Places API - Maps Static API + - Address Validation API Keep in mind that the same [terms and conditions](https://developers.google.com/maps/terms) apply to usage of the APIs when they're accessed through this library. @@ -85,6 +86,9 @@ directions_result = gmaps.directions("Sydney Town Hall", "Parramatta, NSW", mode="transit", departure_time=now) + +# Validate an address with address validation +addressvalidation_result = gmaps.addressvalidation('1600 Amphitheatre Pk', regionCode='US',locality='Mountain View') ``` For more usage examples, check out [the tests](https://github.com/googlemaps/google-maps-services-python/tree/master/tests). diff --git a/googlemaps/addressvalidation.py b/googlemaps/addressvalidation.py new file mode 100644 index 00000000..07df4e71 --- /dev/null +++ b/googlemaps/addressvalidation.py @@ -0,0 +1,75 @@ +# +# Copyright 2022 Google Inc. All rights reserved. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# + +"""Performs requests to the Google Maps Address Validation API.""" +from googlemaps import exceptions + + +_ADDRESSVALIDATION_BASE_URL = "https://addressvalidation.googleapis.com" + + +def _addressvalidation_extract(response): + """ + Mimics the exception handling logic in ``client._get_body``, but + for addressvalidation which uses a different response format. + """ + body = response.json() + return body + + # if response.status_code in (200, 404): + # return body + + # try: + # error = body["error"]["errors"][0]["reason"] + # except KeyError: + # error = None + + # if response.status_code == 403: + # raise exceptions._OverQueryLimit(response.status_code, error) + # else: + # raise exceptions.ApiError(response.status_code, error) + + +def addressvalidation(client, addressLines, regionCode=None , locality=None): + """ + The Google Maps Address Validation API returns a verification of an address + See https://developers.google.com/maps/documentation/address-validation/overview + request must include parameters below. + :param addressLines: The address to validate + :type addressLines: string + :param regionCode: (optional) The country code + :type regionCode: string + :param locality: (optional) Restrict to a locality, ie:Mountain View + :type locality: string + """ + + params = { + "address":{ + "addressLines": addressLines + } + } + + if regionCode is not None: + params["address"]["regionCode"] = regionCode + + if locality is not None: + params["address"]["locality"] = locality + + return client._request("/v1:validateAddress", {}, # No GET params + base_url=_ADDRESSVALIDATION_BASE_URL, + extract_body=_addressvalidation_extract, + post_json=params) \ No newline at end of file diff --git a/googlemaps/client.py b/googlemaps/client.py index 1334571d..d6e37d3e 100644 --- a/googlemaps/client.py +++ b/googlemaps/client.py @@ -403,6 +403,7 @@ def _generate_auth_url(self, path, params, accepts_clientid): from googlemaps.places import places_autocomplete_query from googlemaps.maps import static_map +from googlemaps.addressvalidation import addressvalidation def make_api_method(func): """ @@ -446,6 +447,7 @@ def wrapper(*args, **kwargs): Client.places_autocomplete = make_api_method(places_autocomplete) Client.places_autocomplete_query = make_api_method(places_autocomplete_query) Client.static_map = make_api_method(static_map) +Client.addressvalidation = make_api_method(addressvalidation) def sign_hmac(secret, payload): diff --git a/tests/test_addressvalidation.py b/tests/test_addressvalidation.py new file mode 100644 index 00000000..ccb7df5b --- /dev/null +++ b/tests/test_addressvalidation.py @@ -0,0 +1,48 @@ +# This Python file uses the following encoding: utf-8 +# +# Copyright 2017 Google Inc. All rights reserved. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# + +"""Tests for the addressvalidation module.""" + +import responses + +import googlemaps +from . import TestCase + + +class AddressValidationTest(TestCase): + def setUp(self): + self.key = "AIzaasdf" + self.client = googlemaps.Client(self.key) + + @responses.activate + def test_simple_addressvalidation(self): + responses.add( + responses.POST, + "https://addressvalidation.googleapis.com/v1:validateAddress", + body='{"address": {"regionCode": "US","locality": "Mountain View","addressLines": "1600 Amphitheatre Pkwy"}}', + status=200, + content_type="application/json", + ) + + results = self.client.addressvalidation('1600 Amphitheatre Pk', regionCode='US', locality='Mountain View') + + self.assertEqual(1, len(responses.calls)) + self.assertURLEqual( + "https://addressvalidation.googleapis.com/v1:validateAddress?" "key=%s" % self.key, + responses.calls[0].request.url, + ) \ No newline at end of file From 01a06d7e237a1a736fc30d7bfd6448d61436f69e Mon Sep 17 00:00:00 2001 From: Thomas Anglaret Date: Thu, 29 Sep 2022 18:45:38 +0200 Subject: [PATCH 02/10] quota setting --- .github/dependabot.yml | 14 ++++++++++++ .github/scripts/distribution.sh | 14 ++++++++++++ .github/scripts/install.sh | 14 ++++++++++++ .github/stale.yml | 14 ++++++++++++ docs/conf.py | 14 ++++++++++++ googlemaps/client.py | 36 ++++++++++++++++++++++++++----- index.py | 38 +++++++++++++++++++++++++++++++++ noxfile.py | 14 ++++++++++++ setup.py | 14 ++++++++++++ test.py | 20 +++++++++++++++++ 10 files changed, 187 insertions(+), 5 deletions(-) create mode 100644 index.py create mode 100644 test.py diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 55a9ccdd..36f9436b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,3 +1,17 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + version: 2 updates: - package-ecosystem: pip diff --git a/.github/scripts/distribution.sh b/.github/scripts/distribution.sh index f7c08690..e779cd1d 100755 --- a/.github/scripts/distribution.sh +++ b/.github/scripts/distribution.sh @@ -1,4 +1,18 @@ #!/bin/bash +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + rm -rf dist diff --git a/.github/scripts/install.sh b/.github/scripts/install.sh index a585594c..39e7f9f0 100755 --- a/.github/scripts/install.sh +++ b/.github/scripts/install.sh @@ -1,4 +1,18 @@ #!/bin/bash +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + set -exo pipefail diff --git a/.github/stale.yml b/.github/stale.yml index 8ed0e080..1d39e65d 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -1,3 +1,17 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # Configuration for probot-stale - https://github.com/probot/stale # Number of days of inactivity before an Issue or Pull Request becomes stale diff --git a/docs/conf.py b/docs/conf.py index 19cdfef5..0d8314fb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,3 +1,17 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # -*- coding: utf-8 -*- # # Maps API documentation build configuration file, created by diff --git a/googlemaps/client.py b/googlemaps/client.py index d6e37d3e..6cfe5a00 100644 --- a/googlemaps/client.py +++ b/googlemaps/client.py @@ -31,6 +31,8 @@ import requests import random import time +import math +import sys import googlemaps @@ -52,7 +54,7 @@ class Client: def __init__(self, key=None, client_id=None, client_secret=None, timeout=None, connect_timeout=None, read_timeout=None, retry_timeout=60, requests_kwargs=None, - queries_per_second=50, channel=None, + queries_per_second=60, queries_per_minute=6000,channel=None, retry_over_query_limit=True, experience_id=None, requests_session=None, base_url=_DEFAULT_BASE_URL): @@ -93,11 +95,16 @@ def __init__(self, key=None, client_id=None, client_secret=None, seconds. :type retry_timeout: int - :param queries_per_second: Number of queries per second permitted. + :param queries_per_second: Number of queries per second permitted. Unset queries_per_minute to None. If set smaller number will be used. If the rate limit is reached, the client will sleep for the appropriate amount of time before it runs the current query. :type queries_per_second: int + :param queries_per_minute: Number of queries per minute permitted. Unset queries_per_second to None. If set smaller number will be used. + If the rate limit is reached, the client will sleep for the + appropriate amount of time before it runs the current query. + :type queries_per_minute: int + :param retry_over_query_limit: If True, requests that result in a response indicating the query rate limit was exceeded will be retried. Defaults to True. @@ -169,10 +176,29 @@ def __init__(self, key=None, client_id=None, client_secret=None, "timeout": self.timeout, "verify": True, # NOTE(cbro): verify SSL certs. }) - + + self.queries_quota : int self.queries_per_second = queries_per_second + self.queries_per_minute = queries_per_minute + try: + if (type(self.queries_per_second) == int and type(self.queries_per_minute) == int ): + self.queries_quota = math.floor(min(self.queries_per_second, self.queries_per_minute/60)) + print("##############", self.queries_quota) + elif (self.queries_per_second and type(self.queries_per_second) == int ): + self.queries_quota = math.floor(self.queries_per_second) + print("##############", self.queries_quota) + elif (self.queries_per_minute and type(self.queries_per_minute) == int ): + self.queries_quota = math.floor(self.queries_per_minute/60) + print("##############", self.queries_quota) + else: + sys.exit("MISSING VALID NUMBER for queries_per_second or queries_per_minute") + print("\n","API queries_quota:", self.queries_quota,"\n") + + except NameError: + sys.exit("MISSING VALUE for queries_per_second or queries_per_minute") + self.retry_over_query_limit = retry_over_query_limit - self.sent_times = collections.deque("", queries_per_second) + self.sent_times = collections.deque("", self.queries_quota) self.set_experience_id(experience_id) self.base_url = base_url @@ -303,7 +329,7 @@ def _request(self, url, params, first_request_time=None, retry_counter=0, # Check if the time of the nth previous query (where n is # queries_per_second) is under a second ago - if so, sleep for # the difference. - if self.sent_times and len(self.sent_times) == self.queries_per_second: + if self.sent_times and len(self.sent_times) == self.queries_quota: elapsed_since_earliest = time.time() - self.sent_times[0] if elapsed_since_earliest < 1: time.sleep(1 - elapsed_since_earliest) diff --git a/index.py b/index.py new file mode 100644 index 00000000..4587c93b --- /dev/null +++ b/index.py @@ -0,0 +1,38 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +## if your script calling addressvalidation is not is "googlemaps" folder +## adjust sys path to the "googlemaps" folder +# import sys +# sys.path.insert(0, './google-maps-services-python-master') +import googlemaps +from concurrent.futures import ThreadPoolExecutor + +# Development Test key [INTERNAL] +gmaps = googlemaps.Client(key='AIzaSyD_sJl0qMA65CYHMBokVfMNA7AKyt5ERYs') + +### VALIDATE with Address Validation API + +## THREADED requests +# Example 500 addresses +av_addresses = [ +# Test 4 addresses +('New York', 'US', ''), ('Madrid', 'ES', ''), ('paris', 'FR', ''), ('Roma', 'IT', '') +] + +## SINGLE request +for x in av_addresses: + addressvalidation_result = gmaps.addressvalidation(x[0], regionCode=x[1], locality=None) + print(addressvalidation_result) + diff --git a/noxfile.py b/noxfile.py index d3357fe4..2bc3b2a1 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,3 +1,17 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import nox SUPPORTED_PY_VERSIONS = ["3.7", "3.8", "3.9", "3.10"] diff --git a/setup.py b/setup.py index 8826822d..b2536fc3 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,17 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from setuptools import setup diff --git a/test.py b/test.py new file mode 100644 index 00000000..18a0afa4 --- /dev/null +++ b/test.py @@ -0,0 +1,20 @@ +import math + +queries_quota : int +queries_per_second = 60 # None or 60 +queries_per_minute = None # None or 6000 + +try: + if (type(queries_per_second) == int and type(queries_per_minute) == int ): + queries_quota = math.floor(min(queries_per_second, queries_per_minute/60)) + elif (queries_per_second): + queries_quota = math.floor(queries_per_second) + elif (queries_per_minute): + queries_quota = math.floor(queries_per_minute/60) + else: + print("MISSING VALID NUMBER for queries_per_second or queries_per_minute") + print(queries_quota) + +except NameError: + print("MISSING VALUE for queries_per_second or queries_per_minute") + From 1f7fb5a798300e90eb67d9fef0aa270f6ff139ef Mon Sep 17 00:00:00 2001 From: Thomas Anglaret Date: Thu, 29 Sep 2022 18:47:49 +0200 Subject: [PATCH 03/10] rm index --- index.py | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 index.py diff --git a/index.py b/index.py deleted file mode 100644 index 4587c93b..00000000 --- a/index.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -## if your script calling addressvalidation is not is "googlemaps" folder -## adjust sys path to the "googlemaps" folder -# import sys -# sys.path.insert(0, './google-maps-services-python-master') -import googlemaps -from concurrent.futures import ThreadPoolExecutor - -# Development Test key [INTERNAL] -gmaps = googlemaps.Client(key='AIzaSyD_sJl0qMA65CYHMBokVfMNA7AKyt5ERYs') - -### VALIDATE with Address Validation API - -## THREADED requests -# Example 500 addresses -av_addresses = [ -# Test 4 addresses -('New York', 'US', ''), ('Madrid', 'ES', ''), ('paris', 'FR', ''), ('Roma', 'IT', '') -] - -## SINGLE request -for x in av_addresses: - addressvalidation_result = gmaps.addressvalidation(x[0], regionCode=x[1], locality=None) - print(addressvalidation_result) - From 9a4a4d4a9bf37285e4ac3bddca14ee9e8a7563f8 Mon Sep 17 00:00:00 2001 From: Thomas Anglaret Date: Thu, 29 Sep 2022 19:00:49 +0200 Subject: [PATCH 04/10] quota --- googlemaps/client.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/googlemaps/client.py b/googlemaps/client.py index 6cfe5a00..b27edd75 100644 --- a/googlemaps/client.py +++ b/googlemaps/client.py @@ -183,13 +183,10 @@ def __init__(self, key=None, client_id=None, client_secret=None, try: if (type(self.queries_per_second) == int and type(self.queries_per_minute) == int ): self.queries_quota = math.floor(min(self.queries_per_second, self.queries_per_minute/60)) - print("##############", self.queries_quota) elif (self.queries_per_second and type(self.queries_per_second) == int ): self.queries_quota = math.floor(self.queries_per_second) - print("##############", self.queries_quota) elif (self.queries_per_minute and type(self.queries_per_minute) == int ): self.queries_quota = math.floor(self.queries_per_minute/60) - print("##############", self.queries_quota) else: sys.exit("MISSING VALID NUMBER for queries_per_second or queries_per_minute") print("\n","API queries_quota:", self.queries_quota,"\n") From 8498677e5bf4686b160c29696ece75b307c5566f Mon Sep 17 00:00:00 2001 From: Thomas Anglaret Date: Mon, 3 Oct 2022 11:37:42 +0200 Subject: [PATCH 05/10] params update --- .gitignore | 1 + coverage.xml | 849 ++++++++++++++++++++++++++++++++ googlemaps/addressvalidation.py | 9 +- tests/test_addressvalidation.py | 4 +- 4 files changed, 859 insertions(+), 4 deletions(-) create mode 100644 coverage.xml diff --git a/.gitignore b/.gitignore index c4477ba5..93e7a2fc 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ googlemaps.egg-info *.egg .vscode/ .idea/ +index.py diff --git a/coverage.xml b/coverage.xml new file mode 100644 index 00000000..1c38ca3d --- /dev/null +++ b/coverage.xml @@ -0,0 +1,849 @@ + + + + + + /Users/anglarett/Public/Drop Box/dev-se-git/google-maps-services-python + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/googlemaps/addressvalidation.py b/googlemaps/addressvalidation.py index 07df4e71..4802d8d0 100644 --- a/googlemaps/addressvalidation.py +++ b/googlemaps/addressvalidation.py @@ -1,5 +1,5 @@ # -# Copyright 2022 Google Inc. All rights reserved. +# Copyright 2014 Google Inc. All rights reserved. # # # Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -44,7 +44,7 @@ def _addressvalidation_extract(response): # raise exceptions.ApiError(response.status_code, error) -def addressvalidation(client, addressLines, regionCode=None , locality=None): +def addressvalidation(client, addressLines, regionCode=None , locality=None, enableUspsCass=None): """ The Google Maps Address Validation API returns a verification of an address See https://developers.google.com/maps/documentation/address-validation/overview @@ -55,6 +55,8 @@ def addressvalidation(client, addressLines, regionCode=None , locality=None): :type regionCode: string :param locality: (optional) Restrict to a locality, ie:Mountain View :type locality: string + :param enableUspsCass For the "US" and "PR" regions only, you can optionally enable the Coding Accuracy Support System (CASS) from the United States Postal Service (USPS) + :type locality: boolean """ params = { @@ -69,6 +71,9 @@ def addressvalidation(client, addressLines, regionCode=None , locality=None): if locality is not None: params["address"]["locality"] = locality + if enableUspsCass is not False or enableUspsCass is not None: + params["enableUspsCass"] = enableUspsCass + return client._request("/v1:validateAddress", {}, # No GET params base_url=_ADDRESSVALIDATION_BASE_URL, extract_body=_addressvalidation_extract, diff --git a/tests/test_addressvalidation.py b/tests/test_addressvalidation.py index ccb7df5b..69ad8b70 100644 --- a/tests/test_addressvalidation.py +++ b/tests/test_addressvalidation.py @@ -34,12 +34,12 @@ def test_simple_addressvalidation(self): responses.add( responses.POST, "https://addressvalidation.googleapis.com/v1:validateAddress", - body='{"address": {"regionCode": "US","locality": "Mountain View","addressLines": "1600 Amphitheatre Pkwy"}}', + body='{"address": {"regionCode": "US","locality": "Mountain View","addressLines": "1600 Amphitheatre Pkwy"},"enableUspsCass":true}', status=200, content_type="application/json", ) - results = self.client.addressvalidation('1600 Amphitheatre Pk', regionCode='US', locality='Mountain View') + results = self.client.addressvalidation('1600 Amphitheatre Pk', regionCode='US', locality='Mountain View', enableUspsCass=True) self.assertEqual(1, len(responses.calls)) self.assertURLEqual( From a80062bff83721d8cbca0a05f4655b5aabe83dd0 Mon Sep 17 00:00:00 2001 From: Thomas Anglaret Date: Mon, 3 Oct 2022 14:34:22 +0200 Subject: [PATCH 06/10] update params --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c5d8b18e..2b4478a2 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ directions_result = gmaps.directions("Sydney Town Hall", departure_time=now) # Validate an address with address validation -addressvalidation_result = gmaps.addressvalidation('1600 Amphitheatre Pk', regionCode='US',locality='Mountain View') +addressvalidation_result = gmaps.addressvalidation('1600 Amphitheatre Pk', regionCode='US',locality='Mountain View', enableUspsCass=True) ``` For more usage examples, check out [the tests](https://github.com/googlemaps/google-maps-services-python/tree/master/tests). From 5a0c166296ed455ed172e613036b39a22883e83c Mon Sep 17 00:00:00 2001 From: Thomas Anglaret Date: Fri, 28 Oct 2022 19:48:41 +0200 Subject: [PATCH 07/10] update --- googlemaps/addressvalidation.py | 2 +- googlemaps/client.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/googlemaps/addressvalidation.py b/googlemaps/addressvalidation.py index 4802d8d0..45b74655 100644 --- a/googlemaps/addressvalidation.py +++ b/googlemaps/addressvalidation.py @@ -50,7 +50,7 @@ def addressvalidation(client, addressLines, regionCode=None , locality=None, ena See https://developers.google.com/maps/documentation/address-validation/overview request must include parameters below. :param addressLines: The address to validate - :type addressLines: string + :type addressLines: array :param regionCode: (optional) The country code :type regionCode: string :param locality: (optional) Restrict to a locality, ie:Mountain View diff --git a/googlemaps/client.py b/googlemaps/client.py index b27edd75..54838fa0 100644 --- a/googlemaps/client.py +++ b/googlemaps/client.py @@ -425,7 +425,6 @@ def _generate_auth_url(self, path, params, accepts_clientid): from googlemaps.places import places_autocomplete from googlemaps.places import places_autocomplete_query from googlemaps.maps import static_map - from googlemaps.addressvalidation import addressvalidation def make_api_method(func): From ac0cb191590f6bb8f80ecd2d546fcf3b24c0f780 Mon Sep 17 00:00:00 2001 From: Thomas Anglaret Date: Fri, 28 Oct 2022 19:49:50 +0200 Subject: [PATCH 08/10] update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b4478a2..0a60e9ca 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ directions_result = gmaps.directions("Sydney Town Hall", departure_time=now) # Validate an address with address validation -addressvalidation_result = gmaps.addressvalidation('1600 Amphitheatre Pk', regionCode='US',locality='Mountain View', enableUspsCass=True) +addressvalidation_result = gmaps.addressvalidation(['1600 Amphitheatre Pk'], regionCode='US',locality='Mountain View', enableUspsCass=True) ``` For more usage examples, check out [the tests](https://github.com/googlemaps/google-maps-services-python/tree/master/tests). From e062e25e2b683d9c110275d815835e757a541945 Mon Sep 17 00:00:00 2001 From: Thomas Anglaret Date: Fri, 28 Oct 2022 19:57:37 +0200 Subject: [PATCH 09/10] update --- .gitignore | 1 + README.md | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 93e7a2fc..74d89080 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ googlemaps.egg-info .vscode/ .idea/ index.py +test.py diff --git a/README.md b/README.md index 0a60e9ca..cb5f7821 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,10 @@ directions_result = gmaps.directions("Sydney Town Hall", departure_time=now) # Validate an address with address validation -addressvalidation_result = gmaps.addressvalidation(['1600 Amphitheatre Pk'], regionCode='US',locality='Mountain View', enableUspsCass=True) +addressvalidation_result = gmaps.addressvalidation(['1600 Amphitheatre Pk'], + regionCode='US', + locality='Mountain View', + enableUspsCass=True) ``` For more usage examples, check out [the tests](https://github.com/googlemaps/google-maps-services-python/tree/master/tests). From c051f147c740f8528bc070df1b585682c450314e Mon Sep 17 00:00:00 2001 From: Thomas Anglaret Date: Fri, 28 Oct 2022 20:00:54 +0200 Subject: [PATCH 10/10] update --- test.py => text.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename test.py => text.py (98%) diff --git a/test.py b/text.py similarity index 98% rename from test.py rename to text.py index 18a0afa4..13734488 100644 --- a/test.py +++ b/text.py @@ -16,5 +16,4 @@ print(queries_quota) except NameError: - print("MISSING VALUE for queries_per_second or queries_per_minute") - + print("MISSING VALUE for queries_per_second or queries_per_minute") \ No newline at end of file