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