A deck used to introduce Google App Engine at an Appsterdam Guru Session. It features an overview of the features provided by App Engine, two hands on examples and a peek on advanced features.
complete development stack that uses familiar technologies to build and host applications on the same infrastructure used at Google. @abahgat, #appsterdam “ ” 2/46
underlying operating system. The sandbox allows App Engine to @abahgat, #appsterdam distribute web requests across multiple servers start and stop servers to meet traffic demands isolate apps in a secure, reliable environment abstract hardware, operating system and physical location of the web server · · · · 5/46
URL fetch and email services or the experimental Socket API. inbound connections: only HTTP(s) on ports 80/443. filesystem access: writing files is not allowed. An application can read only files uploaded with the application code. no native code: libraries that depend on native code are generally not available. time limits: app code must terminate within given time limits. (60s for web requests, 10m for tasks but unlimited time for backend jobs) · · · · · 6/46
a NoSQL schemaless data storage built in GAE Google Cloud SQL: a relational SQL database service similar to MySQL Google Cloud Storage: file based storage @abahgat, #appsterdam 7/46
installer. You should also have Python by now, but in case you do not, grab it from here. (Your platform might offer smarter ways to install it.) @abahgat, #appsterdam 11/46
called a p p . y m l @abahgat, #appsterdam a p p l i c a t i o n : e x a m p l e v e r s i o n : 1 r u n t i m e : p y t h o n 2 7 a p i _ v e r s i o n : 1 t h r e a d s a f e : y e s h a n d l e r s : - u r l : . * s c r i p t : m a i n . a p p l i b r a r i e s : - n a m e : w e b a p p 2 v e r s i o n : " 2 . 5 . 2 " Y A M L 16/46
default: In addition to webapp2, the environment includes WebOb and Django. @abahgat, #appsterdam i m p o r t w e b a p p 2 c l a s s M a i n H a n d l e r ( w e b a p p 2 . R e q u e s t H a n d l e r ) : d e f g e t ( s e l f ) : n a m e = s e l f . r e q u e s t . g e t ( ' n a m e ' ) s e l f . r e s p o n s e . w r i t e ( ' H e l l o % s ! ' % n a m e ) a p p = w e b a p p 2 . W S G I A p p l i c a t i o n ( [ ( ' / ' , M a i n H a n d l e r ) ] , d e b u g = T r u e ) P Y T H O N 17/46
original one is implemented in g o o g l e . a p p e n g i n e . e x t . d b The new one is called NDB and it is implemented in g o o g l e . a p p e n g i n e . e x t . n d b They are very similar but not identical We will cover NDB · · · · · 18/46
a Python class. @abahgat, #appsterdam f r o m g o o g l e . a p p e n g i n e . e x t i m p o r t n d b c l a s s C o n t a c t ( n d b . M o d e l ) : n a m e = n d b . S t r i n g P r o p e r t y ( ) e m a i l = n d b . S t r i n g P r o p e r t y ( ) b i r t h _ d a t e = n d b . D a t e P r o p e r t y ( ) P Y T H O N 19/46
#appsterdam f r o m g o o g l e . a p p e n g i n e . e x t i m p o r t n d b d e f S t o r e s B y C i t y ( c i t y , l i m i t ) : q u e r y = S t o r e . q u e r y ( S t o r e . c i t y = = c i t y ) . o r d e r ( S t o r e . n a m e ) r e t u r n q u e r y . f e t c h ( l i m i t , p r o j e c t i o n = [ S t o r e . n a m e , S t o r e . a d d r e s s ] ) P Y T H O N Queries are objects Filters and projections are specified by calling methods Make sure you know the limits! (Read the docs) · · · 20/46
GQL, a SQL-like language. GQL is translated to NDB's native query API. (This is the opposite of what traditional ORM libraries do!) @abahgat, #appsterdam f r o m g o o g l e . a p p e n g i n e . e x t i m p o r t n d b q r y = n d b . g q l ( " S E L E C T * F R O M A c c o u n t W H E R E b a l a n c e < : 1 " , 1 0 0 ) P Y T H O N 21/46
by default. Alternatively, App Engine ships with jinja2, too. @abahgat, #appsterdam < h t m l > < b o d y > { % f o r c o n t a c t i n c o n t a c t s % } { % i f c o n t a c t . n a m e % } < b > { { c o n t a c t . n a m e } } < / b > { % e l s e % } U n n a m e d c o n t a c t { % e n d i f % } < { { c o n t a c t . e m a i l } } > { % e n d f o r % } < a h r e f = " { { u r l } } " > { { u r l _ l i n k t e x t } } < / a > < / b o d y > < / h t m l > H T M L 22/46
template in with webapp2: @abahgat, #appsterdam d e f r e n d e r _ t e m p l a t e ( s e l f , v i e w _ f i l e n a m e , p a r a m s = N o n e ) : i f n o t p a r a m s : p a r a m s = { } p a t h = o s . p a t h . j o i n ( o s . p a t h . d i r n a m e ( _ _ f i l e _ _ ) , ' v i e w s ' , v i e w _ f i l e n a m e ) s e l f . r e s p o n s e . o u t . w r i t e ( t e m p l a t e . r e n d e r ( p a t h , p a r a m s ) ) P Y T H O N 23/46
Can be used to minimize hits to the Datastore or to save transient state information. @abahgat, #appsterdam f r o m g o o g l e . a p p e n g i n e . a p i i m p o r t m e m c a c h e d e f g e t _ d a t a ( ) : d a t a = m e m c a c h e . g e t ( ' k e y ' ) i f d a t a i s n o t N o n e : r e t u r n d a t a e l s e : d a t a = s e l f . q u e r y _ f o r _ d a t a ( ) m e m c a c h e . a d d ( ' k e y ' , d a t a , 6 0 ) r e t u r n d a t a P Y T H O N 24/46
the cursor position of every visitor's mouse. Update the cursor position whenever users move their mouse. Remove cursor icons when visitors leave the page. Complete the code in the c h a n n e l directory of the package you downloaded earlier and implement the missing methods. Point your browser to h t t p : / / l o c a l h o s t : $ A P P _ P O R T / c h a n n e l to test your server. · · · · · 29/46
client, which A server, which · connects to a channel, listen for updates, sends messages to the server. - - - · maintains a registry of open channels, notifies clients of state changes. - - 30/46
that! Enable presence in your a p p . y a m l and implement two handlers that can respond to P O S T at @abahgat, #appsterdam The server needs to keep track of the connected clients, you can keep that information in memcache but for this example, it is necessary to be notified of connections and disconnections. · · · i n b o u n d _ s e r v i c e s : - c h a n n e l _ p r e s e n c e Y A M L / _ a h / c h a n n e l / c o n n e c t e d / / _ a h / c h a n n e l / d i s c o n n e c t e d / · · 31/46
sends a token to the client: The client uses the token to create a channel @abahgat, #appsterdam d e f g e t ( s e l f ) : c l i e n t _ i d = u u i d . u u i d 4 ( ) . h e x t o k e n = c h a n n e l . c r e a t e _ c h a n n e l ( c l i e n t _ i d ) t e m p l a t e _ v a l u e s = { ' c l i e n t ' : c l i e n t _ i d , ' t o k e n ' : t o k e n } s e l f . _ r e n d e r _ t e m p l a t e ( t e m p l a t e _ v a l u e s ) P Y T H O N v a r c l i e n t = " { { c l i e n t } } " ; v a r c h a n n e l = n e w g o o g . a p p e n g i n e . C h a n n e l ( ' { { t o k e n } } ' ) ; f u n c t i o n s e t U p C h a n n e l ( ) { v a r s o c k e t = c h a n n e l . o p e n ( ) ; s o c k e t . o n m e s s a g e = o n M e s s a g e ; } J A V A S C R I P T 32/46
the client. It can send data to the server via HTTP requests: @abahgat, #appsterdam f u n c t i o n o n M e s s a g e ( m e s s a g e ) { d a t a = $ . p a r s e J S O N ( m e s s a g e . d a t a ) ; / * d o s o m e t h i n g w i t h d a t a * / } J A V A S C R I P T f u n c t i o n s e n d C o o r d i n a t e s ( ) { $ . p o s t ( ' / c h a n n e l ' , { x : c u r r e n t _ x , y : c u r r e n t _ y , c l i e n t : c l i e n t } ) ; } J A V A S C R I P T 33/46
n d p o i n t s directory of the package you downloaded earlier and implement the missing methods. Point your browser to h t t p : / / l o c a l h o s t : $ A P P _ P O R T / e n d p o i n t s to test your server. · · 36/46
endpoints decorators, create an API server instance, and map the instance to the API URL @abahgat, #appsterdam @ e n d p o i n t s . a p i ( n a m e = ' m y a p i ' , v e r s i o n = ' v 1 ' , d e s c r i p t i o n = ' M y N e w A P I ' ) c l a s s M y N e w A p i ( r e m o t e . S e r v i c e ) : . . . P Y T H O N a p p l i c a t i o n = e n d p o i n t s . a p i _ s e r v e r ( [ M y N e w A p i ] , r e s t r i c t e d = F a l s e ) P Y T H O N h a n d l e r s : # E n d p o i n t s h a n d l e r - u r l : / _ a h / s p i / . * s c r i p t : s e r v i c e s . a p p l i c a t i o n Y A M L 38/46
e n d p o i n t s . m e t h o d ( R e q u e s t M e s s a g e C l a s s , R e s p o n s e M e s s a g e C l a s s , n a m e = ' f o o . b a r ' , p a t h = ' / b a r ' , h t t p _ m e t h o d = ' G E T ' , . . . ) d e f b a r ( s e l f , r e q u e s t ) : . . . P Y T H O N R e q u e s t M e s s a g e C l a s s and R e s p o n s e M e s s a g e C l a s s are ProtoRPC definitions of the request and response classes, p a t h is the URL path of the endpoint, h t t p _ m e t h o d allows to map different functions to different HTTP methods · · · 39/46
Cloud Endpoints expose discovery services at h t t p s : / / y o u r _ a p p _ i d . a p p s p o t . c o m / _ a h / a p i / d i s c o v e r y / v 1 / a p i s You can also use the APIs Explorer to experiment with your API by visiting h t t p s : / / y o u r _ a p p _ i d . a p p s p o t . c o m / _ a h / a p i / e x p l o r e r You can use the SDK to generate JavaScript, Android and iOS clients for your service, Endpoints can authenticate clients using OAuth 2.0, If you want to build a REST API, check out Endpoints Proto Datastore, and if you work with Android applications, check out the Mobile Backend Starter. · · · · · · 40/46
your app with Google Talk and Instant Message Clients. Search (experimental) – Build indexes for fast search over sets of document (which can be any object your app manipulates. Supports full text search and distance-based geographical search out of the box. Prospective Search (experimental) – Analyze a real-time feed of documents and be notified when anything matches one of your searches. · · · 42/46
location aware system. Search for all the points that are closer than 10km from my position. Run a full text search on the items descriptions. · · · 45/46