CS4HS
Using Google App Engine

Michael Parker
(michael.g.parker@gmail.com)
So what is it?
What's it for?
● Building and running web applications

Why use it?
● Handles serving web pages, efficientl...
Outline
● Some background + DEMO!
● Building the app
○ Defining the data
○ Writing the server-side code
● Deployment + Con...
The Demo and
Some Other Stuff

Go to
http://cs4hs-tasklist.appspot.com
Start with a mock-up
Identify your data (nouns)
Identify your actions (verbs)
The mock-up: creating a task
<h3>Add a new task:</h3>
<form id="new_form" action="create" method="post">
Summary: <input t...
The mock-up: showing/deleting tasks
<h3>Task list for mgp@google.com:</h3>
<form id="delete_form" action="delete" method="...
Anatomy of a web application
Reading data:
1
HTTP GET /index.html
username=user@domain.com

Web
Server

2
Get tasks for
us...
Anatomy of a web application
Modifying data (add, edit, delete):
2
1
HTTP POST /create.html
username=user@domain.com
title...
Defining and
Manipulating Data
Defining your data
Extend db.Model and define properties:
class Task(db.Model):
"""A saved task."""
creator = db.UserPrope...
Inserting new data
Class db.Model provides a put method:
def NewTask(user, summary, body):
"""Creates a new task.
Argument...
Retrieving data
Add identifiers so they can be deleted later:
def GetTasks(user):
"""Returns all tasks created by the give...
Writing the
/index.html Handler
Retrieving tasks
class GetTasksHandler(webapp.RequestHandler):
"""Displays all tasks for the user, and a form to
enter a n...
Retrieving tasks
def write_html(response, template_values={}):
"""Writes the tasks for the user in HTML.
Arguments:
respon...
A look at template_values
{ "user": "mgp@google.com",
"tasks": [
{ "id": "task_id_1",
"summary": "make cs4hs slides",
"bod...
A look at the template
<h3>Task list for {{ user }}:</h3>
<form id="delete_form" action="delete" method="post">
<ul>
{% fo...
The rendered output
<h3>Task list for mgp@google.com:</h3>
<form id="delete_form" action="delete" method="post">
<ul>
<li>...
Writing the
/create.html Handler
Creating tasks
class NewTaskHandler(webapp.RequestHandler):
"""Handler that creates a new task."""
def post(self):
user = ...
Creating tasks with error handling
class NewTaskHandler(webapp.RequestHandler):
"""Handler that creates a new task."""
def...
Creating tasks
...
def handle_error(self, summary, body):
new_task_template_values = {}
new_task_template_values['has_erro...
A look at template_values
{ "user": "mgp@google.com",
"tasks": [
{ "id": "00001",
"summary": "make cs4hs slides",
"body": ...
A look at the template
<h3>Add a new task:</h3>
<form id="new_form" action="new" method="post">
{% if new.has_error %}
<di...
Deployment and
Wrapping Up
Deployment
● Prerequisites:
○ Download the SDK
○ Get the code from https://github.com/mgp/cs4hs-tasklist
○ Import project ...
Questions?
Upcoming SlideShare
Loading in …5
×

A To-do Web App on Google App Engine

667 views

Published on

Presented to high school teachers participating in CS4HS. Covers writing simple to-do web app in Python on Google App Engine. 30 minutes with Q&A.

Demo at http://cs4hs-tasklist.appspot.com/
Source code at https://github.com/mgp/cs4hs-tasklist

Published in: Technology, News & Politics
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
667
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
6
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

A To-do Web App on Google App Engine

  1. 1. CS4HS Using Google App Engine Michael Parker (michael.g.parker@gmail.com)
  2. 2. So what is it? What's it for? ● Building and running web applications Why use it? ● Handles serving web pages, efficiently storing and retrieving lots of data ● Allows authenticating users, sending email and IMs, downloading remote files ● Easy management; don't need to buy or administer servers ● Supports both Python and Java Get the SDK at https://developers.google. com/appengine
  3. 3. Outline ● Some background + DEMO! ● Building the app ○ Defining the data ○ Writing the server-side code ● Deployment + Conclusion
  4. 4. The Demo and Some Other Stuff Go to http://cs4hs-tasklist.appspot.com
  5. 5. Start with a mock-up
  6. 6. Identify your data (nouns)
  7. 7. Identify your actions (verbs)
  8. 8. The mock-up: creating a task <h3>Add a new task:</h3> <form id="new_form" action="create" method="post"> Summary: <input type="text" name="summary" value="" /> Description: <textarea name="body" rows="5"></textarea> <input type="submit" value="Add Task" /> </form>
  9. 9. The mock-up: showing/deleting tasks <h3>Task list for mgp@google.com:</h3> <form id="delete_form" action="delete" method="post"> <ul> <li> <input type="checkbox" name="task_id" value="task_id_1" /> <h4>make cs4hs slides</h4> <div>those will be the slides i'm presenting</div> </li> <li> <input type="checkbox" name="task_id" value="task_id_2" /> <h4>give presentation</h4> <div>hopefully to a thunderous applause</div> </li> </ul> <input type="submit" value="Delete Tasks" /> </form>
  10. 10. Anatomy of a web application Reading data: 1 HTTP GET /index.html username=user@domain.com Web Server 2 Get tasks for user@domain.com /index.html handler 4 <html> ... <li><h3>title1</h3>body1</li> <li><h3>title2</h3>body2</li> ... </html> 3 /create.html handler /delete.html handler task1: (title1, body1) task2: (title2, body2) Storage
  11. 11. Anatomy of a web application Modifying data (add, edit, delete): 2 1 HTTP POST /create.html username=user@domain.com title=title3, body=body3 Web Server /index.html handler Create task for user@domain.com: title=title3, body=body3 3 Get tasks for mgp@google.com 5 <html> ... <li><h3>title1</h3>body1</li> <li><h3>title2</h3>body2</li> <li><h3>title3</h3>body3</li> ... </html> /create.html handler /delete.html handler 4 task1: (title1, body1) task2: (title2, body2) task3: (title3, body3) Storage
  12. 12. Defining and Manipulating Data
  13. 13. Defining your data Extend db.Model and define properties: class Task(db.Model): """A saved task.""" creator = db.UserProperty() summary = db.StringProperty() body = db.TextProperty()
  14. 14. Inserting new data Class db.Model provides a put method: def NewTask(user, summary, body): """Creates a new task. Arguments: user: The user who is creating the task. summary: A summary of the task. body: The full description of the task. """ task = Task() task.creator = user task.summary = summary task.body = body task.put()
  15. 15. Retrieving data Add identifiers so they can be deleted later: def GetTasks(user): """Returns all tasks created by the given user. Arguments: The user to return tasks for. Returns: A list of tasks created by the given user. """ query = db.Query(Task) query.filter('creator =', user) tasks = query.fetch(1000) for task in tasks: task.id = str(task.key()) return tasks
  16. 16. Writing the /index.html Handler
  17. 17. Retrieving tasks class GetTasksHandler(webapp.RequestHandler): """Displays all tasks for the user, and a form to enter a new task. """ def get(self): if users.GetCurrentUser() is None: login_url = users.CreateLoginURL(self.request.uri) self.redirect(login_url) else: write_html(self.response)
  18. 18. Retrieving tasks def write_html(response, template_values={}): """Writes the tasks for the user in HTML. Arguments: response: The connection to the user template_values: Any additional template values to render """ user = users.GetCurrentUser() user_tasks = tasks.GetTasks(user) template_values['user'] = user template_values['tasks'] = user_tasks rendered_page = template.render( _TEMPLATE_PATH, template_values) response.out.write(rendered_page)
  19. 19. A look at template_values { "user": "mgp@google.com", "tasks": [ { "id": "task_id_1", "summary": "make cs4hs slides", "body": "those will be the slides i'm presenting", }, { "id": "task_id_2", "summary": "give presentation", "body": "hopefully to a thunderous applause", } ] }
  20. 20. A look at the template <h3>Task list for {{ user }}:</h3> <form id="delete_form" action="delete" method="post"> <ul> {% for task in tasks %} <li> <input type="checkbox" name="task_id" value="{{ task.id }}" /> <h4>{{ task.summary }}</h4> <div>{{ task.body }}</div> </li> {% endfor %} </ul> ...
  21. 21. The rendered output <h3>Task list for mgp@google.com:</h3> <form id="delete_form" action="delete" method="post"> <ul> <li> <input type="checkbox" name="task_id" value="task_id_1" /> <h4>make cs4hs slides</h4> <div>those will be the slides i'm presenting</div> </li> <li> <input type="checkbox" name="task_id" value="task_id_2" /> <h4>give presentation</h4> <div>hopefully to a thunderous applause</div> </li> </ul> ...
  22. 22. Writing the /create.html Handler
  23. 23. Creating tasks class NewTaskHandler(webapp.RequestHandler): """Handler that creates a new task.""" def post(self): user = users.GetCurrentUser() summary = self.request.get('summary') body = self.request.get('body') tasks.NewTask(user, summary, body) self.redirect('/index.html')
  24. 24. Creating tasks with error handling class NewTaskHandler(webapp.RequestHandler): """Handler that creates a new task.""" def post(self): user = users.GetCurrentUser() summary = self.request.get('summary', None) body = self.request.get('body', None) if not summary or not body: self.handle_error(summary, body) return tasks.NewTask(user, summary, body) self.redirect('/')
  25. 25. Creating tasks ... def handle_error(self, summary, body): new_task_template_values = {} new_task_template_values['has_error'] = True if summary: new_task_template_values['summary'] = summary if body: new_task_template_values['body'] = body template_values = {} template_values['new'] = new_task_template_values write_html(self.response, template_values)
  26. 26. A look at template_values { "user": "mgp@google.com", "tasks": [ { "id": "00001", "summary": "make cs4hs slides", "body": "those will be the slides i'm presenting", }, { "id": "00002", "summary": "give presentation", "body": "hopefully to a thunderous applause", } ], "new": { "has_error": True, "summary": ..., "body": ..., } }
  27. 27. A look at the template <h3>Add a new task:</h3> <form id="new_form" action="new" method="post"> {% if new.has_error %} <div class="error">Please enter both a summary and description below</div> {% endif %} Summary: <input type="text" name="summary" value="{{ new.summary }}" /> Description: <textarea name="body" rows="5">{{ new.body }}</textarea> <input type="submit" value="Add Task" /> </form>
  28. 28. Deployment and Wrapping Up
  29. 29. Deployment ● Prerequisites: ○ Download the SDK ○ Get the code from https://github.com/mgp/cs4hs-tasklist ○ Import project into GoogleAppEngineLauncher ● Running it locally: ○ In GAELauncher, click Run, then Browse ○ Data is stored on your hard drive ○ Can edit the code without restarting the web server ● Deploying it to the web: ○ Register the application name at http://appengine.google. com ○ Change application value in app.yaml to app name ○ In GAELauncher, click Deploy ○ See it at http://app-name.appspot.com
  30. 30. Questions?

×