From 9f091f6226aa889735863006bcbdda417070776f Mon Sep 17 00:00:00 2001 From: Nick Williams Date: Fri, 21 Oct 2016 14:57:27 -0500 Subject: [PATCH 1/4] Fix the use of mutable default arguments Per issue #59 and #82, we should not be using mutable default arguments. This change properly handles arguments that need to default to mutable values. --- googleplaces/__init__.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/googleplaces/__init__.py b/googleplaces/__init__.py index 59f0850..31d9012 100644 --- a/googleplaces/__init__.py +++ b/googleplaces/__init__.py @@ -49,7 +49,10 @@ def __get__(self, instance, cls=None): return result -def _fetch_remote(service_url, params={}, use_http_post=False): +def _fetch_remote(service_url, params=None, use_http_post=False): + if not params: + params = {} + encoded_data = {} for k, v in params.items(): if isinstance(v, six.string_types): @@ -67,19 +70,25 @@ def _fetch_remote(service_url, params={}, use_http_post=False): request = urllib.request.Request(service_url, data=encoded_data) return (request_url, urllib.request.urlopen(request)) -def _fetch_remote_json(service_url, params={}, use_http_post=False): +def _fetch_remote_json(service_url, params=None, use_http_post=False): """Retrieves a JSON object from a URL.""" + if not params: + params = {} + request_url, response = _fetch_remote(service_url, params, use_http_post) if six.PY3: str_response = response.read().decode('utf-8') return (request_url, json.loads(str_response, parse_float=Decimal)) return (request_url, json.load(response, parse_float=Decimal)) -def _fetch_remote_file(service_url, params={}, use_http_post=False): +def _fetch_remote_file(service_url, params=None, use_http_post=False): """Retrieves a file from a URL. Returns a tuple (mimetype, filename, data) """ + if not params: + params = {} + request_url, response = _fetch_remote(service_url, params, use_http_post) dummy, params = cgi.parse_header( response.headers.get('Content-Disposition', '')) From 7e8df94f44e62162ed319bc90dc5b94c95e85960 Mon Sep 17 00:00:00 2001 From: Daniil Date: Thu, 1 Dec 2016 15:26:11 +0000 Subject: [PATCH 2/4] added support for next _page_token --- googleplaces/__init__.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/googleplaces/__init__.py b/googleplaces/__init__.py index 59f0850..d8822de 100644 --- a/googleplaces/__init__.py +++ b/googleplaces/__init__.py @@ -220,7 +220,7 @@ def query(self, **kwargs): def nearby_search(self, language=lang.ENGLISH, keyword=None, location=None, lat_lng=None, name=None, radius=3200, rankby=ranking.PROMINENCE, - sensor=False, type=None, types=[]): + sensor=False, type=None, types=[], pagetoken=None): """Perform a nearby search using the Google Places API. One of either location or lat_lng are required, the rest of the keyword @@ -280,6 +280,8 @@ def nearby_search(self, language=lang.ENGLISH, keyword=None, location=None, self._request_params['keyword'] = keyword if name is not None: self._request_params['name'] = name + if pagetoken is not None: + self._request_params['pagetoken'] = pagetoken if language is not None: self._request_params['language'] = language self._add_required_param_keys() @@ -757,6 +759,7 @@ def __init__(self, query_instance, response): for place in response['results']: self._places.append(Place(query_instance, place)) self._html_attributions = response.get('html_attributions', []) + self._next_page_token = response.get('next_page_token', []) @property def raw_response(self): @@ -779,11 +782,22 @@ def html_attributions(self): """ return self._html_attributions + @property + def next_page_token(self): + """Returns the next page token(next_page_token). + """ + return self._next_page_token + @property def has_attributions(self): """Returns a flag denoting if the response had any html attributions.""" return len(self.html_attributions) > 0 + @property + def has_next_page_token(self): + """Returns a flag denoting if the response had any html attributions.""" + return len(self.next_page_token) > 0 + def __repr__(self): """ Return a string representation stating the number of results.""" return '<{} with {} result(s)>'.format(self.__class__.__name__, len(self.places)) From 1d1fab0188bbc156e0e8fa8a5a8694fc4f5bebf9 Mon Sep 17 00:00:00 2001 From: slimkrazy Date: Sun, 8 Jan 2017 18:54:49 +0000 Subject: [PATCH 3/4] Added pagetoken support for text_search API. Updated README. --- CONTRIBUTORS | 1 + README.rst | 16 +++++++++++++++- googleplaces/__init__.py | 33 +++++++++++++++++++++------------ 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index f6f45ad..becd975 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -17,3 +17,4 @@ jpulec ruhman drootnar keradus +daniil-shumko diff --git a/README.rst b/README.rst index 3456d29..71160f5 100644 --- a/README.rst +++ b/README.rst @@ -87,6 +87,12 @@ Code is easier to understand than words, so let us dive right in :: photo.data + # Are there any additional pages of results? + if query_result.has_next_page_token: + query_result_next_page = google_places.nearby_search( + pagetoken=query_result.next_page_token) + + # Adding and deleting a place try: added_place = google_places.add_place(name='Mom and Pop local store', @@ -136,6 +142,10 @@ Reference name -- A term to be matched against the names of the Places. Results will be restricted to those containing the passed name value. (default None) + pagetoken-- Optional parameter to force the search result to return the next + 20 results from a previously run search. Setting this parameter + will execute a search with the same parameters used previously. (default None) + radius -- The radius (in meters) around the location/lat_lng to restrict the search to. The maximum is 50000 meters (default 3200) @@ -165,6 +175,10 @@ Reference language -- The language code, indicating in which language the results should be returned, if possble. (default en) + pagetoken-- Optional parameter to force the search result to return the next + 20 results from a previously run search. Setting this parameter + will execute a search with the same parameters used previously. (default None) + radius -- The radius (in meters) around the location/lat_lng to restrict the search to. The maximum is 50000 meters (default 3200) @@ -354,7 +368,7 @@ Reference googleplaces.Place reference - (DEPRECATED) Returns a unique identifier for the Place that can be used to + (DEPRECATED) Returns a unique identifier for the Place that can be used to fetch full details about it. It is recommended that stored references for Places be regularly updated. A Place may have many valid reference tokens. diff --git a/googleplaces/__init__.py b/googleplaces/__init__.py index 5100868..8dadff7 100644 --- a/googleplaces/__init__.py +++ b/googleplaces/__init__.py @@ -35,7 +35,7 @@ __all__ = ['GooglePlaces', 'GooglePlacesError', 'GooglePlacesAttributeError', 'geocode_location'] -__version__ = '1.3.1' +__version__ = '1.4.0' __author__ = 'Samuel Adu' __email__ = 'sam@slimkrazy.com' @@ -223,8 +223,8 @@ def nearby_search(self, language=lang.ENGLISH, keyword=None, location=None, sensor=False, type=None, types=[], pagetoken=None): """Perform a nearby search using the Google Places API. - One of either location or lat_lng are required, the rest of the keyword - arguments are optional. + One of either location, lat_lng or pagetoken are required, the rest of + the keyword arguments are optional. keyword arguments: keyword -- A term to be matched against all available fields, including @@ -250,9 +250,13 @@ def nearby_search(self, language=lang.ENGLISH, keyword=None, location=None, types -- An optional list of types, restricting the results to Places (default []). If there is only one item the request will be send as type param. + pagetoken-- Optional parameter to force the search result to return the next + 20 results from a previously run search. Setting this parameter + will execute a search with the same parameters used previously. + (default None) """ - if location is None and lat_lng is None: - raise ValueError('One of location or lat_lng must be passed in.') + if location is None and lat_lng is None and pagetoken is None: + raise ValueError('One of location, lat_lng or pagetoken must be passed in.') if rankby == 'distance': # As per API docs rankby == distance: # One or more of keyword, name, or types is required. @@ -290,18 +294,22 @@ def nearby_search(self, language=lang.ENGLISH, keyword=None, location=None, _validate_response(url, places_response) return GooglePlacesSearchResult(self, places_response) - def text_search(self, query, language=lang.ENGLISH, lat_lng=None, - radius=3200, type=None, types=[], location=None): + def text_search(self, query=None, language=lang.ENGLISH, lat_lng=None, + radius=3200, type=None, types=[], location=None, pagetoken=None): """Perform a text search using the Google Places API. - Only the query kwarg is required, the rest of the keyword arguments - are optional. + Only the one of the query or pagetoken kwargs are required, the rest of the + keyword arguments are optional. keyword arguments: lat_lng -- A dict containing the following keys: lat, lng (default None) location -- A human readable location, e.g 'London, England' (default None) + pagetoken-- Optional parameter to force the search result to return the next + 20 results from a previously run search. Setting this parameter + will execute a search with the same parameters used previously. + (default None) radius -- The radius (in meters) around the location/lat_lng to restrict the search to. The maximum is 50000 meters. (default 3200) @@ -326,6 +334,8 @@ def text_search(self, query, language=lang.ENGLISH, lat_lng=None, self._request_params['types'] = '|'.join(types) if language is not None: self._request_params['language'] = language + if pagetoken is not None: + self._request_params['pagetoken'] = pagetoken self._add_required_param_keys() url, places_response = _fetch_remote_json( GooglePlaces.TEXT_SEARCH_API_URL, self._request_params) @@ -784,8 +794,7 @@ def html_attributions(self): @property def next_page_token(self): - """Returns the next page token(next_page_token). - """ + """Returns the next page token(next_page_token).""" return self._next_page_token @property @@ -795,7 +804,7 @@ def has_attributions(self): @property def has_next_page_token(self): - """Returns a flag denoting if the response had any html attributions.""" + """Returns a flag denoting if the response had a next page token.""" return len(self.next_page_token) > 0 def __repr__(self): From 85442cbaf3c07fac1692be325298cdecd671c741 Mon Sep 17 00:00:00 2001 From: slimkrazy Date: Sun, 8 Jan 2017 21:10:08 +0000 Subject: [PATCH 4/4] Updated contributors file. --- CONTRIBUTORS | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index becd975..cf2dbcf 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -18,3 +18,4 @@ ruhman drootnar keradus daniil-shumko +beamerblvd