SlideShare une entreprise Scribd logo
1  sur  68
Télécharger pour lire hors ligne
WRITING APPS THE GOOGLE-Y WAY Pamela Fox, YOW! Australia 2010 (Brisbane)
Who am I? twitter.com/pamelafox [email_address] pamelafox.org you get the idea...
Who am I? Google Maps API Google Wave API 2006 2010 2008 Google App Engine
Who am I? wave side projects 92 apps
Who am I? Java pYthon
What is App Engine? ,[object Object],[object Object]
What is a “web app”?
Static vs. Dynamic
Anonymous vs. Users
Intranet vs. Internet ~2 billion Hundreds - Thousands
What is a “web app”?
Some Google web apps
Some Google App Engine web apps www.gifttag.com www.buddypoke.com
Google apps on App Engine panoramio.com pubsubhubbub.appspot.com
How does App Engine work? ,[object Object],[object Object],[object Object]
Demo: Guestbook awesomest-app.appspot.com http://code.google.com/p/google-app-engine-samples/source/browse/trunk/guestbook appengine.google.com localhost build deploy monitor
App Engine architecture
App Engine architecture user task
App Engine architecture
App Engine architecture LIMIT CPU LIMIT Memory LIMIT Time
App Engine architecture hardware ports globals file system Groovy, JRuby, Mirah, Clojure, Scala
App Engine architecture 141,241,791 calls 1 GB data $0.15 GB/month 45,000,000 calls 657,000 -  46,000,000 calls *Always check docs for latest quotas. 192,672,000 calls 558 GB data $0.15 GB/month 7,000 - 1,700,000 calls $0.0001 per mail sent 46,000,000 calls  1,046 GB data sent 100,000 - 20,000,000 calls
The tricky bits
Datastore Entity Properties Key Entity Entity Entity Entity Path Kind Name/ID
Example: Speaker Entities Key Path Kind ID First Name Last Name Speaker1 - Speaker 1 Rod Johnson Key Path Kind ID First Name Last Name Middle Name Suffix Speaker2 - Speaker 2 Guy Steele L Jr.
Modeling Speaker Entities ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Saving Speaker Entities ,[object Object],[object Object],[object Object],[object Object],[object Object]
Updating Speaker Entities ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],LIMIT! (size/# of batch ops)
Queries & Indexes Query Index Index Index Index Query Query Query Query Query
Queries & Indexes SELECT * from Speaker ORDER BY lastname LIMIT! (# of results) key lastname Speaker3 Fox Speaker4 Hohpe Speaker1 Johnson Speaker2 Steele
Queries & Indexes SELECT * from Speaker ORDER by middlename key middlename Speaker2 L
Queries & Indexes SELECT * from Speaker WHERE keynote = True key keynote Speaker1 True Speaker2 True Speaker3 False Speaker4 False
Queries & Indexes SELECT * from Speaker WHERE keynote = False key keynote Speaker1 True Speaker2 True Speaker3 False Speaker4 False
Queries ,[object Object],[object Object],[object Object],[object Object],[object Object],LIMIT! (size of results)
Custom Indexes ,[object Object],[object Object],SELECT * from Speaker ORDER BY lastname, keynote key lastname keynote Speaker3 Fox false Speaker4 Hohpe false Speaker1 Johnson true Speaker2 Steele true
Custom Indexes ,[object Object],[object Object],SELECT * from Speaker WHERE lastname > 'Johnson'  and keynote = true key lastname keynote Speaker3 Fox false Speaker4 Hohpe false Speaker1 Johnson true Speaker2 Steele true
Impossible Indexes SELECT * from Speaker WHERE lastname < 'Steele'  and firstname > 'Gregory' ...not in subsequent rows! key lastname firstname Speaker3 Fox Pamela Speaker4 Hohpe Gregory Speaker1 Johnson Rod Speaker2 Steele Guy
Impossible Indexes SELECT * from Speaker WHERE lastname > 'Fox' ORDER BY firstname  ...not in the correct order! key lastname firstname Speaker3 Fox Pamela Speaker4 Hohpe Gregory Speaker1 Johnson Rod Speaker2 Steele Guy
Queries with Offset ,[object Object],SELECT * from Speaker LIMIT 2 OFFSET 2 1 2 ...slow! LIMIT! (# of offset) key lastname Speaker3 Fox Speaker4 Hohpe Speaker1 Johnson Speaker2 Steele
Queries with Cursors ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
More Properties class Talk(db.Model): title = db.StringProperty(required=True) abstract = db.TextProperty(required=True) speaker = db.ReferenceProperty(Speaker) tags = db.StringListProperty() pamela = Speaker.all().filter('firstname = ', 'Pamela').get() talk = Talk('Writing Apps the Googley Way', 'Bla bla bla', pamela, ['App Engine', 'Python']) talk.put() talk = Talk('Wonders of the Onesie', 'Bluh bluh bluh', pamela, ['Pajamas', 'Onesies']) talk.put()
Back-References pamela = Speaker.all().filter('firstname = ', 'Pamela').get() for talk in pamela.talk_set: print talk.title SELECT * from Talk WHERE speaker = Speaker3 key speaker Talk6 Speaker2 Talk1 Speaker3 Talk2 Speaker3 Talk5 Speaker4
Searching List Properties talks = Talk.all().filter('tags = ', 'python') .fetch(10) SELECT * from Talk WHERE tags = 'Python' LIMIT! (# of index rows) key lastname Talk1 App Engine Talk2 Pajamas Talk1 Python Talk2 Onesies
Update Transactions commit journal apply entities apply indexes A B
Entity Groups pamela = Speaker.all().filter('firstname = ', 'Pamela').get() talk1 = Talk('Writing Apps the Googley Way', 'Bla bla bla', pamela, ['App Engine', 'Python'], parent=pamela) talk2 = Talk('Wonders of the Onesie', 'Bluh bluh bluh', pamela, ['Pajamas', 'Onesies'], parent=pamela) db.put(talk1, talk2) def update_talks(): talk1.title = 'Writing Apps the Microsoft Way' talk2.title = 'Wonders of the Windows' db.put(talk1, talk2) db.run_in_transaction(update_talks)
Common Features
Counters 1 2 3 4 5 people have done something.
RageTube: Global Stats ragetube.net http://github.com/pamelafox/ragetube
RageTube: Global Stats SongStat yaycount viewcount title artist Key Path Kind Name (song) naycount mehcount
RageTube: Global Stats viewcount viewcount viewcount datastore memcache
RageTube: Global Stats class Song(db.Model): viewcount = db.IntegerProperty(default=0) title = db.StringProperty() artist = db.StringProperty() def get_viewcount(self): viewcount = self.viewcount cached_viewcount = memcache.get('viewcount-' + self.key().name(), self.key().kind()) if cached_viewcount: viewcount += cached_viewcount return viewcount @classmethod def flush_viewcount(cls, name): song = cls.get_by_key_name(name) value = memcache.get('viewcount-' + name, cls.kind()) memcache.decr('viewcount-' + name, value, cls.kind()) song.viewcount += value song.put() @classmethod def incr_viewcount(cls, name, interval=5, value=1): memcache.incr('viewcount-' + name, value, cls.kind()) interval_num = get_interval_number(datetime.now(), interval) task_name = '-'.join([cls.kind(), name.replace(' ', '-'),  'viewcount', str(interval), str(interval_num)]) deferred.defer(cls.flush_viewcount, name, _name=task_name) LIMIT! (# of tasks)
Ratings Rated by 500 users.
App Gallery: Ratings google.com/analytics/apps/
App Gallery: Ratings Comment Application total_ratings sum_ratings avg_rating rated_index comment_count rating
App Gallery: Ratings def UpdateAppCommentData(self, rating, operation): def UpdateCommentData(self, rating, operation): self.comment_count += 1 * operation self.sum_ratings += rating * operation self.total_ratings += 1 * operation self.avg_rating = int(round(self.sum_ratings / self.total_ratings)) self.rated_index = '%d:%d:%d' %  (self.avg_rating, self.total_ratings, self.index) self.put() db.run_in_transaction(UpdateCommentData, self, rating, operation) app.UpdateAppCommentData(rating, db_models.Comment.ADD) comment = db_models.Comment() comment.application = app comment.rating = rating comment.put() query.order('-avg_rating').order('-rated_index')
Geospatial Queries
City-Go-Round: Agencies citygoround.org https://github.com/walkscore/City-Go-Round
City-Go-Round: Geo Queries Agency GeoModel location (GeoPt) location_geocells (StringListProperty)
City-Go-Round: Geo Queries def fetch_agencies_near(lat, long, bbox_side_in_miles): query = Agency.all() bbox = bbox_centered_at(lat, long, bbox_side_in_miles) return Agency.bounding_box_fetch(query, bbox, max_results = 50) def bounding_box_fetch(query, bbox, max_results=1000,): results = [] query_geocells = geocell.best_bbox_search_cells(bbox) for entity in query.filter('location_geocells IN', query_geocells): if len(results) == max_results: break if (entity.location.lat >= bbox.south and entity.location.lat <= bbox.north and entity.location.lon >= bbox.west and entity.location.lon <= bbox.east): results.append(entity) return results
Full Text Search ,[object Object],Search Thingy It's like pizza, but in the cloud. Other Thingy This will make you smell as delicious as pizza.
Disclosed.ca: Search https://github.com/nurey/disclosed disclosed.ca
Disclosed.ca: Search Contract agency_name vendor_name description comments uri
Disclosed.ca: Search from search.core import SearchIndexProperty, porter_stemmer class Contract(db.Model): uri = db.StringProperty(required=True) agency_name = db.StringProperty(required=True) vendor_name = db.StringProperty(required=True) description = db.StringProperty() comments = db.TextProperty() search_index = SearchIndexProperty(('agency_name', 'vendor_name', 'description', 'comments'), indexer=porter_stemmer) results = Contract.search_index.search(sheep').fetch(20)
Disclosed.ca: Search Contract agency_name vendor_name description comments uri search_index (StringListProperty) SearchIndex
Disclosed.ca: Search SELECT FROM ContractSearch WHERE search_index = &quot;sheep&quot; key search_index ContractSearch1 charter ContractSearch1 june ContractSearch1 sheep ContractSearch2 sheep ContractSearch1 wood
More Learning http://ae-book.appspot.com http://code.google.com/appengine http://blog.notdot.net/
AppEngine: Now & Later &quot;Run your web apps on Google's infrastructure. Easy to build, easy to maintain, easy to scale.&quot; ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Thanks for coming!

Contenu connexe

Tendances

Plugin jQuery, Design Patterns
Plugin jQuery, Design PatternsPlugin jQuery, Design Patterns
Plugin jQuery, Design PatternsRobert Casanova
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginnersleo lapworth
 
Introduction to Perl Best Practices
Introduction to Perl Best PracticesIntroduction to Perl Best Practices
Introduction to Perl Best PracticesJosé Castro
 
Dealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottDealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottO'Reilly Media
 
Searching ORM: First Why, Then How
Searching ORM: First Why, Then HowSearching ORM: First Why, Then How
Searching ORM: First Why, Then Howsfarmer10
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010leo lapworth
 
LPW: Beginners Perl
LPW: Beginners PerlLPW: Beginners Perl
LPW: Beginners PerlDave Cross
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In PerlKang-min Liu
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)andrewnacin
 
Cakefest 2010: API Development
Cakefest 2010: API DevelopmentCakefest 2010: API Development
Cakefest 2010: API DevelopmentAndrew Curioso
 
Accelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gemAccelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gemWynn Netherland
 
jQuery Plugin Creation
jQuery Plugin CreationjQuery Plugin Creation
jQuery Plugin Creationbenalman
 
Evolving Software with Moose
Evolving Software with MooseEvolving Software with Moose
Evolving Software with MooseDave Cross
 
WordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryWordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryl3rady
 

Tendances (20)

Ruby on discuz
Ruby on discuzRuby on discuz
Ruby on discuz
 
Symfony2 meets propel 1.5
Symfony2 meets propel 1.5Symfony2 meets propel 1.5
Symfony2 meets propel 1.5
 
Plugin jQuery, Design Patterns
Plugin jQuery, Design PatternsPlugin jQuery, Design Patterns
Plugin jQuery, Design Patterns
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
 
Introduction to Perl Best Practices
Introduction to Perl Best PracticesIntroduction to Perl Best Practices
Introduction to Perl Best Practices
 
Dealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottDealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter Scott
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
Searching ORM: First Why, Then How
Searching ORM: First Why, Then HowSearching ORM: First Why, Then How
Searching ORM: First Why, Then How
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010
 
LPW: Beginners Perl
LPW: Beginners PerlLPW: Beginners Perl
LPW: Beginners Perl
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)
 
Cakefest 2010: API Development
Cakefest 2010: API DevelopmentCakefest 2010: API Development
Cakefest 2010: API Development
 
Accelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gemAccelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gem
 
jQuery Plugin Creation
jQuery Plugin CreationjQuery Plugin Creation
jQuery Plugin Creation
 
P3 2018 python_regexes
P3 2018 python_regexesP3 2018 python_regexes
P3 2018 python_regexes
 
Evolving Software with Moose
Evolving Software with MooseEvolving Software with Moose
Evolving Software with Moose
 
WordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryWordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know query
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Perl
PerlPerl
Perl
 

En vedette

Getting started with google wave
Getting started with google waveGetting started with google wave
Getting started with google waveMohamed Amin Embi
 
Google Wave First Look
Google Wave   First LookGoogle Wave   First Look
Google Wave First LookVijay Raj
 
What Is Google Wave
What Is Google WaveWhat Is Google Wave
What Is Google Waverkeith
 
Google Wave API: Now and Beyond
Google Wave API: Now and BeyondGoogle Wave API: Now and Beyond
Google Wave API: Now and BeyondMarakana Inc.
 
Google Wave 20/20: Product, Protocol, Platform
Google Wave 20/20: Product, Protocol, PlatformGoogle Wave 20/20: Product, Protocol, Platform
Google Wave 20/20: Product, Protocol, PlatformPamela Fox
 
Google Wave Introduction
Google Wave IntroductionGoogle Wave Introduction
Google Wave IntroductionCraig Dickson
 
What Is Google Wave?
What Is Google Wave?What Is Google Wave?
What Is Google Wave?Mark Fidelman
 
Email Is So 1973
Email Is So 1973Email Is So 1973
Email Is So 1973Red Magma
 

En vedette (15)

Google Wave Intro
Google Wave IntroGoogle Wave Intro
Google Wave Intro
 
Getting started with google wave
Getting started with google waveGetting started with google wave
Getting started with google wave
 
Google Wave First Look
Google Wave   First LookGoogle Wave   First Look
Google Wave First Look
 
Are you ready for Google Wave?
Are you ready for Google Wave?Are you ready for Google Wave?
Are you ready for Google Wave?
 
20091014 Google Wave
20091014 Google Wave20091014 Google Wave
20091014 Google Wave
 
Google Wave Basics
Google Wave BasicsGoogle Wave Basics
Google Wave Basics
 
What Is Google Wave
What Is Google WaveWhat Is Google Wave
What Is Google Wave
 
Google Wave API: Now and Beyond
Google Wave API: Now and BeyondGoogle Wave API: Now and Beyond
Google Wave API: Now and Beyond
 
Google Wave 20/20: Product, Protocol, Platform
Google Wave 20/20: Product, Protocol, PlatformGoogle Wave 20/20: Product, Protocol, Platform
Google Wave 20/20: Product, Protocol, Platform
 
Google wave
Google wave Google wave
Google wave
 
Google Wave
Google WaveGoogle Wave
Google Wave
 
Google Wave Introduction
Google Wave IntroductionGoogle Wave Introduction
Google Wave Introduction
 
What Is Google Wave?
What Is Google Wave?What Is Google Wave?
What Is Google Wave?
 
Email Is So 1973
Email Is So 1973Email Is So 1973
Email Is So 1973
 
Google Wave
Google WaveGoogle Wave
Google Wave
 

Similaire à Writing Apps the Google-y Way (Brisbane)

The bones of a nice Python script
The bones of a nice Python scriptThe bones of a nice Python script
The bones of a nice Python scriptsaniac
 
Python - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave ParkPython - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave Parkpointstechgeeks
 
Plone For Developers - World Plone Day, 2009
Plone For Developers - World Plone Day, 2009Plone For Developers - World Plone Day, 2009
Plone For Developers - World Plone Day, 2009Core Software Group
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceMaarten Balliauw
 
ScotRuby - Dark side of ruby
ScotRuby - Dark side of rubyScotRuby - Dark side of ruby
ScotRuby - Dark side of rubyGautam Rege
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonPython Ireland
 
React.js Basics - ConvergeSE 2015
React.js Basics - ConvergeSE 2015React.js Basics - ConvergeSE 2015
React.js Basics - ConvergeSE 2015Robert Pearce
 
NUS iOS Swift Talk
NUS iOS Swift TalkNUS iOS Swift Talk
NUS iOS Swift TalkGabriel Lim
 
Addmi 10.5-basic query-language
Addmi 10.5-basic query-languageAddmi 10.5-basic query-language
Addmi 10.5-basic query-languageodanyboy
 
Decorators in Python
Decorators in PythonDecorators in Python
Decorators in PythonBen James
 
Think Generic - Add API's To Your Custom Modules
Think Generic - Add API's To Your Custom ModulesThink Generic - Add API's To Your Custom Modules
Think Generic - Add API's To Your Custom ModulesJens Sørensen
 
PyCon APAC - Django Test Driven Development
PyCon APAC - Django Test Driven DevelopmentPyCon APAC - Django Test Driven Development
PyCon APAC - Django Test Driven DevelopmentTudor Munteanu
 
Javascript Primer
Javascript PrimerJavascript Primer
Javascript PrimerAdam Hepton
 
Casting for not so strange actors
Casting for not so strange actorsCasting for not so strange actors
Casting for not so strange actorszucaritask
 

Similaire à Writing Apps the Google-y Way (Brisbane) (20)

Having Fun Programming!
Having Fun Programming!Having Fun Programming!
Having Fun Programming!
 
The bones of a nice Python script
The bones of a nice Python scriptThe bones of a nice Python script
The bones of a nice Python script
 
Python - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave ParkPython - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave Park
 
Plone For Developers - World Plone Day, 2009
Plone For Developers - World Plone Day, 2009Plone For Developers - World Plone Day, 2009
Plone For Developers - World Plone Day, 2009
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to Space
 
ScotRuby - Dark side of ruby
ScotRuby - Dark side of rubyScotRuby - Dark side of ruby
ScotRuby - Dark side of ruby
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in Python
 
React.js Basics - ConvergeSE 2015
React.js Basics - ConvergeSE 2015React.js Basics - ConvergeSE 2015
React.js Basics - ConvergeSE 2015
 
An introduction to Ruby
An introduction to RubyAn introduction to Ruby
An introduction to Ruby
 
NUS iOS Swift Talk
NUS iOS Swift TalkNUS iOS Swift Talk
NUS iOS Swift Talk
 
Addmi 10.5-basic query-language
Addmi 10.5-basic query-languageAddmi 10.5-basic query-language
Addmi 10.5-basic query-language
 
Decorators in Python
Decorators in PythonDecorators in Python
Decorators in Python
 
Think Generic - Add API's To Your Custom Modules
Think Generic - Add API's To Your Custom ModulesThink Generic - Add API's To Your Custom Modules
Think Generic - Add API's To Your Custom Modules
 
Fantom and Tales
Fantom and TalesFantom and Tales
Fantom and Tales
 
PyCon APAC - Django Test Driven Development
PyCon APAC - Django Test Driven DevelopmentPyCon APAC - Django Test Driven Development
PyCon APAC - Django Test Driven Development
 
My First Ruby
My First RubyMy First Ruby
My First Ruby
 
Elegant APIs
Elegant APIsElegant APIs
Elegant APIs
 
Javascript Primer
Javascript PrimerJavascript Primer
Javascript Primer
 
Casting for not so strange actors
Casting for not so strange actorsCasting for not so strange actors
Casting for not so strange actors
 
Django
DjangoDjango
Django
 

Plus de Pamela Fox

Teaching Programming Online
Teaching Programming OnlineTeaching Programming Online
Teaching Programming OnlinePamela Fox
 
Engineering culture
Engineering cultureEngineering culture
Engineering culturePamela Fox
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryPamela Fox
 
A Year of Hermit Hacking
A Year of Hermit HackingA Year of Hermit Hacking
A Year of Hermit HackingPamela Fox
 
The Developer Experience
The Developer Experience The Developer Experience
The Developer Experience Pamela Fox
 
Making JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachableMaking JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachablePamela Fox
 
How I became a born again vegetable-tarian
How I became a born again vegetable-tarianHow I became a born again vegetable-tarian
How I became a born again vegetable-tarianPamela Fox
 
The Developer Experience
The Developer ExperienceThe Developer Experience
The Developer ExperiencePamela Fox
 
No, Really, I'm Shy
No, Really, I'm ShyNo, Really, I'm Shy
No, Really, I'm ShyPamela Fox
 
The Wonders of the "Onesie"
The Wonders of the "Onesie"The Wonders of the "Onesie"
The Wonders of the "Onesie"Pamela Fox
 
I’M A Barbie Girl In A CS World
I’M A Barbie Girl In A CS WorldI’M A Barbie Girl In A CS World
I’M A Barbie Girl In A CS WorldPamela Fox
 
Collaborative Mapping with Google Wave
Collaborative Mapping with Google WaveCollaborative Mapping with Google Wave
Collaborative Mapping with Google WavePamela Fox
 
Google Products: Deep Dive on Google Maps
Google Products: Deep Dive on Google MapsGoogle Products: Deep Dive on Google Maps
Google Products: Deep Dive on Google MapsPamela Fox
 
Google Products & Google Maps
Google Products & Google MapsGoogle Products & Google Maps
Google Products & Google MapsPamela Fox
 
Mashups & APIs
Mashups & APIsMashups & APIs
Mashups & APIsPamela Fox
 
A World of Words
A World of WordsA World of Words
A World of WordsPamela Fox
 
Web APIs & Google APIs
Web APIs & Google APIsWeb APIs & Google APIs
Web APIs & Google APIsPamela Fox
 
Growing up Geek: My Dad, the Computer Scientist
Growing up Geek: My Dad, the Computer ScientistGrowing up Geek: My Dad, the Computer Scientist
Growing up Geek: My Dad, the Computer ScientistPamela Fox
 
Living in the Cloud: Hosting Data & Apps Using the Google Infrastructure
Living in the Cloud: Hosting Data & Apps Using the Google InfrastructureLiving in the Cloud: Hosting Data & Apps Using the Google Infrastructure
Living in the Cloud: Hosting Data & Apps Using the Google InfrastructurePamela Fox
 
Client Killed the Server Star
Client Killed the Server StarClient Killed the Server Star
Client Killed the Server StarPamela Fox
 

Plus de Pamela Fox (20)

Teaching Programming Online
Teaching Programming OnlineTeaching Programming Online
Teaching Programming Online
 
Engineering culture
Engineering cultureEngineering culture
Engineering culture
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
 
A Year of Hermit Hacking
A Year of Hermit HackingA Year of Hermit Hacking
A Year of Hermit Hacking
 
The Developer Experience
The Developer Experience The Developer Experience
The Developer Experience
 
Making JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachableMaking JavaScript Libraries More Approachable
Making JavaScript Libraries More Approachable
 
How I became a born again vegetable-tarian
How I became a born again vegetable-tarianHow I became a born again vegetable-tarian
How I became a born again vegetable-tarian
 
The Developer Experience
The Developer ExperienceThe Developer Experience
The Developer Experience
 
No, Really, I'm Shy
No, Really, I'm ShyNo, Really, I'm Shy
No, Really, I'm Shy
 
The Wonders of the "Onesie"
The Wonders of the "Onesie"The Wonders of the "Onesie"
The Wonders of the "Onesie"
 
I’M A Barbie Girl In A CS World
I’M A Barbie Girl In A CS WorldI’M A Barbie Girl In A CS World
I’M A Barbie Girl In A CS World
 
Collaborative Mapping with Google Wave
Collaborative Mapping with Google WaveCollaborative Mapping with Google Wave
Collaborative Mapping with Google Wave
 
Google Products: Deep Dive on Google Maps
Google Products: Deep Dive on Google MapsGoogle Products: Deep Dive on Google Maps
Google Products: Deep Dive on Google Maps
 
Google Products & Google Maps
Google Products & Google MapsGoogle Products & Google Maps
Google Products & Google Maps
 
Mashups & APIs
Mashups & APIsMashups & APIs
Mashups & APIs
 
A World of Words
A World of WordsA World of Words
A World of Words
 
Web APIs & Google APIs
Web APIs & Google APIsWeb APIs & Google APIs
Web APIs & Google APIs
 
Growing up Geek: My Dad, the Computer Scientist
Growing up Geek: My Dad, the Computer ScientistGrowing up Geek: My Dad, the Computer Scientist
Growing up Geek: My Dad, the Computer Scientist
 
Living in the Cloud: Hosting Data & Apps Using the Google Infrastructure
Living in the Cloud: Hosting Data & Apps Using the Google InfrastructureLiving in the Cloud: Hosting Data & Apps Using the Google Infrastructure
Living in the Cloud: Hosting Data & Apps Using the Google Infrastructure
 
Client Killed the Server Star
Client Killed the Server StarClient Killed the Server Star
Client Killed the Server Star
 

Dernier

7movierulz.uk
7movierulz.uk7movierulz.uk
7movierulz.ukaroemirsr
 
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptx
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptxHELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptx
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptxHelene Heckrotte
 
AMAZON SELLER VIRTUAL ASSISTANT PRODUCT RESEARCH .pdf
AMAZON SELLER VIRTUAL ASSISTANT PRODUCT RESEARCH .pdfAMAZON SELLER VIRTUAL ASSISTANT PRODUCT RESEARCH .pdf
AMAZON SELLER VIRTUAL ASSISTANT PRODUCT RESEARCH .pdfJohnCarloValencia4
 
Team B Mind Map for Organizational Chg..
Team B Mind Map for Organizational Chg..Team B Mind Map for Organizational Chg..
Team B Mind Map for Organizational Chg..dlewis191
 
Fabric RFID Wristbands in Ireland for Events and Festivals
Fabric RFID Wristbands in Ireland for Events and FestivalsFabric RFID Wristbands in Ireland for Events and Festivals
Fabric RFID Wristbands in Ireland for Events and FestivalsWristbands Ireland
 
Ethical stalking by Mark Williams. UpliftLive 2024
Ethical stalking by Mark Williams. UpliftLive 2024Ethical stalking by Mark Williams. UpliftLive 2024
Ethical stalking by Mark Williams. UpliftLive 2024Winbusinessin
 
A flour, rice and Suji company in Jhang.
A flour, rice and Suji company in Jhang.A flour, rice and Suji company in Jhang.
A flour, rice and Suji company in Jhang.mcshagufta46
 
PDT 89 - $1.4M - Seed - Plantee Innovations.pdf
PDT 89 - $1.4M - Seed - Plantee Innovations.pdfPDT 89 - $1.4M - Seed - Plantee Innovations.pdf
PDT 89 - $1.4M - Seed - Plantee Innovations.pdfHajeJanKamps
 
NASA CoCEI Scaling Strategy - November 2023
NASA CoCEI Scaling Strategy - November 2023NASA CoCEI Scaling Strategy - November 2023
NASA CoCEI Scaling Strategy - November 2023Steve Rader
 
Scrum Events & How to run them effectively
Scrum Events & How to run them effectivelyScrum Events & How to run them effectively
Scrum Events & How to run them effectivelyMarianna Nakou
 
ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...
ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...
ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...ISONIKELtd
 
Upgrade Your Banking Experience with Advanced Core Banking Applications
Upgrade Your Banking Experience with Advanced Core Banking ApplicationsUpgrade Your Banking Experience with Advanced Core Banking Applications
Upgrade Your Banking Experience with Advanced Core Banking ApplicationsIntellect Design Arena Ltd
 
Building Your Personal Brand on LinkedIn - Expert Planet- 2024
 Building Your Personal Brand on LinkedIn - Expert Planet-  2024 Building Your Personal Brand on LinkedIn - Expert Planet-  2024
Building Your Personal Brand on LinkedIn - Expert Planet- 2024Stephan Koning
 
The Vietnam Believer Newsletter_MARCH 25, 2024_EN_Vol. 003
The Vietnam Believer Newsletter_MARCH 25, 2024_EN_Vol. 003The Vietnam Believer Newsletter_MARCH 25, 2024_EN_Vol. 003
The Vietnam Believer Newsletter_MARCH 25, 2024_EN_Vol. 003believeminhh
 
Amazon ppt.pptx Amazon about the company
Amazon ppt.pptx Amazon about the companyAmazon ppt.pptx Amazon about the company
Amazon ppt.pptx Amazon about the companyfashionfound007
 
Personal Brand Exploration Presentation Eric Bonilla
Personal Brand Exploration Presentation Eric BonillaPersonal Brand Exploration Presentation Eric Bonilla
Personal Brand Exploration Presentation Eric BonillaEricBonilla13
 
Project Brief & Information Architecture Report
Project Brief & Information Architecture ReportProject Brief & Information Architecture Report
Project Brief & Information Architecture Reportamberjiles31
 
To Create Your Own Wig Online To Create Your Own Wig Online
To Create Your Own Wig Online  To Create Your Own Wig OnlineTo Create Your Own Wig Online  To Create Your Own Wig Online
To Create Your Own Wig Online To Create Your Own Wig Onlinelng ths
 
Chapter_Five_The_Rural_Development_Policies_and_Strategy_of_Ethiopia.pptx
Chapter_Five_The_Rural_Development_Policies_and_Strategy_of_Ethiopia.pptxChapter_Five_The_Rural_Development_Policies_and_Strategy_of_Ethiopia.pptx
Chapter_Five_The_Rural_Development_Policies_and_Strategy_of_Ethiopia.pptxesiyasmengesha
 
Live-Streaming in the Music Industry Webinar
Live-Streaming in the Music Industry WebinarLive-Streaming in the Music Industry Webinar
Live-Streaming in the Music Industry WebinarNathanielSchmuck
 

Dernier (20)

7movierulz.uk
7movierulz.uk7movierulz.uk
7movierulz.uk
 
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptx
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptxHELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptx
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptx
 
AMAZON SELLER VIRTUAL ASSISTANT PRODUCT RESEARCH .pdf
AMAZON SELLER VIRTUAL ASSISTANT PRODUCT RESEARCH .pdfAMAZON SELLER VIRTUAL ASSISTANT PRODUCT RESEARCH .pdf
AMAZON SELLER VIRTUAL ASSISTANT PRODUCT RESEARCH .pdf
 
Team B Mind Map for Organizational Chg..
Team B Mind Map for Organizational Chg..Team B Mind Map for Organizational Chg..
Team B Mind Map for Organizational Chg..
 
Fabric RFID Wristbands in Ireland for Events and Festivals
Fabric RFID Wristbands in Ireland for Events and FestivalsFabric RFID Wristbands in Ireland for Events and Festivals
Fabric RFID Wristbands in Ireland for Events and Festivals
 
Ethical stalking by Mark Williams. UpliftLive 2024
Ethical stalking by Mark Williams. UpliftLive 2024Ethical stalking by Mark Williams. UpliftLive 2024
Ethical stalking by Mark Williams. UpliftLive 2024
 
A flour, rice and Suji company in Jhang.
A flour, rice and Suji company in Jhang.A flour, rice and Suji company in Jhang.
A flour, rice and Suji company in Jhang.
 
PDT 89 - $1.4M - Seed - Plantee Innovations.pdf
PDT 89 - $1.4M - Seed - Plantee Innovations.pdfPDT 89 - $1.4M - Seed - Plantee Innovations.pdf
PDT 89 - $1.4M - Seed - Plantee Innovations.pdf
 
NASA CoCEI Scaling Strategy - November 2023
NASA CoCEI Scaling Strategy - November 2023NASA CoCEI Scaling Strategy - November 2023
NASA CoCEI Scaling Strategy - November 2023
 
Scrum Events & How to run them effectively
Scrum Events & How to run them effectivelyScrum Events & How to run them effectively
Scrum Events & How to run them effectively
 
ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...
ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...
ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...
 
Upgrade Your Banking Experience with Advanced Core Banking Applications
Upgrade Your Banking Experience with Advanced Core Banking ApplicationsUpgrade Your Banking Experience with Advanced Core Banking Applications
Upgrade Your Banking Experience with Advanced Core Banking Applications
 
Building Your Personal Brand on LinkedIn - Expert Planet- 2024
 Building Your Personal Brand on LinkedIn - Expert Planet-  2024 Building Your Personal Brand on LinkedIn - Expert Planet-  2024
Building Your Personal Brand on LinkedIn - Expert Planet- 2024
 
The Vietnam Believer Newsletter_MARCH 25, 2024_EN_Vol. 003
The Vietnam Believer Newsletter_MARCH 25, 2024_EN_Vol. 003The Vietnam Believer Newsletter_MARCH 25, 2024_EN_Vol. 003
The Vietnam Believer Newsletter_MARCH 25, 2024_EN_Vol. 003
 
Amazon ppt.pptx Amazon about the company
Amazon ppt.pptx Amazon about the companyAmazon ppt.pptx Amazon about the company
Amazon ppt.pptx Amazon about the company
 
Personal Brand Exploration Presentation Eric Bonilla
Personal Brand Exploration Presentation Eric BonillaPersonal Brand Exploration Presentation Eric Bonilla
Personal Brand Exploration Presentation Eric Bonilla
 
Project Brief & Information Architecture Report
Project Brief & Information Architecture ReportProject Brief & Information Architecture Report
Project Brief & Information Architecture Report
 
To Create Your Own Wig Online To Create Your Own Wig Online
To Create Your Own Wig Online  To Create Your Own Wig OnlineTo Create Your Own Wig Online  To Create Your Own Wig Online
To Create Your Own Wig Online To Create Your Own Wig Online
 
Chapter_Five_The_Rural_Development_Policies_and_Strategy_of_Ethiopia.pptx
Chapter_Five_The_Rural_Development_Policies_and_Strategy_of_Ethiopia.pptxChapter_Five_The_Rural_Development_Policies_and_Strategy_of_Ethiopia.pptx
Chapter_Five_The_Rural_Development_Policies_and_Strategy_of_Ethiopia.pptx
 
Live-Streaming in the Music Industry Webinar
Live-Streaming in the Music Industry WebinarLive-Streaming in the Music Industry Webinar
Live-Streaming in the Music Industry Webinar
 

Writing Apps the Google-y Way (Brisbane)

  • 1. WRITING APPS THE GOOGLE-Y WAY Pamela Fox, YOW! Australia 2010 (Brisbane)
  • 2. Who am I? twitter.com/pamelafox [email_address] pamelafox.org you get the idea...
  • 3. Who am I? Google Maps API Google Wave API 2006 2010 2008 Google App Engine
  • 4. Who am I? wave side projects 92 apps
  • 5. Who am I? Java pYthon
  • 6.
  • 7. What is a “web app”?
  • 10. Intranet vs. Internet ~2 billion Hundreds - Thousands
  • 11. What is a “web app”?
  • 13. Some Google App Engine web apps www.gifttag.com www.buddypoke.com
  • 14. Google apps on App Engine panoramio.com pubsubhubbub.appspot.com
  • 15.
  • 16. Demo: Guestbook awesomest-app.appspot.com http://code.google.com/p/google-app-engine-samples/source/browse/trunk/guestbook appengine.google.com localhost build deploy monitor
  • 20. App Engine architecture LIMIT CPU LIMIT Memory LIMIT Time
  • 21. App Engine architecture hardware ports globals file system Groovy, JRuby, Mirah, Clojure, Scala
  • 22. App Engine architecture 141,241,791 calls 1 GB data $0.15 GB/month 45,000,000 calls 657,000 - 46,000,000 calls *Always check docs for latest quotas. 192,672,000 calls 558 GB data $0.15 GB/month 7,000 - 1,700,000 calls $0.0001 per mail sent 46,000,000 calls 1,046 GB data sent 100,000 - 20,000,000 calls
  • 24. Datastore Entity Properties Key Entity Entity Entity Entity Path Kind Name/ID
  • 25. Example: Speaker Entities Key Path Kind ID First Name Last Name Speaker1 - Speaker 1 Rod Johnson Key Path Kind ID First Name Last Name Middle Name Suffix Speaker2 - Speaker 2 Guy Steele L Jr.
  • 26.
  • 27.
  • 28.
  • 29. Queries & Indexes Query Index Index Index Index Query Query Query Query Query
  • 30. Queries & Indexes SELECT * from Speaker ORDER BY lastname LIMIT! (# of results) key lastname Speaker3 Fox Speaker4 Hohpe Speaker1 Johnson Speaker2 Steele
  • 31. Queries & Indexes SELECT * from Speaker ORDER by middlename key middlename Speaker2 L
  • 32. Queries & Indexes SELECT * from Speaker WHERE keynote = True key keynote Speaker1 True Speaker2 True Speaker3 False Speaker4 False
  • 33. Queries & Indexes SELECT * from Speaker WHERE keynote = False key keynote Speaker1 True Speaker2 True Speaker3 False Speaker4 False
  • 34.
  • 35.
  • 36.
  • 37. Impossible Indexes SELECT * from Speaker WHERE lastname < 'Steele' and firstname > 'Gregory' ...not in subsequent rows! key lastname firstname Speaker3 Fox Pamela Speaker4 Hohpe Gregory Speaker1 Johnson Rod Speaker2 Steele Guy
  • 38. Impossible Indexes SELECT * from Speaker WHERE lastname > 'Fox' ORDER BY firstname ...not in the correct order! key lastname firstname Speaker3 Fox Pamela Speaker4 Hohpe Gregory Speaker1 Johnson Rod Speaker2 Steele Guy
  • 39.
  • 40.
  • 41. More Properties class Talk(db.Model): title = db.StringProperty(required=True) abstract = db.TextProperty(required=True) speaker = db.ReferenceProperty(Speaker) tags = db.StringListProperty() pamela = Speaker.all().filter('firstname = ', 'Pamela').get() talk = Talk('Writing Apps the Googley Way', 'Bla bla bla', pamela, ['App Engine', 'Python']) talk.put() talk = Talk('Wonders of the Onesie', 'Bluh bluh bluh', pamela, ['Pajamas', 'Onesies']) talk.put()
  • 42. Back-References pamela = Speaker.all().filter('firstname = ', 'Pamela').get() for talk in pamela.talk_set: print talk.title SELECT * from Talk WHERE speaker = Speaker3 key speaker Talk6 Speaker2 Talk1 Speaker3 Talk2 Speaker3 Talk5 Speaker4
  • 43. Searching List Properties talks = Talk.all().filter('tags = ', 'python') .fetch(10) SELECT * from Talk WHERE tags = 'Python' LIMIT! (# of index rows) key lastname Talk1 App Engine Talk2 Pajamas Talk1 Python Talk2 Onesies
  • 44. Update Transactions commit journal apply entities apply indexes A B
  • 45. Entity Groups pamela = Speaker.all().filter('firstname = ', 'Pamela').get() talk1 = Talk('Writing Apps the Googley Way', 'Bla bla bla', pamela, ['App Engine', 'Python'], parent=pamela) talk2 = Talk('Wonders of the Onesie', 'Bluh bluh bluh', pamela, ['Pajamas', 'Onesies'], parent=pamela) db.put(talk1, talk2) def update_talks(): talk1.title = 'Writing Apps the Microsoft Way' talk2.title = 'Wonders of the Windows' db.put(talk1, talk2) db.run_in_transaction(update_talks)
  • 47. Counters 1 2 3 4 5 people have done something.
  • 48. RageTube: Global Stats ragetube.net http://github.com/pamelafox/ragetube
  • 49. RageTube: Global Stats SongStat yaycount viewcount title artist Key Path Kind Name (song) naycount mehcount
  • 50. RageTube: Global Stats viewcount viewcount viewcount datastore memcache
  • 51. RageTube: Global Stats class Song(db.Model): viewcount = db.IntegerProperty(default=0) title = db.StringProperty() artist = db.StringProperty() def get_viewcount(self): viewcount = self.viewcount cached_viewcount = memcache.get('viewcount-' + self.key().name(), self.key().kind()) if cached_viewcount: viewcount += cached_viewcount return viewcount @classmethod def flush_viewcount(cls, name): song = cls.get_by_key_name(name) value = memcache.get('viewcount-' + name, cls.kind()) memcache.decr('viewcount-' + name, value, cls.kind()) song.viewcount += value song.put() @classmethod def incr_viewcount(cls, name, interval=5, value=1): memcache.incr('viewcount-' + name, value, cls.kind()) interval_num = get_interval_number(datetime.now(), interval) task_name = '-'.join([cls.kind(), name.replace(' ', '-'), 'viewcount', str(interval), str(interval_num)]) deferred.defer(cls.flush_viewcount, name, _name=task_name) LIMIT! (# of tasks)
  • 52. Ratings Rated by 500 users.
  • 53. App Gallery: Ratings google.com/analytics/apps/
  • 54. App Gallery: Ratings Comment Application total_ratings sum_ratings avg_rating rated_index comment_count rating
  • 55. App Gallery: Ratings def UpdateAppCommentData(self, rating, operation): def UpdateCommentData(self, rating, operation): self.comment_count += 1 * operation self.sum_ratings += rating * operation self.total_ratings += 1 * operation self.avg_rating = int(round(self.sum_ratings / self.total_ratings)) self.rated_index = '%d:%d:%d' % (self.avg_rating, self.total_ratings, self.index) self.put() db.run_in_transaction(UpdateCommentData, self, rating, operation) app.UpdateAppCommentData(rating, db_models.Comment.ADD) comment = db_models.Comment() comment.application = app comment.rating = rating comment.put() query.order('-avg_rating').order('-rated_index')
  • 57. City-Go-Round: Agencies citygoround.org https://github.com/walkscore/City-Go-Round
  • 58. City-Go-Round: Geo Queries Agency GeoModel location (GeoPt) location_geocells (StringListProperty)
  • 59. City-Go-Round: Geo Queries def fetch_agencies_near(lat, long, bbox_side_in_miles): query = Agency.all() bbox = bbox_centered_at(lat, long, bbox_side_in_miles) return Agency.bounding_box_fetch(query, bbox, max_results = 50) def bounding_box_fetch(query, bbox, max_results=1000,): results = [] query_geocells = geocell.best_bbox_search_cells(bbox) for entity in query.filter('location_geocells IN', query_geocells): if len(results) == max_results: break if (entity.location.lat >= bbox.south and entity.location.lat <= bbox.north and entity.location.lon >= bbox.west and entity.location.lon <= bbox.east): results.append(entity) return results
  • 60.
  • 62. Disclosed.ca: Search Contract agency_name vendor_name description comments uri
  • 63. Disclosed.ca: Search from search.core import SearchIndexProperty, porter_stemmer class Contract(db.Model): uri = db.StringProperty(required=True) agency_name = db.StringProperty(required=True) vendor_name = db.StringProperty(required=True) description = db.StringProperty() comments = db.TextProperty() search_index = SearchIndexProperty(('agency_name', 'vendor_name', 'description', 'comments'), indexer=porter_stemmer) results = Contract.search_index.search(sheep').fetch(20)
  • 64. Disclosed.ca: Search Contract agency_name vendor_name description comments uri search_index (StringListProperty) SearchIndex
  • 65. Disclosed.ca: Search SELECT FROM ContractSearch WHERE search_index = &quot;sheep&quot; key search_index ContractSearch1 charter ContractSearch1 june ContractSearch1 sheep ContractSearch2 sheep ContractSearch1 wood
  • 66. More Learning http://ae-book.appspot.com http://code.google.com/appengine http://blog.notdot.net/
  • 67.