googlemaps / google-maps-services-python

Python client library for Google Maps API Web Services
Apache License 2.0
4.49k stars 1.3k forks source link

Pagination in Places Produces ApiError: INVALID_REQUEST (Rate-limit Problem?) #366

Open ChicagoDev opened 4 years ago

ChicagoDev commented 4 years ago

Environment Details

API Used: Places OS: Mac OS 10.15.4 (Catalina) Python Version: 3.8 Library Version: 4.4.1 Other Info: Executed in PyCharm

Steps to Reproduce

1) Retrieve a list of places with a radius 2) submit a next page request with next_page_token

Code that Produces Exception

import googlemaps
import json
from pprint import pprint
import time

## Import API Key
with open('config.json') as config_file:
    config_data = json.load(config_file)

## Establish API Connection
gmaps = googlemaps.Client(key=config_data['maps_api_key'])

## Find places
barber_shops = gmaps.places('barber shop', radius=3218)

#Extract Next Page Token
npt = barber_shops["next_page_token"]

#For Usability
print(f'The first business returned is {barber_shops["results"][0]["name"]}')
print(f'\t The placed id is {barber_shops["results"][0]["id"]}')
print(f'\n\t\tThe next_page_token is {npt}')

#Request the next page || Raises googlemaps.exceptions.ApiError: INVALID_REQUEST
next_page_barber_shops = gmaps.places('barber shop', radius=3218, page_token=npt)
pprint(next_page_barber_shops)

Stack Trace

Traceback (most recent call last):
  File "/Users/bjg/CDA/GMaps_LeadGen/rate_limit_bug", line 26, in <module>
    next_page_barber_shops = gmaps.places('barber shop', radius=3218, page_token=npt)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/googlemaps/client.py", line 418, in wrapper
    result = func(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/googlemaps/places.py", line 243, in places
    return _places(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/googlemaps/places.py", line 409, in _places
    return client._request(url, params)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/googlemaps/client.py", line 313, in _request
    result = self._get_body(response)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/googlemaps/client.py", line 342, in _get_body
    raise googlemaps.exceptions.ApiError(api_status,
googlemaps.exceptions.ApiError: INVALID_REQUEST

Extra

Adding time.sleep(2) resolves this error and the code executes

Working Code
import googlemaps
import json
from pprint import pprint
import time

## Import API Key
with open('config.json') as config_file:
    config_data = json.load(config_file)

## Establish API Connection
gmaps = googlemaps.Client(key=config_data['maps_api_key'])

## Find places
barber_shops = gmaps.places('barber shop', radius=3218)

#Extract Next Page Token
npt = barber_shops["next_page_token"]

#For Usability
print(f'The first business returned is {barber_shops["results"][0]["name"]}')
print(f'\t The placed id is {barber_shops["results"][0]["id"]}')
print(f'\n\t\tThe next_page_token is {npt}')

#Request the next page || Raises googlemaps.exceptions.ApiError: INVALID_REQUEST
#next_page_barber_shops = gmaps.places('barber shop', radius=3218, page_token=npt)
#pprint(next_page_barber_shops)

#However if time.sleep(2) is utilized, there is no error:
time.sleep(2)
next_page_barber_shops = gmaps.places('barber shop', radius=3218, page_token=npt)
pprint(next_page_barber_shops)
jpoehnelt commented 4 years ago

I haven't had a chance to look into this. Did you find anything else on this?

Giuzzilla commented 4 years ago

Having the same issue, and can confirm that time.sleep(2) solves it, so it seems to be a rate-limiting issue.

If I call the API twice with no page_token the request works correctly. If I query multiple different "type" with no sleep I don't get any rate-limiting/error either.

The problem is there even if you don't use a radius.

skumarlabs commented 4 years ago

Had the same problem, fixed it using time.sleep(2) The reason for this behavior is also mentioned in the documentation

There is a short delay between when a next_page_token is issued, and when it will become valid. Requesting the next page before it is available will return an INVALID_REQUEST response. Retrying the request with the same next_page_token will return the next page of results.

therahulmehta commented 2 years ago

There is a short delay between when a next_page_token is issued, and when it will become valid. Requesting the next page before it is available will return an INVALID_REQUEST response. Retrying the request with the same next_page_token will return the next page of results.

@skumarlabs could you point me to where you found that? I just can't seem to find that in the docs now.

koosha-t commented 11 months ago

Any updates on this?

Tylerlhess commented 9 months ago

This should either be closed as working as designed (as it is according to the docs) or add in an automatic sleep timer with override option when using a next_page_token.

Or better yet update the library to use the Nearby Search (New) api endpoint which only returns 20 results.