Search code examples
javascriptpythongoogle-app-enginegoogle-cloud-endpointswebapp2

Google Cloud Endpoints not Loading when redirect via webapp2


I have a web app running on Google App Engine. I implemented an API via Cloud Endpoints and I use it in this app via Javascript. However, to log the users in, I use webapp2 to handle the process. When the users are successfully logged in, they are redirected to the home page. Everything seemed to work fine before I added the webapp2 redirect, but now I get this error:

GET http://localhost:10080/_ah/api/discovery/v1/apis/books/v1/rest?fields=rootUrl%2CservicePath%2Cresources%2Cparameters%2Cmethods&pp=0 500 (OK)

Uncaught TypeError: Cannot read property 'queryBooks' of undefined

I think it's really strange, since what I did more was just redirect from one page to another. I tried to refresh the page but the error was still there. I tried to handle the login via javascript but it was too painful.

Here's the relevant code:

gapi loading:

<head>
  ...   
  <script type="text/javascript">
    function init() {
      var apisToLoad;
      var loadCallback = function() {
        console.log(88);
        if (--apisToLoad == 0) {
          signin(true, userAuthed);
        }
      };

      apisToLoad = 2; // must match number of calls to gapi.client.load()
      apiRoot = '//' + window.location.host + '/_ah/api';
      console.log(apiRoot);
      gapi.client.load('books', 'v1', loadCallback, apiRoot);
      gapi.client.load('oauth2', 'v2', loadCallback);
    }

    function authorizeCallback()
    {

    }

    function signin(mode, authorizeCallback) {
      gapi.auth.authorize({client_id: '480333XXXXXXXXXXXXXXo6lckcrt5sehee3dg.apps.googleusercontent.com',
        scope: 'https://www.googleapis.com/auth/userinfo.email', immediate: true},
        authorizeCallback);
    }

    function userAuthed() {
      var request = gapi.client.oauth2.userinfo.get().execute(function(resp) {
        if (!resp.code) {
          // User is signed in, call my Endpoint
          start_spinner();
          gapi.client.books.queryBooks({"subject":"ita"}).execute(function(q) {
            create_content(q.items, "ita");
            add_searches();
          });
        }
      });
    }
    </script>
     <script src="https://apis.google.com/js/client.js?onload=init"></script>
</head>
<body>

project/index.html

<a href="{{ url|safe }}" class="mdl-button mdl-js-button mdl-button--accent">
  Accedi
</a>

webapp2 main.py

    (all the imports)

    JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)


class MainPage(webapp2.RequestHandler):
    def get(self):
        user = users.get_current_user()

        url = users.create_login_url(self.request.uri + 'login')
        if user:

            user_id = getUserId(user)
            p_key = ndb.Key(Profile, user_id)
            profile = p_key.get()

            if profile:
                self.redirect('/partials/home.html', permanent = True)


        template_values = {'url': url}

        template = JINJA_ENVIRONMENT.get_template('index.html')
        self.response.write(template.render(template_values))


class LogIn(webapp2.RequestHandler):
    def get(self):
        user = users.get_current_user()

        if user:
            user_id = getUserId(user)
            p_key = ndb.Key(Profile, user_id)
            profile = p_key.get()

            if profile:
                self.redirect('partials/home.html', permanent = True)
            else:
                profile = Profile(
                    key = p_key,
                    nickName = user.nickname(), 
                    firstName = "Test",
                    lastName = "Test",
                    mainEmail = user.email()
                )
                # save the profile to datastore
                profile.put()
                self.redirect('/partials/home.html')

        else:
            self.redirect('/')

app = webapp2.WSGIApplication([
    ('/', MainPage),
    ('/login', LogIn)
], debug=True)

EDIT:

Here's the app.yaml code:

application: project-books
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:

- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: /js
  static_dir: static/js

- url: /img
  static_dir: static/img

- url: /css
  static_dir: static/css

- url: /partials
  static_dir: static/partials

#- url: /.*
#  script: main.app

- url: /_ah/spi/.*
  script: books.api
  secure: always

libraries:

- name: endpoints
  version: latest

- name: pycrypto
  version: latest

- name: webapp2
  version: latest

- name: jinja2
  version: latest

When I comment #- url: /.* # script: main.app

the API is working and can be accessed in the api explorer on localhost, otherwise it can't. So the error is in these two lines but I can't figure out why.


Solution

  • Assuming you show indeed all the relevant code the error message suggests that gapi.client.books is undefined at this line (the only reference to queryBooks):

    gapi.client.books.queryBooks({"subject":"ita"}).execute(function(q) {
    

    You may want to display it in a debug message to confirm that.

    If confirmed check your related code, eventually your imports and your API installation in GAE.