Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

38

Transcript of Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

Page 1: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.
Page 2: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

Googe App Engine CodelabMarzia NiccolaiMay 28-29, 2008

Page 3: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

3

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/googleappengineoWindows InstalleroMac App Engine LauncheroZip Archive

Page 4: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

4

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

Page 5: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

5

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

Page 6: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

6

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

Page 7: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

7

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

Page 8: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

8

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

Page 9: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

9

Defining the Wiki Modelfrom google.appengine.ext import db

class WikiPage(db.Model):  title = db.StringProperty()  body = db.TextProperty()

Page 10: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

10

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()

Page 11: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

11

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

Page 12: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

12

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

Page 13: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

13

Sample GQL QueriesSELECT * 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

Page 14: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

14

Codelab: Building our wiki

• Allow our users to:o View Wiki pageso Edit Wiki pages

Page 15: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

15

app.yaml - Describing our App

• The app.yaml specifies the application configuration for Google App Engine

• Specify the application name and version:

application: wikiversion: 1

Page 16: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

16

Wiki’s app.yaml

• Specify the application’s script handlers:

handlers:- url: /.* script: main.py

Page 17: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

17

app.yaml: complete

application: wikiversion: 1runtime: pythonapi_version: 1

handlers:- url: .* script: main.py

Page 18: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

18

WebApp Framework

• WSGI framework for handling requests• Uses Request Handlers classes to serve

pages• Returns entire output when handler exits

(no streaming)

Page 19: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

19

Wiki Page Handlers Requirements

• View Wiki Pages (/view/WikiTopic)o Request page /view/WikiTopico Directs you to the page on WikiTopic

• Add/Edit Wiki Pages (/edit/WikiTopic)o Create pages that don’t existo Edit existing pages

Page 20: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

20

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/WikiPageo Display Content, if it exists!o Allow user to Add or Edit the Page

Page 21: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

21

Define the Edit Handler

• When the user requests /edit/WikiPage:o Give them form with a text box to enter contento Post the form to /save/WikiPage

Page 22: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

22

Define the Save Handler

• When the user posts a request to /save/WikiPage:o Get the body of the requesto Create a data objecto Store the object to the datastoreo Redirect the user to /view/WikiPage

Page 23: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

23

Wiki: Take 1

• http://localhost:8080/

Page 24: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

24

Wiki: Take 1 Issues

• We do no processing on the form input, and do no formatting

• We are ignoring the Wiki author!

Page 25: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

25

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

Page 26: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

26

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

Page 27: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

27

Wiki Take 2 in Action

• http://localhost:8080

Page 28: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

28

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

Page 29: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

29

Reference Properties

• Enable 1:many, many:many entity relationships

• Allows entity to store a reference to another entity

Page 30: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

30

Using ReferencePropertyclass Story(db.Model):  story_text = db.TextProperty()

class Comment(db.Model):  story = db.ReferenceProperty(Story)  comment_text = db.TextProperty()  user = db.UserProperty()

Page 31: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

31

Retrieve a Reference Propertya_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)

Page 32: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

32

Back Referencesa_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) )

Page 33: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

33

ReferenceProperty & the Wiki

• New object model for wiki take 3class WikiUser(db.Model)• Store user information in an entityclass WikiContent(db.Model)• Creates the parent wiki pageclass WikiRevision(db.Model)• Stores each revision of the Wiki Page

Page 34: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

34

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()

Page 35: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

35

Wiki Page

class WikiContent(db.Model):  title = db.StringProperty()

Page 36: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

36

Wiki Revisionclass 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()

Page 37: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.

37

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

Page 38: Googe App Engine Codelab Marzia Niccolai May 28-29, 2008.