This will show you how to get a Pylons web app running on Google App Engine (GAE) in about 15 minutes, assuming you already have your GAE account and a familiarity with Pylons and
The approach described here is focused on using as “normal” a process as possible for creating a Pylons app, with minimal modifications for GAE. It uses a stock
virtualenv, and a stock
paster create template, instead of an entirely different setup just for GAE. Several manual edits are required (but fewer now!)
This means that you could use an existing app or an existing virtualenv, with a few modifications. This is up to you, as I don’t know what your exact setup looks like, but most of the steps below should apply.
To begin, run the following commands in an appropriate directory, replacing $MYPROJ and $MYAPP with whatever values you like (they can be the same, though if they are the directory structure can end up slightly confusing.
paster create will make two directories named $MYAPP as it is.)
virtualenv --python=python2.5 --no-site-packages --unzip-setuptools $MYPROJ cd $MYPROJ pip install -U -E . pylons touch ./lib/python2.5/site-packages/paste/__init__.py rm -f ./lib/python2.5/site-packages/simplejson*/_speedups* ./bin/paster create -t pylons $MYAPP template_engine=mako sqlalchemy=False
You’ll then need to create
app.py in the current directory. Replace
$REGNAME with the name of your application as registered with Google. For example, if your hosted URL is myapp.appspot.com, the registered name is myapp. And don’t forget to replace
app.py with whatever you gave to
application: $REGNAME version: 1 runtime: python api_version: 1 handlers: - url: /.* script: app.py skip_files: | ^(.*/)?( (bin/.*)| (include/.*)| (.*/docs/.*)| (.*/(ez_)?setup.py)| (.*/(MANIFEST.in|README.txt|setup.cfg))| (lib/python2\.\d/[^/]*\.py)| (lib/python2\.\d/(lib-dynload|config|distutils|encodings)/.*)| (.*\.pth)| (app\.yaml)| (app\.yml)| (index\.yaml)| (index\.yml)| (#.*#)| (.*~)| (.*\.py[co])| (.*/RCS/.*)| (\..*)| )$
import sys import os # Change to the directory name of your app (what you gave to paster create) appdir = '$MYAPP' # Change the version number if necessary libdir = "lib/python2.5/site-packages" # If you used pip, you can shorten this to [appdir, libdir] # The rest is necessary if you used easy_install sys.path = [appdir, libdir] + ['%s/%s' % (libdir, n) for n in os.listdir(libdir) if n.endswith('.egg')] + sys.path # Workaround for latest setuptools importing mkdir os.mkdir = lambda *x:None from paste.deploy import loadapp from google.appengine.ext.webapp.util import run_wsgi_app # To switch between development and deployment versions, # edit this line or have multiple versions of this file run_wsgi_app(loadapp('config:development.ini', relative_to=appdir))
Finally, in your Pylons app’s
environment.py, comment out or delete the line beginning
module_directory= in the instantiation of
TemplateLookup. GAE does not have a writable filesystem, so Mako’s file-based template caching will not work on it. If you are using a different template system, you’ll have to figure out what is required to stop it from trying to write any files.
Python versions other than 2.5
GAE runs Python 2.5. As long as your code runs on 2.5, you can use whatever (2.x) version of Python you want locally. You’ll need to change all instances of
python2.5 in the script above, and also edit the value of
You can run your app locally in a GAE environment using the
Google App Engine SDK/Launcher <http://code.google.com/appengine/downloads.html>_. It’s fairly simple, and documentation is available and beyond the scope of this article, but here are a few tips:
In the GUI version of the SDK/Launcher, be sure to use
File->Add Existing Applicationrather than
File->New Application. The path to use is the directory that contains
Using the command-line version,
dev_appserver.py, don’t run it from within the
virtualenv; it won’t be able to find the Google libraries.
The SDK/Launcher has a primitive (compared to
paster serve) reloading capability. In order to force an “automatic” reload while your app is running, you’ll need to edit (or
There are two ways to deploy your application: the Google App Engine SDK/Launcher application, or the
appcfg.py command-line script.
The SDK/Launcher application gives you a nice push-button GUI, while
appcfg.py is more flexible with various options such as verbose mode (
-v), which prints a list of which files are being uploaded, and which are being skipped.
When I deployed a barebones Pylons app in this way, with the included
skip_list, the file count came out to 821 using
pip and 814 using
easy_install, both, well under the 3,000-file limit. Your “base” file count will probably vary slightly as new library versions come out.
If you are using
easy_install (but apparently not if you are using
pip), you can reduce the file count by excluding EGG-INFO directories from being uploaded. This will probably not break anything (but see below), unless part of your code depends on entry points of modules other than your app. You’ll need to add a line to the middle of the
skip_list regex in your
app.yaml, as follows:
For me, this reduced the “base” file count to 691, a savings of about 120 files. Unfortunately, excluding
.egg-info directories when using
pip breaks the setup.
If you do this, you must also add
template_engine=None as a keyword argument to the
config.init_app function call in your Pylons app’s
environment.py. Otherwise, some legacy code in Pylons (supporting the outdated Buffet template system) will break because it can’t find some egg info.
Notes on workarounds, for the curious
GAE does not appear to use
.pthfiles, which are files that are placed on the Python path and contain additions to the path. This is why
sys.pathmust be set up in
easy_install.pthfile to make sure only the latest installed version of each package is on the path. This is why you have to manually delete duplicate packages using this GAE method.
app.pyhas a rather odd line:
os.mkdir = lambda *x:None. The latest version of
setuptools(as of 0.6c11) attempts to import
mkdirdoes not exist on GAE. This monkey-patch allows
setuptoolsto be imported.
skip_listthat prevents files that are part of the
virtualenvbut useless on GAE, such as binary shared objects, from being uploaded.
The “speedups” part of
_speedups.so) uses a C extension, which is not supported by GAE. But the package is set up so that it will still work if these files are missing.
Paste uses a wonky system to allow separate packages (Paste, Paste Deploy, Paste Script) to inhabit the same
pastenamespace. When installed using
pip, this system is dependent on several
.pthfiles, which don’t work on GAE. But sticking an
__init__.pyin makes it work normally.
At this point, you should be up and running and see the Pylons welcome page when you visit your local server run by the SDK. There are still more steps to a real GAE app, of course, such as familiarizing yourself with Google’s datastore models.
I can’t provide “support” on any of this, per se, but if the steps here don’t work for you, please e-mail me and I’ll try to correct or amend the article.