google app engine in 40 minutes (the absolute essentials)

76

Upload: python-ireland

Post on 19-May-2015

542 views

Category:

Technology


0 download

DESCRIPTION

This talk covers just the stuff needed to get you up-to-speed with Google App Engine and its associated technologies (based on the Python run-time, of course). In addition to a bit of talking, Paul will also demo a working webapp built and deployed on the App Engine cloud... all in 40 minutes.

TRANSCRIPT

Page 1: Google App Engine in 40 minutes (the absolute essentials)
Page 2: Google App Engine in 40 minutes (the absolute essentials)

2

Google App Engine in 40 Minutes

(The Absolute Essentials)

Paul Barry – Institute of Technology, Carlow in Ireland

PyCon Ireland 2011

Page 3: Google App Engine in 40 minutes (the absolute essentials)

Grab the slides:

http://paulbarry.itcarlow.ie/GAE.pdf

Page 4: Google App Engine in 40 minutes (the absolute essentials)

4

Page 5: Google App Engine in 40 minutes (the absolute essentials)

5

Page 6: Google App Engine in 40 minutes (the absolute essentials)

6

The Absolute Essentials in 40 Minutes...

Page 7: Google App Engine in 40 minutes (the absolute essentials)

7

What is Google App Engine?

Page 8: Google App Engine in 40 minutes (the absolute essentials)

8

Cloud-based Application Deployment Environment

Page 9: Google App Engine in 40 minutes (the absolute essentials)

9

Integrated Collection of Google APIs

Page 10: Google App Engine in 40 minutes (the absolute essentials)

10

Guido's Playground

Page 11: Google App Engine in 40 minutes (the absolute essentials)

11

Is App Engine “just another framework”?

Page 12: Google App Engine in 40 minutes (the absolute essentials)

12

It is all about your data...

Page 13: Google App Engine in 40 minutes (the absolute essentials)

13

Think of App Engine as a highly scalable,distributed database server that you can program

with Python 2.5...

Page 14: Google App Engine in 40 minutes (the absolute essentials)

14

Think of App Engine as a highly scalable,distributed database server that you can program

with Python 2.5...

and (cough) Java and (cough, cough) Go

Page 15: Google App Engine in 40 minutes (the absolute essentials)

15

MVC

Page 16: Google App Engine in 40 minutes (the absolute essentials)

16

Let's solve a real problem...

Page 17: Google App Engine in 40 minutes (the absolute essentials)

17

Page 18: Google App Engine in 40 minutes (the absolute essentials)

18

Page 19: Google App Engine in 40 minutes (the absolute essentials)

19

Page 20: Google App Engine in 40 minutes (the absolute essentials)

20

Page 21: Google App Engine in 40 minutes (the absolute essentials)

21

Step 1

Download the SDK from:

http://code.google.com/appengine/

and sign-up for an App Engine account ID

Page 22: Google App Engine in 40 minutes (the absolute essentials)

22

Step 2

Create a new project...

Page 23: Google App Engine in 40 minutes (the absolute essentials)

23

...by creating an app.yaml file

application: dwwgapp version: 1 runtime: python api_version: 1

handlers: - url: /static static_dir: static

- url: /.* script: dwwgapp.py

Page 24: Google App Engine in 40 minutes (the absolute essentials)

24

Step 3

Model Your Data

Page 25: Google App Engine in 40 minutes (the absolute essentials)

25

Create dwwgDB.py (1 of 3)

from google.appengine.ext import db

Page 26: Google App Engine in 40 minutes (the absolute essentials)

26

Create dwwgDB.py (2 of 3)

from google.appengine.ext import db

class Sighting(db.Model):

Page 27: Google App Engine in 40 minutes (the absolute essentials)

27

Page 28: Google App Engine in 40 minutes (the absolute essentials)

28

Create dwwgDB.py (3 of 3)

from google.appengine.ext import db

class Sighting(db.Model):name = db.StringProperty()email = db.StringProperty()date = db.DateProperty()time = db.TimeProperty()location = db.StringProperty()fin_type = db.StringProperty()whale_type = db.StringProperty()blow_type = db.StringProperty()wave_type = db.StringProperty()

Page 29: Google App Engine in 40 minutes (the absolute essentials)

29

Step 4

Define your UI in HTML

Page 30: Google App Engine in 40 minutes (the absolute essentials)

30

The header.html template

<html> <head>

<title>{{ title }}</title> </head> <body>

<h1>{{ title }}</h1>

Page 31: Google App Engine in 40 minutes (the absolute essentials)

31

The footer.html template

<p> {{ links }} </p> </body>

</html>

Page 32: Google App Engine in 40 minutes (the absolute essentials)

32

The form_start.html template

<form method=”POST” action=”/”> <table>

Page 33: Google App Engine in 40 minutes (the absolute essentials)

33

The form_end.html

<tr><th>&nbsp;</th><td><input type="submit"

value="{{ sub_title }}"></td></tr>

</table> </form>

Page 34: Google App Engine in 40 minutes (the absolute essentials)

34

Render some HTML

from google.appengine.ext.webapp import template

html = template.render('templates/header.html', {'title': 'Report a Possible Sighting'})

Page 35: Google App Engine in 40 minutes (the absolute essentials)

35

Rendering a Page

from google.appengine.ext.webapp import template

html = template.render('templates/header.html',{'title': 'Report a Possible Sighting'})

html = html + template.render('templates/form_start.html', {})

# Do something in here to render the form?!?!?!?!?!?!?

html = html + template.render('templates/form_end.html',{'sub_title': 'Submit Sighting'})

html = html + template.render('templates/footer.html', {'links': ''})

Page 36: Google App Engine in 40 minutes (the absolute essentials)

36

Step 5

Write code to render your form

Page 37: Google App Engine in 40 minutes (the absolute essentials)

37

Django Forms to the Rescue!

from google.appengine.ext.db import djangoforms

import dwwgDB

class SightingForm(djangoforms.ModelForm):class Meta:

model = dwwgDB.Sighting

Page 38: Google App Engine in 40 minutes (the absolute essentials)

38

Rendering a Page, Again

from google.appengine.ext.webapp import template

html = template.render('templates/header.html',{'title': 'Report a Possible Sighting'})

html = html + template.render('templates/form_start.html', {})

html = html + str(SightingForm())

html = html + template.render('templates/form_end.html',{'sub_title': 'Submit Sighting'})

html = html + template.render('templates/footer.html', {'links': ''})

Page 39: Google App Engine in 40 minutes (the absolute essentials)

39

Step 6

Tie it all together with logic

Page 40: Google App Engine in 40 minutes (the absolute essentials)

40

You need to start your webapp

from google.appengine.ext import webappfrom google.appengine.ext.webapp.util import run_wsgi_app

app = webapp.WSGIApplication([('/.*', SightingInputPage)], debug=True)

def main(): run_wsgi_app(app)

if __name__ == '__main__': main()

Page 41: Google App Engine in 40 minutes (the absolute essentials)

41

Remember the app.yaml file?

application: dwwgapp version: 1 runtime: python api_version: 1

handlers: - url: /static static_dir: static

- url: /.* script: dwwgapp.py

Page 42: Google App Engine in 40 minutes (the absolute essentials)

42

Put this code in dwwgapp.py

from google.appengine.ext import webappfrom google.appengine.ext.webapp.util import run_wsgi_app

app = webapp.WSGIApplication([('/.*', SightingInputPage)], debug=True)

def main(): run_wsgi_app(app)

if __name__ == '__main__': main()

Page 43: Google App Engine in 40 minutes (the absolute essentials)

43

What's this SightingInputPage thing?

Page 44: Google App Engine in 40 minutes (the absolute essentials)

44

class SightingInputPage(webapp.RequestHandler): def get(self): html = template.render('templates/header.html',

{'title': 'Report a Possible Sighting'}) html = html + template.render('templates/form_start.html', {}) html = html + str(SightingForm()) html = html + template.render('templates/form_end.html',

{'sub_title': 'Submit Sighting'}) html = html + template.render('templates/footer.html', {'links': ''}) self.response.out.write(html)

Responding to a GET Request

Page 45: Google App Engine in 40 minutes (the absolute essentials)

45

Step 7

Take your local app for a spin

Page 46: Google App Engine in 40 minutes (the absolute essentials)

46

Click the “Run” button...

or

$ dev_appserver.py dwwgapp

Page 47: Google App Engine in 40 minutes (the absolute essentials)

47

Ta Da! :-(

Page 48: Google App Engine in 40 minutes (the absolute essentials)

48

Looks kinda shitty, doesn't it?

Page 49: Google App Engine in 40 minutes (the absolute essentials)

49

Add a little CSS goodness..

<link type="text/css" rel="stylesheet" href="/static/dwwg.css" /><link type="text/css" rel="stylesheet" href="/static/styledform.css" />

Page 50: Google App Engine in 40 minutes (the absolute essentials)

50

...and some code to dwwgDB.py

_FINS = ['Falcate', 'Triangular', 'Rounded'] _WHALES = ['Humpback', 'Orca', 'Blue', 'Killer', 'Beluga', 'Fin', 'Gray', 'Sperm'] _BLOWS = ['Tall', 'Bushy', 'Dense'] _WAVES = ['Flat', 'Small', 'Moderate', 'Large', 'Breaking', 'High']

...

location = db.StringProperty(multiline=True)fin_type = db.StringProperty(choices=_FINS) whale_type = db.StringProperty(choices=_WHALES) blow_type = db.StringProperty(choices=_BLOWS) wave_type = db.StringProperty(choices=_WAVES)

Page 51: Google App Engine in 40 minutes (the absolute essentials)

51

Ta Da! :-)

Page 52: Google App Engine in 40 minutes (the absolute essentials)

52

Step 8

Do something with your data

Page 53: Google App Engine in 40 minutes (the absolute essentials)

53

You need to POST data!

POST data with put()

Page 54: Google App Engine in 40 minutes (the absolute essentials)

54

class SightingInputPage(webapp.RequestHandler): def get(self): html = template.render('templates/header.html',

{'title': 'Report a Possible Sighting'}) html = html + template.render('templates/form_start.html', {}) html = html + str(SightingForm()) html = html + template.render('templates/form_end.html',

{'sub_title': 'Submit Sighting'}) html = html + template.render('templates/footer.html', {'links': ''}) self.response.out.write(html)

Page 55: Google App Engine in 40 minutes (the absolute essentials)

55

class SightingInputPage(webapp.RequestHandler): def get(self): html = template.render('templates/header.html',

{'title': 'Report a Possible Sighting'}) html = html + template.render('templates/form_start.html', {}) html = html + str(SightingForm()) html = html + template.render('templates/form_end.html',

{'sub_title': 'Submit Sighting'}) html = html + template.render('templates/footer.html', {'links': ''}) self.response.out.write(html)

def post(self):

Page 56: Google App Engine in 40 minutes (the absolute essentials)

56

class SightingInputPage(webapp.RequestHandler): def get(self): html = template.render('templates/header.html',

{'title': 'Report a Possible Sighting'}) html = html + template.render('templates/form_start.html', {}) html = html + str(SightingForm()) html = html + template.render('templates/form_end.html',

{'sub_title': 'Submit Sighting'}) html = html + template.render('templates/footer.html', {'links': ''}) self.response.out.write(html)

def post(self): new_sighting = dwwgDB.Sighting()

Page 57: Google App Engine in 40 minutes (the absolute essentials)

57

class SightingInputPage(webapp.RequestHandler): def get(self): html = template.render('templates/header.html',

{'title': 'Report a Possible Sighting'}) html = html + template.render('templates/form_start.html', {}) html = html + str(SightingForm()) html = html + template.render('templates/form_end.html',

{'sub_title': 'Submit Sighting'}) html = html + template.render('templates/footer.html', {'links': ''}) self.response.out.write(html)

def post(self): new_sighting = dwwgDB.Sighting() new_sighting.name = self.request.get('name') new_sighting.email = self.request.get('email') new_sighting.date = self.request.get('date') new_sighting.time = self.request.get('time') new_sighting.location = self.request.get('location') new_sighting.fin_type = self.request.get('fin_type') new_sighting.whale_type = self.request.get('whale_type') new_sighting.blow_type =self.request.get('blow_type') new_sighting.wave_type = self.request.get('wave_type')

Page 58: Google App Engine in 40 minutes (the absolute essentials)

58

class SightingInputPage(webapp.RequestHandler): def get(self): html = template.render('templates/header.html',

{'title': 'Report a Possible Sighting'}) html = html + template.render('templates/form_start.html', {}) html = html + str(SightingForm()) html = html + template.render('templates/form_end.html',

{'sub_title': 'Submit Sighting'}) html = html + template.render('templates/footer.html', {'links': ''}) self.response.out.write(html)

def post(self): new_sighting = dwwgDB.Sighting() new_sighting.name = self.request.get('name') new_sighting.email = self.request.get('email') new_sighting.date = self.request.get('date') new_sighting.time = self.request.get('time') new_sighting.location = self.request.get('location') new_sighting.fin_type = self.request.get('fin_type') new_sighting.whale_type = self.request.get('whale_type') new_sighting.blow_type =self.request.get('blow_type') new_sighting.wave_type = self.request.get('wave_type')

new_sighting.put()

Page 59: Google App Engine in 40 minutes (the absolute essentials)

59

html = template.render('templates/header.html', {'title': 'Thank you!'}) html = html + "<p>Thank you for providing your sighting data.</p>" html = html + template.render('templates/footer.html', {'links': 'Enter <a href="/">another sighting</a>.'}) self.response.out.write(html)

And don't forget to say “Thanks!”

Page 60: Google App Engine in 40 minutes (the absolute essentials)

60

Page 61: Google App Engine in 40 minutes (the absolute essentials)

61

Step 9

Deploy to Google's cloud

Page 62: Google App Engine in 40 minutes (the absolute essentials)

62

Click the “Deploy” button...

or

$ appcfg.py upload dwwgapp/

Page 63: Google App Engine in 40 minutes (the absolute essentials)

63

http://dwwgapp.appspot.com

Page 64: Google App Engine in 40 minutes (the absolute essentials)

64

Step 10

Realise your not done...

Page 65: Google App Engine in 40 minutes (the absolute essentials)

65

Damn That Spam!

Some smart-alec posted a sightingof a Great White Shark on the top

of Mount Leinster...

Page 66: Google App Engine in 40 minutes (the absolute essentials)

66

What to do?

Page 67: Google App Engine in 40 minutes (the absolute essentials)

67

A tiny config tweak to app.yaml...

application: dwwgapp version: 1 runtime: python api_version: 1

handlers: - url: /static static_dir: static

- url: /.* script: dwwgapp.py login: required

Page 68: Google App Engine in 40 minutes (the absolute essentials)

68

...and two tiny code changes

Add this to the dwwgDB.py model:

which_user = db.UserProperty()

Add this to your post() method in dwwgapp.py:

new_sighting.which_user = users.get_current_user()

Page 69: Google App Engine in 40 minutes (the absolute essentials)

69

http://dwwgapp.appspot.com

Page 70: Google App Engine in 40 minutes (the absolute essentials)

70

http://appengine.google.com

Page 71: Google App Engine in 40 minutes (the absolute essentials)

71

And after all that,what do you end up with?

Page 72: Google App Engine in 40 minutes (the absolute essentials)

72

Happy Clients!

Page 73: Google App Engine in 40 minutes (the absolute essentials)

73

Want to learn moreabout this talk's example code?

Page 74: Google App Engine in 40 minutes (the absolute essentials)

74

Head First Python

Page 75: Google App Engine in 40 minutes (the absolute essentials)

75

Don't forget to check out the App Engine Tutorial on Sunday

with Seán Murphy

Page 76: Google App Engine in 40 minutes (the absolute essentials)

76