Your SlideShare is downloading. ×
0
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Python Ireland Nov 2009 Talk - Appengine
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Python Ireland Nov 2009 Talk - Appengine

546

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
546
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Google App Engine Writing a Stack Overflow clone on App Engine in under an hour* http://blog.bitquabit.com/2009/07/01/one-which-i-call-out-hacker-news/
  • 2. Agenda1. App Engine Introduction2. Demo: Building an app3. Demo: Deploying an app4. Demo: Writing App Overflow5. App Engines Services6. Questions If I say "Cloud" at any point, Boo!
  • 3. App Engineintroduction
  • 4. Building web applications is hard
  • 5. Thinking about scalabilityJust a few users.... ....the tools, platform and design dont matter too much
  • 6. Thinking about scalabilityLots and lots of users... ....you must design for scalability
  • 7. WhiteHouse.gov/openforquestions
  • 8. Serving developers AND their customersGoogle App Engine Scalable High Performance Standards Cost effective
  • 9. The Components
  • 10. 1. Scalable Serving Architecture creative commons licensed photograph from cote
  • 11. 1. Scalable Serving Architecture Incoming Requests App Engine App Engine App Engine Front End Front End Front EndLoad Balancer AppServer AppServer AppServer
  • 12. 1. Scalable Serving Architecture Incoming Requests App Engine App Engine App Engine Front End Front End Front EndLoad Balancer AppServer AppServer AppServer Other Google AppServer Infrastructure API Layer - Bigtable - Google Accounts App App App - Memcache - Image manipulation
  • 13. 2. Distributed DatastoreThe Datastore is... Distributed Transactional Natively Partitioned Hierarchial Wow. That is one big table. Schemaless Based on Bigtable
  • 14. 2. Distributed DatastoreThe Datastore is not... A relational database A SQL engine Just Bigtable Wow. That is one big table.
  • 15. Demo: Writing an app
  • 16. App configurationapplication: appoverflowversion: 1runtime: pythonapi_version: 1handlers:- url: /.* script: /request.py
  • 17. Request handlingclass IndexHandler(webapp.RequestHandler): def render_template(self, name, values): path = os.path.join(os.path.dirname(__file__), templates, name) self.response.out.write(template.render(path, values)) def get(self): self.render_template(index.html, {})application = webapp.WSGIApplication([ (/, IndexHandler),], debug=True)def main(): run_wsgi_app(application)
  • 18. Demo: Deploying an app In 30 seconds or less. Time me!
  • 19. Demo: Writing App Overflow
  • 20. Adding authenticationclass IndexHandler(webapp.RequestHandler): def __init__(self): self.user = users.get_current_user() def render_template(self, name, values): url = self.request.url template_values.update({ user: self.user, login_url:users.create_login_url(url), logout_url:users.create_logout_url(url), }) path = os.path.join(os.path.dirname(__file__), templates, template_name) self.response.out.write(template.render(path, template_values))
  • 21. Adding authentication<html><head> <title>{%block title%}App Overflow{%endblock%}</title> {% block head %}{% endblock %}</head><body> <div class="login"> {% if user %} Logged in as {{user.nickname}} | <a href="{{logout_url}}">Log Out</a> {% else %} <a href="{{login_url}}">Log In</a> {% endif %} </div> {% block body %}{% endblock %}</body></html>
  • 22. Storing datafrom google.appengine.ext import dbclass Question(db.Model): asker = db.UserProperty(required=True) title = db.StringProperty(required=True, indexed=False) body = db.TextProperty(required=True) asked_at = db.DateTimeProperty(auto_now_add=True)
  • 23. Storing dataclass NewQuestionHandler(BaseHandler): def get(self): self.render_form(forms.QuestionForm()) def post(self): form = forms.QuestionForm(self.request.POST) if not form.is_valid(): self.render_form(form) return entity = models.Question( asker=self.user, **form.clean_data) entity.put() self.redirect(/questions/%d/ % (entity.key().id(),))
  • 24. Fetching dataclass QuestionHandler(BaseHandler): def get_question(self, id): question = models.Question.get_by_id(int(id)) return question def render_page(self, question): template_values = { question: question, } self.render_template(question.html, template_values) def get(self, id): question = self.get_question(id) if question: self.render_page(question)
  • 25. Queriesclass IndexHandler(BaseHandler): def get_questions(self): q = models.Question.all() q.order(-asked_at) return q.fetch(20) def render_page(self): template_values = { questions: self.get_questions(), } self.render_template(index.html, template_values) def get(self): self.render_page()
  • 26. Precomputationclass Question(db.Model): asker = db.UserProperty(required=True) title = db.StringProperty(required=True, indexed=False) body = db.TextProperty(required=True) asked_at = db.DateTimeProperty(auto_now_add=True) answer_count = db.IntegerProperty(required=True, default=0)class Answer(db.Model): answerer = db.UserProperty(required=True) body = db.TextProperty(required=True) answered_at = db.DateTimeProperty(auto_now_add=True)
  • 27. Transactionsanswer = models.Answer( parent=question, answerer=self.user, # ...)def save_answer(answer): def _tx(): question = db.get(answer.parent().key()) question.answer_count += 1 db.put([answer, question]) return answer.key() return db.run_in_transaction(_tx)
  • 28. XMPPclass XmppHandler(xmpp_handlers.CommandHandler): def ask_command(self, message=None): question = models.Question( title=message.arg, body=message.arg, sender=message.sender) question.put() message.reply(Your question has been received. You will be pinged when an answeris submitted.)# Elsewhere...xmpp.send_message([question.sender], Answer: + answer.body)
  • 29. Additional services / APIs URL Fetch Memcache Mail - incoming and outgoing Images Google Accounts Cron support Task Queue
  • 30. Questions?

×