Deploying web2py to Google App Engine
Search for TODO: in this chapter
There are two kinds of deployment to the Google App Engine: Locally, using a web server running as localhost
on your development machine, and in App Engine's cloud servers.
Deploying locally is normally faster and lets you make mistakes before you go live. It is also necessary to build database indexes.
This chapter shows how to run web2py itself on Google App Engine, both locally and in the cloud. Web2py's sample GAE configuration files default to the familiar web2py welcome
app.
When you deploy your app, you also deploy web2py itself
Your app consists of a set of subdirectories under web2py/applications/your_app
.
The web2py directory tree may look complicated, but it's actually a fairly small framework consisting of a couple megabytes of source code in a well-structured directory tree. In practice, remember it's just a program--you launch it as you would any other Python program, for example:
# Just illustrating. Don't do this now
$ cd /usr/local/web2py
$ python web2py.py
Your app will be in a directory tree of its own in the location web2py/applications/your_app
.
Google App Engine apps are just files that get served
Deploying a directory tree to GAE results in something a little gross on the Google side of things. It's just a huge mass of files in a single directory. Those get served by GAE when requested.
The directory tree structure is preserved only because slashes (or in Windows, backslashes) are legal filenames in GAE's own file system.
Deploying web2py locally using Google App Engine
Your first job is to run web2py locally the GAE way. You must do this before deploying it to GAE.
Recall that to run web2py locally you need a webserver running on your development machine. Instead of web2py's built-in Rocket server, you'll be using GAE's. Let's get web2py running locally using GAE deployment tools.
- Make sure you're in your web2py directory.
$ cd /usr/local/web2py
- Run web2py using the
-G GAE
option to generate the proper configuration files and place them in the web2py directory:
$ python web2py.py -G GAE
Your GAE app name: tomcampbell
This generates the files app.yaml
and gaehandler.py
. If you do it more than once you'll get this error message:
app.yaml already exists in the web2py folder
gaehandler.py already exists in the web2py folder
TODO: Explain what files are generated
TODO: Explain app name unless that happened early, which probably should be the case
TODO: Replace tomcampbell with better example name
This results in the creation of two files GAE needs: app.yaml
and gaehandler.py
.
- Run
dev_appserver.py
:
$ dev_appserver.py ../web2py
# I think it may actually be:
# dev_appserver.py ../web2py --mysql_user=sampleuser --mysql_password=foo
Open your browser and visit this address: http://localhost:8080/welcome/default/index
:
Deploying web2py to the cloud
We've seen web2py running locally using GAE. It's time to get that baby on the Web! Use appcfg.py
to copy the files to up the cloud
$ appcfg.py update ../web2py
The output looks something like this
09:38 PM Application: tomcampbell; version: 1
09:38 PM Host: appengine.google.com
09:38 PM
Starting update of app: tomcampbell, version: 1
09:38 PM Getting current resource limits.
09:38 PM Scanning files on local disk.
Could not guess mimetype for applications/welcome/static/fonts/glyphicons-halflings-regular.woff2. Using application/octet-stream.
09:38 PM Scanned 500 files.
Could not guess mimetype for applications/welcome/static/fonts/glyphicons-halflings-regular.woff2. Using application/octet-stream.
09:38 PM Cloning 195 static files.
09:38 PM Cloning 496 application files.
09:38 PM Uploading 43 files and blobs.
09:38 PM Uploaded 43 files and blobs.
09:38 PM Compilation starting.
09:38 PM Compilation: 17 files left.
09:38 PM Compilation: 11 files left.
09:38 PM Compilation completed.
09:38 PM Starting deployment.
09:38 PM Checking if deployment succeeded.
09:38 PM Deployment successful.
09:38 PM Checking if updated app version is serving.
09:38 PM Completed update of app: tomcampbell, version: 1
Running your newly deployed cloud app;
To start the app:
- Open
http://tomcampbell.appspot.com
in the browser.
Troubleshooting: Do you need to update your version in GAE?
The first time you do this everything will happen as expected. But you may repeat this process later and discover your deployed app does not seem to have updated even if you changed the version number in app.yaml
.
That's because GAE keeps several versions of your app available at any one time (currently it's 10 versions) and you need to choose which version you want as the "default".
The first time you upload it's easy, because that becomes the current version. App Engine serves pages from that version automatically.
If you leave the version number the same in app.yaml
when you upload a new version of an app, App Engine silently overwrites the version you're uploading.
If you change the version number in app.yaml
, however, you must then select that as the current version manually.
Here's how to see which version is current.
Checking which Google App Engine version is the current one (default)
To find out which version is current:
- From (https://console.developers.google.com/project/)[https://console.developers.google.com/project/) choose the current project by clicking its name.
- From the left panel choose
Compute
>App Engine
>Versions
.
A list of versions appears. Here's what it looks like the first time you upload an app:
TODO: Improving this document
Explain
Admin is disabled because insecure channel
message and how to enable HTTPSI got this message on localhost after running appcfg.py
The authentication flow has completed.
- See if there's ever a reason to answer
n
to this question:
Allow dev_appserver to check for updates on startup? (Y/n):
TODO: This is probably outdated
$ appcfg.py update ../web2py
The first time you do this, you'll be asked for permission by GAE to use your Google account:
- Choose
Allow
.
Importing python-MySQL
GAE deployment requires the MySQL-python
package. If you have problems deploying, you may need to install it.
- Installing the
MySQL-python
requires pip. See Installing pip to determine if you have pip, and how to install it if you don't.
$ sudo -H pip install MySQL-python
Troubleshooting
ImportError: Cannot import module....modules.MySQLdb
At the time of writing there's a problem running this on recent versions of Macintosh OS X.
If you get output like this in the terminal, you need a patch. The meat of the message is ImportError: Cannot import module....modules.MySQLdb
.
ERROR 2016-01-05 03:13:53,224 restricted.py:174] Traceback (most recent call last):
File "/Users/tom/web2py/gluon/restricted.py", line 227, in restricted
exec ccode in environment
File "/Users/tom/web2py/applications/test/models/db.py", line 18, in <module>
import MySQLdb as mysql
File "/Users/tom/web2py/web2py/gluon/custom_import.py", line 89, in custom_importer
raise ImportError, 'Cannot import module %s' % str(e)
ImportError: Cannot import module 'applications.test.modules.MySQLdb'
It's because of changes to OS X that restrct the use of relative path names in packages. See MySQL Improperly Configured Reason: unsafe use of relative path on stackoverflow.
- The fix is to run the
install_name_tool
program:
$ sudo install_name_tool -change libmysqlclient.18.dylib \
/usr/local/mysql/lib/libmysqlclient.18.dylib \
/Library/Python/2.7/site-packages/_mysql.so
Resources
- The web2py README.MD has a brief GAE discussion
- Google App Engine (GAE): Uploading Your Application
- Google App Engine Python 2.7 documentation
- Rapid Development with Python, Django, and Google App Engine by the great Guido van Rossum, creator of Python and the accompanying Presentation slides in PDF form is a little out of date but has good information on GAE architecture.
- Ridge Solutions: Web2py - Make your app the default web application.
- web2py book: Deploying on Google App Engine,
- web2py README.MD: