Making API calls to Google Books API public data

1,328 views
Skip to first unread message

Fourat Janabi

unread,
Apr 22, 2016, 6:55:45 PM4/22/16
to Google App Engine

I have a GAE instance using Python 2.7.11. In it, I make several calls to Google's Book API, and only ever for public data. The two APIs I use are the book search and retrieve a specific volume. I neither want, nor ever plan on getting private information on these calls. When I deployed my app locally, the APIs always respond with the data I'm looking for. I love them. When I deploy my app, I get a '403 forbidden' error. Nothing I have tried seems to work. After several hours of research, the narrowest I can get it down to is that I need an OAuth2 token, which is used to request private user data, to request public book data. Why is this? My app will never request nor needs access to user data. Can anyone help with this? Thank you.

Adam (Cloud Platform Support)

unread,
Apr 22, 2016, 8:02:54 PM4/22/16
to Google App Engine
It would help if you could post the exact code which is making the call as well as the exact JSON response your receive. This also seems like a good question to post to Stack Overflow, as it will have greater visibility. Check out our community support page for the list of tags we monitor.
Message has been deleted

Fourat Janabi

unread,
Apr 22, 2016, 8:52:54 PM4/22/16
to Google App Engine
Traceback (most recent call last):
     File         "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/base/data/home/apps/s~my-life-app/1.392279800807967905/myapp.py", line 320, in post
    response_body = urlopen(request).read()
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/urllib2.py", line 127, in urlopen
    return _opener.open(url, data, timeout)
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/urllib2.py", line 410, in open
    response = meth(req, response)
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/urllib2.py", line 523, in http_response
    'http', request, response, code, msg, hdrs)
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/urllib2.py", line 448, in error
    return self._call_chain(*args)
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/urllib2.py", line 382, in _call_chain
    result = func(*args)
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/urllib2.py", line 531, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) 
HTTPError: HTTP Error 403: Forbidden

Here is the code that creates that creates the API Call:

headers = {'Accept': 'application/json'}      
  book = Book(parent=books_key)
  book.name = self.request.get('name')
  googleBookSearch = "https://www.googleapis.com/books/v1/volumes?q="
  googleBookVol = "https://www.googleapis.com/books/v1/volumes/ID"
  escapedBookName = urllib.quote(book.name)
  apiCall = googleBookSearch + escapedBookName + "&" + api_key2
  request = Request(apiCall, headers=headers)
  response_body = urlopen(request).read()
  parsed_book = json.loads(response_body)
  if parsed_book['totalItems'] != 0:
    volumeID = parsed_book['items'][0]['id']
    googleBookVol = googleBookVol.replace("ID", volumeID)
    googleBookVol = googleBookVol + "?" + api_key2
    logging.info(googleBookVol)
    request = Request(googleBookVol, headers=headers)
    response_body = urlopen(request).read()
    response_body = json.loads(response_body)
    book.name = response_body['volumeInfo']['title']
    pageCount = response_body['volumeInfo']['pageCount']
    book.pages = int(pageCount)
    bookCover = response_body['volumeInfo']['imageLinks']['smallThumbnail']
    book.cover = str(bookCover)
    book.published = str(response_body['volumeInfo']['publishedDate'])
    book.author = str(response_body['volumeInfo']['authors'][0])
    book.put()
    self.redirect("/books")

Adam (Cloud Platform Support)

unread,
Apr 25, 2016, 7:50:36 PM4/25/16
to Google App Engine
I get the same error, but I can see more detail in the App Engine logs viewer:

HttpError: <HttpError 403 when requesting https://www.googleapis.com/books/v1/volumes?q=<query>&alt=json&key=<key> returned "Cannot determine user location for geographically restricted operation.">

It seems this is not related to OAuth2, but is a known issue with the Books API when run from App Engine and some other hosting services where the originating IP cannot be geolocated. To solve this, you can try adding the 'country' query string parameter to the request eg. '&country=US'.

Fourat Janabi

unread,
Apr 26, 2016, 6:46:43 PM4/26/16
to Google App Engine
Thank you so much Adam! That worked :)
Reply all
Reply to author
Forward
0 new messages