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 <http://stackoverflow.com/questions/24460197/accessing-books-api-through-appengine-fails-with-error-code-400>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'. On Friday, April 22, 2016 at 8:52:54 PM UTC-4, Fourat Janabi wrote: > > 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") > > > On Friday, April 22, 2016 at 7:55:45 PM UTC-3, Fourat Janabi wrote: >> >> >> 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. >> > -- You received this message because you are subscribed to the Google Groups "Google App Engine" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/google-appengine. To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/74388bb3-bb4d-4293-8776-aec0ab430021%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
