Search code examples
pythonajaxgoogle-app-enginerpcwebapp2

Can't get "Using AJAX to Enable Client RPC Requests" Demo on google app engine to work with python 2.7


I've never done anything with AJAX, only basic things with javascript, and my python experience is more on the scientific side. That said, my website development on google app engine was moving along nicely until I came up on trying to create a demo of ajax functionality.

I found this demo on the GAE site, but it doesn't seem to be working. This post will probably be pretty long as I want to explain hurdle I'm experiencing. Any help or insight that can be provided, either on how to fix this demo or use a different ajax approach, is greatly appreciated

For reference I am using Google App Engine with Python 2.7 and am running 32-bit Ubuntu 12.04. Also, I know that other questions have been asked around this topic, but I have not found a satisfactory response.

...

So starting with the demo I copied the requisite index.html, main.py, and app.yaml filesto a directory called get. Per the instructions I also created a subdirectory, static, where I put in a copy of json2.js (which the demo said could be found at json.org , but I could only find at github). So my project structure looks like this:

-dir:get
  -app.yaml
  -main.py
  -index.html
  -dir static:
    -json2.js

With everything setup I start my webserver:

chris@thinkpad:~/code/get$ python ~/google_appengine/dev_appserver.py ./

This starts successfully. However, when I point my browser to http://localhost:8080/ i get an import error:

File "/home/chris/code/get/main.py", line 6, in <module>
from django.utils import simplejson
ImportError: No module named django.utils

So I do a little bit of digging and it seems like the tutorial was written for python 2.5, so I'll need to make some changes to my app.yaml file. The version from the demo looks like this:

application: get
version: 1
runtime: python
api_version: 1

handlers:
- url: /static
  static_dir: static

- url: /.*
  script: main.py

my new, 2.7 version is shown below. Note the addition of threadsafe: true, the conversion of main.py to main.app and the addition of the libraries parameter.

application: get
version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /static
  static_dir: static

- url: /.*
  script: main.app

libraries:
- name: django
  version: latest

Again, I successfully start the appserver. Now, pointing to http://localhost:8080/ raises the following error:

ImportError: <module 'main' from '/home/chris/code/get/main.pyc'> has no attribute app

This leads me to look at the app function in the bottom of main.py. By default it looks like this:

def main():
    app = webapp.WSGIApplication([
        ('/', MainPage),
        ('/rpc', RPCHandler),
        ], debug=True)
    util.run_wsgi_app(app)

if __name__ == '__main__':
    main()

Massaging it to make it a little more python27 friendly replaces that entire code block, function and all, with:

app = webapp.WSGIApplication([
        ('/', MainPage),
        ('/rpc', RPCHandler),
        ], debug=True)

Restarting the appserver and again pointing to http://localhost:8080/, I finally get the page to appear:

enter image description here

Unfortunately, the saga continues. I restart the appserver, getting this printout:

chris@thinkpad:~/code/get$ python ~/google_appengine/dev_appserver.py ./
INFO     2013-05-25 16:18:28,097 sdk_update_checker.py:244] Checking for updates to the SDK.
INFO     2013-05-25 16:18:28,322 sdk_update_checker.py:272] The SDK is up to date.
INFO     2013-05-25 16:18:28,354 api_server.py:153] Starting API server at:  http://localhost:56101
INFO     2013-05-25 16:18:28,375 dispatcher.py:164] Starting server "default" running at: http://localhost:8080
INFO     2013-05-25 16:18:28,385 admin_server.py:117] Starting admin server at: http://localhost:8000

Then I click the 'Add' button. This raises an error, which I've printed below in it's entirety, that I can't quite figure out:

INFO     2013-05-25 16:18:37,633 server.py:585] default: "GET / HTTP/1.1" 200 3597
INFO     2013-05-25 16:18:37,989 server.py:585] default: "GET /static/json2.js HTTP/1.1" 304 -
INFO     2013-05-25 16:18:38,164 server.py:585] default: "GET /favicon.ico HTTP/1.1" 404 154
ERROR    2013-05-25 16:18:41,469 webapp2.py:1528] __init__() takes exactly 1 argument (3 given)
Traceback (most recent call last):
  File "/home/chris/google_appengine/lib/webapp2-2.3/webapp2.py", line 1511, in __call__
    rv = self.handle_exception(request, response, e)
  File "/home/chris/google_appengine/lib/webapp2-2.3/webapp2.py", line 1505, in __call__
    rv = self.router.dispatch(request, response)
  File "/home/chris/google_appengine/lib/webapp2-2.3/webapp2.py", line 1253, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/home/chris/google_appengine/lib/webapp2-2.3/webapp2.py", line 1076, in __call__
handler = self.handler(request, response)
TypeError: __init__() takes exactly 1 argument (3 given)
ERROR    2013-05-25 16:18:41,471 wsgi.py:235] 
Traceback (most recent call last):
  File "/home/chris/google_appengine/google/appengine/runtime/wsgi.py", line 223, in Handle
    result = handler(dict(self._environ), self._StartResponse)
  File "/home/chris/google_appengine/lib/webapp2-2.3/webapp2.py", line 1519, in __call__
    response = self._internal_error(e)
  File "/home/chris/google_appengine/lib/webapp2-2.3/webapp2.py", line 1511, in __call__
    rv = self.handle_exception(request, response, e)
  File "/home/chris/google_appengine/lib/webapp2-2.3/webapp2.py", line 1505, in __call__
    rv = self.router.dispatch(request, response)
  File "/home/chris/google_appengine/lib/webapp2-2.3/webapp2.py", line 1253, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/home/chris/google_appengine/lib/webapp2-2.3/webapp2.py", line 1076, in __call__
handler = self.handler(request, response)
TypeError: __init__() takes exactly 1 argument (3 given)
INFO     2013-05-25 16:18:41,479 server.py:585] default: "GET /rpc?action=Add&arg0=%221%22&arg1=%222%22&time=1369498721460 HTTP/1.1" 500 -

At this point I'm stuck. Any thoughts on how to get this demo to function properly, or perhaps a better path to go down to make my web app ajaxy, would be greatly appreciated.


Solution

  • Any thoughts on how to get this demo to function properly, or perhaps a better path to go down to make my web app ajaxy, would be greatly appreciated.

    Since posting a full app here would be a bit overkill, I decided to put a very simple ajax demo on Github. This doesn't immediately fix your issues, but should help with the concept.