SlideShare a Scribd company logo
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, 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
Outline
● Some background + DEMO!
● Building the app
○ Defining the data
○ Writing the server-side code
● Deployment + Conclusion
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 type="text" name="summary" value="" />
Description: <textarea name="body" rows="5"></textarea>
<input type="submit" value="Add Task" />
</form>
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>
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
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
Defining and
Manipulating Data
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()
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()
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
Writing the
/index.html Handler
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)
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)
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",
}
]
}
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>
...
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>
...
Writing the
/create.html Handler
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')
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('/')
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)
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": ...,
}
}
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>
Deployment and
Wrapping Up
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
Questions?

More Related Content

PDF
Developing iOS REST Applications
PDF
Demo how to create visualforce and apex controller to update, delete custom o...
PDF
Parse London Meetup - Cloud Code Tips & Tricks
PDF
Learning React: Facebook's Javascript Library For Building User Interfaces
PDF
MVS: An angular MVC
PDF
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
PDF
Firebase for Apple Developers
PDF
JavaScript - Chapter 11 - Events
Developing iOS REST Applications
Demo how to create visualforce and apex controller to update, delete custom o...
Parse London Meetup - Cloud Code Tips & Tricks
Learning React: Facebook's Javascript Library For Building User Interfaces
MVS: An angular MVC
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
Firebase for Apple Developers
JavaScript - Chapter 11 - Events

What's hot (20)

PPT
Backbone.js
PPTX
ReactJs presentation
PDF
VMWorld 2017 Hackathon training: Getting Started with Clarity
PDF
Grails Launchpad - From Ground Zero to Orbit
PDF
Advanced redux
PPTX
J Query Presentation of David
PPTX
Introduction to modern front-end with Vue.js
PPTX
The Many Ways to Build Modular JavaScript
PDF
Crossing platforms with JavaScript & React
PDF
Mini Curso de Django
PDF
Grails Simple Login
PPTX
Better web apps with React and Redux
PDF
Unobtrusive JavaScript
ODP
PPTX
Getting started with ReactJS
PDF
Switch to React.js from AngularJS developer
PPTX
A (very) opinionated guide to MSBuild and Project Files
PDF
PWA 與 Service Worker
PPT
jQuery for beginners
PDF
Future of Web Apps: Google Gears
Backbone.js
ReactJs presentation
VMWorld 2017 Hackathon training: Getting Started with Clarity
Grails Launchpad - From Ground Zero to Orbit
Advanced redux
J Query Presentation of David
Introduction to modern front-end with Vue.js
The Many Ways to Build Modular JavaScript
Crossing platforms with JavaScript & React
Mini Curso de Django
Grails Simple Login
Better web apps with React and Redux
Unobtrusive JavaScript
Getting started with ReactJS
Switch to React.js from AngularJS developer
A (very) opinionated guide to MSBuild and Project Files
PWA 與 Service Worker
jQuery for beginners
Future of Web Apps: Google Gears
Ad

Similar to A To-do Web App on Google App Engine (20)

PPTX
PDF
Tech night ldn - chatbot
PDF
Using Google App Engine 1st Edition Charles Severance
PDF
Webapp2 2.2
PPTX
Python Code Camp for Professionals 1/4
PDF
Web Development with Python and Django
ODP
Why Python Web Frameworks Are Changing the Web
PDF
Using Google App Engine 1st Edition Charles Severance
PDF
OSCON Google App Engine Codelab - July 2010
PDF
How I Built Bill, the AI-Powered Chatbot That Reads Our Docs for Fun , by Tod...
PDF
TurboGears2 Pluggable Applications
PDF
django_introduction20141030
PDF
Using Google App Engine 1st Edition Charles Severance 2024 scribd download
POT
Web Techology and google code sh (2014_10_10 08_57_30 utc)
PDF
Django - basics
PDF
Google app-engine-with-python
PPTX
individuals thought of as a group because
PPTX
Googleappengineintro 110410190620-phpapp01
PDF
Web develop in flask
PDF
Flask intro - ROSEdu web workshops
Tech night ldn - chatbot
Using Google App Engine 1st Edition Charles Severance
Webapp2 2.2
Python Code Camp for Professionals 1/4
Web Development with Python and Django
Why Python Web Frameworks Are Changing the Web
Using Google App Engine 1st Edition Charles Severance
OSCON Google App Engine Codelab - July 2010
How I Built Bill, the AI-Powered Chatbot That Reads Our Docs for Fun , by Tod...
TurboGears2 Pluggable Applications
django_introduction20141030
Using Google App Engine 1st Edition Charles Severance 2024 scribd download
Web Techology and google code sh (2014_10_10 08_57_30 utc)
Django - basics
Google app-engine-with-python
individuals thought of as a group because
Googleappengineintro 110410190620-phpapp01
Web develop in flask
Flask intro - ROSEdu web workshops
Ad

Recently uploaded (20)

PPT
Teaching material agriculture food technology
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
sap open course for s4hana steps from ECC to s4
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Empathic Computing: Creating Shared Understanding
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Teaching material agriculture food technology
Advanced methodologies resolving dimensionality complications for autism neur...
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Unlocking AI with Model Context Protocol (MCP)
Understanding_Digital_Forensics_Presentation.pptx
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
NewMind AI Weekly Chronicles - August'25 Week I
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
sap open course for s4hana steps from ECC to s4
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Programs and apps: productivity, graphics, security and other tools
Empathic Computing: Creating Shared Understanding
Mobile App Security Testing_ A Comprehensive Guide.pdf
Reach Out and Touch Someone: Haptics and Empathic Computing
Network Security Unit 5.pdf for BCA BBA.
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...

A To-do Web App on Google App Engine

  • 1. CS4HS Using Google App Engine Michael Parker (michael.g.parker@gmail.com)
  • 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. Outline ● Some background + DEMO! ● Building the app ○ Defining the data ○ Writing the server-side code ● Deployment + Conclusion
  • 4. The Demo and Some Other Stuff Go to http://cs4hs-tasklist.appspot.com
  • 5. Start with a mock-up
  • 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. 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. 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. 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
  • 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. 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. 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
  • 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. 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. 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. 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. 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> ...
  • 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. 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. 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. 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. 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>
  • 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