Python and Google App Engine
Python and Google App Engine
and
Google App Engine
Dan Sanderson
June 14, 2012
Agenda
Development environment
Tools and IDEs
Unit testing
Remote access
(more more more!)
Thursday, June 14, 12
Demo
Development
Environment
Make your computer look like AE.
Development
Environment
Make your computer look like AE.
Development
Environment
Python 2.7
App Engine SDK (development server)
Optional packages
virtualenv and pip
Thursday, June 14, 12
Python 2.7
python.org
2.7.x, not 3.x
Interpreter, standard library
(App Engine sandbox)
Thursday, June 14, 12
Python 2.7
Windows
Python 2.7.3 Windows (X86-64) Installer
C:\Python27\
python -V
Thursday, June 14, 12
Python 2.7
Mac OS X
10.7 Lion: you already have it
python -V
Python 2.7.3 Mac OS X installers
Homebrew (mxcl.github.com/homebrew)
Thursday, June 14, 12
Python 2.7
Linux
You probably have it.
python -V
Ubuntu Precise: python 2.7.3
sudo apt-get install python
Thursday, June 14, 12
Windows:
GoogleAppEngine-1.6.6.msi
Mac OS X:
GoogleAppEngineLauncher-1.6.6.dmg
Linux:
google_appengine_1.6.6.zip
Optional Packages
app.yaml:
application: myapp
version: 1
runtime: python27
api_version: 1
threadsafe: true
# ...
libraries:
- name: django
version: 1.3
- name: jinja2
version: 2.6
- name: markupsafe
version: 0.15
Optional Packages
Django
Jinja2, markupsafe
lxml
numpy
PIL
pycrypto
webapp2*
webob
yaml
Optional Packages
AE live environment:
AE modules + sandbox + AEs Python +
requested libraries
virtualenv
Create virtual Python environments, each
with its own set of packages
virtualenv
virtualenv (once):
Install
sudo easy_install virtualenv
virtualenv myapp_env
the environment:
Activate
source ./myapp_env/bin/activate
pip
Python package installation manager
Like easy_install but better
Python Package Index (PyPI):
pypi.python.org
pip
pip (once):
Install
sudo easy_install pip
install a package from PyPI:
To
pip install jinja2
install a specific version:
To
pip install jinja2==2.6
pip
file:
Requirements
pip install -r requirements.txt
app.yaml:
requirements.txt:
libraries:
- name: django
version: 1.3
- name: jinja2
version: 2.6
- name: markupsafe
version: 0.15
django==1.3
jinja2==2.6
markupsafe==0.15
virtualenv myapp_env
source ./myapp_env/bin/activate
pip install -r requirements.txt
django==1.3
jinja2==2.6
lxml==2.3
markupsafe==0.15
numpy==1.6.1
pycrypto==2.3
PyYAML==3.10
webapp2==2.5.1
webob==1.1.1
PIL==1.1.7
dev_appserver.py
dev_appserver.py appdir
Runs a local web server
Watches your files for changes, re-imports modules
Simulates runtime environment and services locally
Development Server
Console
localhost:8080/_ah/admin
Web UI to inspect and manipulate the
development environment
appcfg.py
appcfg.py
Use --oauth2
Use two-factor authentication
For tools that dont support OAuth
JetBrains PyCharm
jetbrains.com/pycharm
JetBrains PyCharm
JetBrains PyCharm
JetBrains PyCharm
Aptana PyDev
Aptana PyDev
Unit Testing
Unit Testing
Its just Python, right?
Activate your virtualenv
Make sure google_appengine and your apps
root dir are in PYTHONPATH
Unit Testing
% source ./myapp_env/bin/activate
(myapp_env)% export PYTHONPATH=$PYTHONPATH:/
Users/dan/google_appengine
(myapp_env)% python
>>> from google.appengine.ext import db
>>> import models
>>> m = models.Entry()
>>> m.title = Test
>>> m.put()
# (in theory)
>>>
Unit Testing
>>> from google.appengine.api import mail
>>> mail.send_mail([email protected]', [email protected]',
subj, body)
...
AssertionError: No api proxy found for service
mail
>>>
testbed
google.appengine.ext.testbed
testbed
>>>
>>>
>>>
>>>
testbed
>>> tb.activate()
>>> tb.init_mail_stub()
>>> from google.appengine.api import mail
>>> mail.send_mail([email protected]', [email protected]',
subj, body)
# (success!)
>>> tb.get_stub(testbed.MAIL_SERVICE_NAME)
.get_sent_messages([email protected]')
[<google.appengine.api.mail.EmailMessage
object at 0x10b5115d0>]
>>>
testbed
import unittest
from google.appengine.ext import testbed
import models
class EntryTestBase(unittest.TestCase):
def setUp(self):
self.tb = testbed.Testbed()
self.tb.activate()
self.tb.init_datastore_v3_stub()
def tearDown(self):
self.tb.deactivate()
testbed
class EntryTestBase(unittest.TestCase):
# ...
def testEntry(self):
m = models.Entry()
m.title = Test
m.put()
self.assertIsNotNone(m.create_date)
if __name__ == __main__:
unittest.main()
testbed
tb.init_all_stubs()
tb.init_blobstore_stub()
tb.init_datastore_v3_stub()
tb.init_memcache_stub()
tb.init_images_stub()
tb.init_mail_stub()
tb.init_taskqueue_stub()
tb.init_urlfetch_stub()
tb.init_user_stub()
tb.init_xmpp_stub()
developers.google.com/appengine/docs/python/tools/
localunittesting
Thursday, June 14, 12
Unit Testing
>>> import webob
>>> import blog
>>> h = blog.FrontPageHandler()
>>> h.request = webob.Request.blank(/)
>>> h.get()
# (assuming testbed is set up as needed)
>>> h.response.status
200 OK
>>>
WebTest
Test helper for WSGI applications, wraps
WebTest
import unittest
import webtest
import blog
class BlogTest(unittest.TestCase):
def setUp(self):
# (testbed init goes here...)
self.testapp = webtest.TestApp(
blob.application)
WebTest
class BlogTest(unittest.TestCase):
# ...
def testFrontPage(self):
response = self.testapp.get(/)
self.assertEqual(200, response.status_int)
# ...
webtest.pythonpaste.org
www.webob.org
Remote Access
Remote Access
Service API stubs: live site, development
server, testbed
Remote Access
Activate the remote_api builtin
(/_ah/remote_api) in app.yaml:
builtins:
- remote_api: on
remote_api_shell.py appid
(Does not support OAuth, must use appspecific password: google.com/settings)
Remote Access
% cd ae-book
% remote_api_shell.py ae-book
Email: ...
Password: ...
App Engine remote_api shell
Python 2.7.1 ...
s~ae-book> import models
s~ae-book> m = models.Entry.all().fetch(3)
s~ae-book> m[2].title
uCode Samples Are Coming
Remote Access
#!/usr/bin/python
from google.appengine.ext.remote_api import \
remote_api_stub
def auth_func():
# prompt for email address and password
return email_address, password
remote_api_stub.ConfigureRemoteApi(
appid, /_ah/remote_api, auth_func)
remote_api_stub.MaybeInvokeAuthentication()
Review
Development environment
Review
Unit testing
WebTest
PyCharm code coverage
Remote access
testbed
Remote shell
Remote access from a script
developers.google.com/
appengine
appengine.google.com
ae-book.appspot.com
Programming Google App
Engine, 2nd ed.
Summer 2012
Dan Sanderson
profiles.google.com/
dan.sanderson