380 likes | 490 Views
This guide walks you through building a simple wiki using Google App Engine. You will learn how to set up the App Engine SDK, define wiki data models, and manage content creation, editing, and storage. The tutorial covers querying data with GQL, managing users, and adding advanced features like revisions and authorship. By the end, you'll have a functioning wiki application, complete with user interactions and a robust backend data structure. The codelab provides all necessary resources and links for a seamless learning experience.
E N D
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 • Windows Installer • Mac App Engine Launcher • Zip Archive
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
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
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
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/typesandpropertyclasses.html
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
Defining the Wiki Model from google.appengine.ext import db class WikiPage(db.Model): title = db.StringProperty() body = db.TextProperty()
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()
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
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
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
Codelab: Building our wiki • Allow our users to: • View Wiki pages • Edit Wiki pages
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
Wiki’s app.yaml • Specify the application’s script handlers: handlers: - url: /.* script: main.py
app.yaml: complete application: wiki version: 1 runtime: python api_version: 1 handlers: - url: .* script: main.py
WebApp Framework • WSGI framework for handling requests • Uses Request Handlers classes to serve pages • Returns entire output when handler exits (no streaming)
Wiki Page Handlers Requirements • View Wiki Pages (/view/WikiTopic) • Request page /view/WikiTopic • Directs you to the page on WikiTopic • Add/Edit Wiki Pages (/edit/WikiTopic) • Create pages that don’t exist • Edit existing pages
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 • Display Content, if it exists! • Allow user to Add or Edit the Page
Define the Edit Handler • When the user requests /edit/WikiPage: • Give them form with a text box to enter content • Post the form to /save/WikiPage
Define the Save Handler • When the user posts a request to /save/WikiPage: • Get the body of the request • Create a data object • Store the object to the datastore • Redirect the user to /view/WikiPage
Wiki: Take 1 • http://localhost:8080/
Wiki: Take 1 Issues • We do no processing on the form input, and do no formatting • We are ignoring the Wiki author!
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
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
Wiki Take 2 in Action • http://localhost:8080
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
Reference Properties • Enable 1:many, many:many entity relationships • Allows entity to store a reference to another entity
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()
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)
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) )
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
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()
Wiki Page class WikiContent(db.Model): title = db.StringProperty()
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()
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