google app engine in 40 minutes (the absolute essentials)

Post on 19-May-2015

541 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

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

2

Google App Engine in 40 Minutes

(The Absolute Essentials)

Paul Barry – Institute of Technology, Carlow in Ireland

PyCon Ireland 2011

Grab the slides:

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

4

5

6

The Absolute Essentials in 40 Minutes...

7

What is Google App Engine?

8

Cloud-based Application Deployment Environment

9

Integrated Collection of Google APIs

10

Guido's Playground

11

Is App Engine “just another framework”?

12

It is all about your data...

13

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

with Python 2.5...

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

15

MVC

16

Let's solve a real problem...

17

18

19

20

21

Step 1

Download the SDK from:

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

and sign-up for an App Engine account ID

22

Step 2

Create a new project...

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

24

Step 3

Model Your Data

25

Create dwwgDB.py (1 of 3)

from google.appengine.ext import db

26

Create dwwgDB.py (2 of 3)

from google.appengine.ext import db

class Sighting(db.Model):

27

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

29

Step 4

Define your UI in HTML

30

The header.html template

<html> <head>

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

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

31

The footer.html template

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

</html>

32

The form_start.html template

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

33

The form_end.html

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

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

</table> </form>

34

Render some HTML

from google.appengine.ext.webapp import template

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

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': ''})

36

Step 5

Write code to render your form

37

Django Forms to the Rescue!

from google.appengine.ext.db import djangoforms

import dwwgDB

class SightingForm(djangoforms.ModelForm):class Meta:

model = dwwgDB.Sighting

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': ''})

39

Step 6

Tie it all together with logic

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

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

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

43

What's this SightingInputPage thing?

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

45

Step 7

Take your local app for a spin

46

Click the “Run” button...

or

$ dev_appserver.py dwwgapp

47

Ta Da! :-(

48

Looks kinda shitty, doesn't it?

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" />

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)

51

Ta Da! :-)

52

Step 8

Do something with your data

53

You need to POST data!

POST data with put()

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)

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

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

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

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

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!”

60

61

Step 9

Deploy to Google's cloud

62

Click the “Deploy” button...

or

$ appcfg.py upload dwwgapp/

63

http://dwwgapp.appspot.com

64

Step 10

Realise your not done...

65

Damn That Spam!

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

of Mount Leinster...

66

What to do?

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

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

69

http://dwwgapp.appspot.com

70

http://appengine.google.com

71

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

72

Happy Clients!

73

Want to learn moreabout this talk's example code?

74

Head First Python

75

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

with Seán Murphy

76

top related