Transcript Slide 1

Googe App Engine
Codelab
Marzia Niccolai
May 28-29, 2008
Step 1: Download the SDK
• You must have Python 2.5 installed on your computer to use the
App Engine SDK
• http://code.google.com/p/googleappengine
o Windows Installer
o Mac App Engine Launcher
o Zip Archive
3
Building a Wiki
• Today we are going to build a wiki with
Google App Engine
• You can download the code from:
• http://code.google.com/p/google-app-engine-codelab
4
Wiki Content
• Step 1 - Basic Wiki
• Step 2 - Wiki that uses Markup and
displays the author
• Step 3 - Wiki that supports revisions
• Step 4 - Wiki that displays user page
• Step 5 - Wiki that fetches user feeds
During the Codelab, we will be going over
steps 1&2 and building step 3
5
Wiki Data
• To start with, we will have wiki pages with a
title & a text body
• With App Engine you store you data as
objects called entities
• Entities have 1 or more properties of
supported data types
6
Data Types
•
•
•
•
•
•
•
•
•
•
IntegerProperty, FloatProperty, BooleanProperty
StringProperty, TextProperty
DateTimeProperty
ListProperty
ReferenceProperty, SelfReferenceProperty
UserProperty
BlobProperty
LinkProperty, EmailProperty
Other rich properties...
http://code.google.com/appengine/docs/datastore/typesandp
ropertyclasses.html
7
Defining a Model
• Define your data models as a Python class
• To create an entity use the class
constructor
• Call put() on the object to add it to the
datastore
8
Defining the Wiki Model
from google.appengine.ext import db
class WikiPage(db.Model):
title = db.StringProperty()
body = db.TextProperty()
9
Create, Update, Delete
• Once you have a data object (new or
existing), calling put() writes that
object to the datastore
object = WikiPage(title=my_title, body=my_body)
object.put()
• To delete an object from the
datastore, call delete() on the object
# assume we have retrieved object
object.delete()
10
Querying for Data
• Google provides two methods for querying
data
• Today we’ll use GQL, a SQL-like query
language
• We also have a query interface, which you
can read more about at:
• http://code.google.com/appengine/docs
11
GQL
• Google App Engine returns entire entities
based on your queries
• You can filter the data based on equalities
and inequalities
• You can order the data
12
Sample GQL Queries
SELECT * FROM Person WHERE birth_year >= :min
AND birth_year <= :max
SELECT * FROM Person WHERE birth_year >= :min
ORDER BY birth_year, last_name
SELECT * FROM Person WHERE last_name = "Smith"
AND height < 72
ORDER BY height DESC
13
Codelab: Building our wiki
• Allow our users to:
o
o
View Wiki pages
Edit Wiki pages
14
app.yaml - Describing our App
• The app.yaml specifies the application
configuration for Google App Engine
• Specify the application name and version:
application: wiki
version: 1
15
Wiki’s app.yaml
• Specify the application’s script handlers:
handlers:
- url: /.*
script: main.py
16
app.yaml: complete
application: wiki
version: 1
runtime: python
api_version: 1
handlers:
- url: .*
script: main.py
17
WebApp Framework
• WSGI framework for handling requests
• Uses Request Handlers classes to serve
pages
• Returns entire output when handler exits
(no streaming)
18
Wiki Page Handlers Requirements
• View Wiki Pages (/view/WikiTopic)
o
o
Request page /view/WikiTopic
Directs you to the page on WikiTopic
• Add/Edit Wiki Pages (/edit/WikiTopic)
o
o
Create pages that don’t exist
Edit existing pages
19
Define our View Handler
• Redirect request from
http://myapp.apppost.com/ to
http://myapp.appspot.com/view/StartPage
• When you request
http://myapp.appspot.com/view/WikiPage
o Display Content, if it exists!
o Allow user to Add or Edit the Page
20
Define the Edit Handler
• When the user requests /edit/WikiPage:
o
o
Give them form with a text box to enter content
Post the form to /save/WikiPage
21
Define the Save Handler
• When the user posts a request to
/save/WikiPage:
Get the body of the request
Create a data object
o Store the object to the datastore
o Redirect the user to /view/WikiPage
o
o
22
Wiki: Take 1
• http://localhost:8080/
23
Wiki: Take 1 Issues
• We do no processing on the form input,
and do no formatting
• We are ignoring the Wiki author!
24
Wiki Take 2: Processing Form input
• Use the ‘markdown’ third party library to
allow formatting
• Find WikiWords (words that are camel
cased) and replace them with links
25
Wiki Take 2: Authors
• Let people log in and out of our website
• Only allow people who are logged in to edit
pages
• Store the author of the page
26
Wiki Take 2 in Action
• http://localhost:8080
27
Wiki Take 3 - Revisions
• You will be adding revision history
• Each time someone edits the page,
associate that revision as the current
revision of the wiki page
28
Reference Properties
• Enable 1:many, many:many entity
relationships
• Allows entity to store a reference to
another entity
29
Using ReferenceProperty
class Story(db.Model):
story_text = db.TextProperty()
class Comment(db.Model):
story = db.ReferenceProperty(Story)
comment_text = db.TextProperty()
user = db.UserProperty()
30
Retrieve a Reference Property
a_comment = Comment.gql(‘WHERE user = :1’, the_user).get()
self.response.out.write(‘Our user commented on this story: %s’ %
a_comment.story.story_text)
31
Back References
a_story = Story.all().get()
for a_comment in a_story.comment_set():
self.response.out.write(‘by:%s<br />%s<br />’ %
(a_comment.user.nickname, a_comment.comment_text) )
32
ReferenceProperty & the Wiki
• New object model for wiki take 3
class WikiUser(db.Model)
• Store user information in an entity
class WikiContent(db.Model)
• Creates the parent wiki page
class WikiRevision(db.Model)
• Stores each revision of the Wiki Page
33
Wiki User
• In the future we want our wiki page to have
user profiles so we can create a user entity
that stores information about our user:
class WikiUser(db.Model):
wiki_user = db.UserProperty()
joined = db.DateTimeProperty(auto_now_add=True)
wiki_user_picture = db.BlobProperty()
user_feed = db.StringProperty()
34
Wiki Page
class WikiContent(db.Model):
title = db.StringProperty()
35
Wiki Revision
class WikiRevision(db.Model):
wiki_page = db.ReferenceProperty(WikiContent)
revision_body = db.TextProperty(required=True)
author = db.ReferenceProperty(WikiUser)
created = db.DateTimeProperty(auto_now_add=True)
version_number = db.IntegerProperty()
36
Now it’s your turn!
• Using the model defined above, add
support for revisions to our wiki!
• We’ll be walking around to offer assistance
as needed
37