PHP4, HTML4, early 2003 First school projects, sites, 2003-2005 First work, 2006 Met PHP5, late 2006 Own web design studio, 2007 Switch to Python & Django, late 2007
2011-2012 Django is good, but Flask is better GetGoing Inc., 2012-2015 Flask, Flask, Flask. Oh no, Django again Ezhome Inc., early 2015 Django REST Framework, okay
p t > -hell in templates Hard to maintain across distributed team One developer -> one code style, X developers -> X code styles Hard to maintain between projects Same v e n d o r / directories, no dependencies management
s r c = " / p a t h / t o / u n d e r s c o r e . j s " t y p e = " t e x t / j a v a s c r i p t " > < / s c r i p t > < s c r i p t t y p e = " t e x t / j a v a s c r i p t " > _ . e a c h ( d o c u m e n t . g e t E l e m e n t s B y T a g N a m e ( " a " ) , f u n c t i o n ( i t e m ) { i f ( i t e m . h r e f . i n d e x O f ( " h t t p : / / " ) | | i t e m . h r e f . i n d e x O f ( " h t t p s : / / " ) ) { i t e m . h r e f = " / g o ? " + i t e m . h r e f ; i t e m . o n c l i c k = f u n c t i o n ( ) { i t e m . c l a s s L i s t . a d d ( " v i s i t e d - l i n k " ) ; r e t u r n F a l s e ; } } } ) ; . . . < / s c r i p t >
s r c = " / p a t h / t o / b u n d l e . j s " t y p e = " t e x t / j a v a s c r i p t " > < / s c r i p t > < s c r i p t t y p e = " t e x t / j a v a s c r i p t " > p r o c e s s E x t e r n a l L i n k s ( d o c u m e n t . g e t E l e m e n t s B y T a g N a m e ( " a " ) ) ; < / s c r i p t >
e a c h } f r o m " u n d e r s c o r e " ; f u n c t i o n h a n d l e E x t e r n a l L i n k C l i c k ( e v t ) { e v t . p r e v e n t D e f a u l t ( ) ; e v t . t a r g e t . c l a s s L i s t . a l l ( " v i s i t e d - l i n k " ) ; } e x p o r t f u n c t i o n p r o c e s s E x t e r n a l L i n k s ( e l e m e n t s ) { e a c h ( e l e m e n t s , i t e m = > { i f ( / ^ h t t p s ? \ : \ / \ / / . t e s t ( i t e m . h r e f ) ) { i t e m . h r e f = " / g o ? " + i t e m . h r e f ; i t e m . a d d E v e n t L i s t e n e r ( " c l i c k " , h a n d l e E x t e r a n l L i n k C l i c k ) ; } } ) ; } e x p o r t d e f a u l t { p r o c e s s E x t e r n a l L i n k s : p r o c e s s E x t e r n a l L i n k s } ;
u n c t i o n m y F u n c t i o n ( ) { . . . } e x p o r t d e f a u l t { m y F u n c t i o n : m y F u n c t i o n } ; ./app.js i m p o r t m y L i b r a r y f r o m " . / l i b / m y L i b r a r y " ; i m p o r t { m y F u n c t i o n } f r o m " . / l i b / m y L i b r a r y " ;
s o d e s = [ . . . ] ; c o n s t a N e w H o p e = e p i s o d e s . f i l t e r ( i t e m = > i t e m . e p i s o d e = = = " I V " ) ; c o n s t e p i s o d e T i t l e s = e p i s o d e s . m a p ( i t e m = > { r e t u r n i t e m . t i t l e . t o U p p e r C a s e ( ) ; } )
w H o p e e x t e n d s E p i s o d e { i d : " I V " , n a m e : " A N e w H o p e " , c o n s t r u c t o r ( ) { s u p e r ( ) ; t h i s . d i r e c t e d B y = " G e o r g e L u c a s " ; } r e n d e r ( ) { . . . } } c o n s t a N e w H o p e = n e w A N e w H o p e ( ) ;
i s o d e = ' I V ' ; c o n s t t i t l e = ' A N e w H o p e ' ; ` A l o n g t i m e a g o i n a g a l a x y f a r , f a r a w a y . . . S T A R W A R S E p i s o d e $ { e p i s o d e } $ { t i t l e . t o U p p e r C a s e ( ) } I t i s a p e r i o d o f c i v i l w a r . R e b e l s p a c e s h i p s , s t r i k i n g f r o m a h i d d e n b a s e , h a v e w o n t h e i r f i r s t v i c t o r y a g a i n s t t h e e v i l G a l a c t i c E m p i r e . `
r s t , , t h i r d ] = [ 1 , 2 , 3 , 4 , 5 , 6 ] ; c o n s t { e p i s o d e , t i t l e } = { e p i s o d e : " I V " , t i t l e : " A N e w H o p e " , o p e n i n g : " . . . " } ; c o n s t { e p i s o d e : i d , t i t l e : n a m e } = { . . . } ;
p i n g = n e w M a p ( ) ; m a p . s e t ( " I V " , " A N e w H o p e " ) ; m a p . g e t ( " I V " ) = = = " A N e w H o p e " ; v a r e p i s o d e s = n e w S e t ( ) ; e p i s o d e s . a d d ( " A N e w H o p e " ) . a d d ( " T h e E m p i r e S t r i k e s B a c k " ) . a d d ( " R e t u r n o f t h e J e d i " ) . a d d ( " A N e w H o p e " ) ; e p i s o d e s . h a s ( " A N e w H o p e " ) ; e p i s o d e s . s i z e = = = 3 ;
R e a c t , { C o m p o n e n t } f r o m " r e a c t " ; c l a s s E u r o P y t h o n e x t e n d s C o m p o n e n t { r e n d e r ( ) { r e t u r n ( ; } } R e a c t . r e n d e r ( < d i v > H e l l o , E u r o P y t h o n 2 0 1 5 ! < / d i v > ) < E u r o P y t h o n / > , d o c u m e n t . g e t E l e m e n t B y I d ( " r e a c t - c o n t a i n e r " ) ) ;
u r o P y t h o n e x t e n d s C o m p o n e n t { s t a t e = { c l i c k s : 0 } , h a n d l e C l i c k = ( ) = > { t h i s . s e t S t a t e ( { c l i c k s : t h i s . s t a t e . c l i c k s + 1 } ) ; } , r e n d e r ( ) { c o n s t { c l i c k s } = t h i s . s t a t e ; r e t u r n ( } } R e a c t . r e n d e r ( < d i v > T h i s b u t t o n c l i c k e d { c l i c k s } t i m e ( s ) . < b r / > < b u t t o n o n C l i c k = { t h i s . h a n d l e C l i c k } > C l i c k M e < / b u t t o n > < / d i v > ) < E u r o P y t h o n / > , d o c u m e n t . g e t E l e m e n t B y I d ( " r e a c t - c o n t a i n e r " ) ) ;
a r k d o w n f r o m " . / c o m p o n e n t s / M a r k d o w n " ; c l a s s C o m m e n t F o r m e x t e n d s C o m p o n e n t { s t a t e = { c o m m e n t : " " , p r e v i e w : f a l s e } , h a n d l e C o m m e n t C h a n g e = ( e v t ) = > { t h i s . s e t S t a t e ( { c o m m e n t : e v t . t a r g e t . v a l u e } ) ; } , h a n d l e P r e v i e w C l i c k = ( e v t ) = > { t h i s . s e t S t a t e ( { p r e v i e w : t r u e } ) ; } , r e n d e r ( ) { c o n s t { c o m m e n t , p r e v i e w } = t h i s . s t a t e ; i f ( p r e v i e w ) r e t u r n r e t u r n ( ; } } < M a r k d o w n > { c o m m e n t } < / M a r k d o w n > ; < d i v > < t e x t a r e a o n C h a n g e = { t h i s . h a n d l e C o m m e n t C h a n g e } p l a c e h o l d e r = " Y o u r C o m m e n t " v a l u e = { c o m m e n t } / > < b u t t o n o n C l i c k = { t h i s . h a n d l e P r e v i e w C l i c k } > P r e v i e w < / b u t t o n > < / d i v > )
m m e n t s e x t e n d s C o m p o n e n t { s t a t e = { d a t a : [ ] , s t a t u s : n u l l } , c o m p o n e n t D i d M o u n t ( ) { t h i s . l o a d D a t a ( ) ; } , l o a d D a t a = ( ) = > { f e t c h ( a p i U r l ) . t h e n ( r e s p o n s e = > { i f ( r e s p o n s e . o k ( ) ) { r e t u r n P r o m i s e . r e s o l v e ( r e s p o n s e . j s o n ( ) ) ; } r e t u r n P r o m i s e . r e j e c t ( n e w E r r o r ( r e s p o n s e . s t a t u s T e x t | | r e s p o n s e . s t a t u s ) ) ; } ) . t h e n ( j s o n = > { t h i s . s e t S t a t e ( { d a t a : j s o n , s t a t u s : t r u e } ) ; } , ( ) = > { t h i s . s e t S t a t e ( { d a t a : [ ] , s t a t u s : f a l s e } ) ; } ) ) ; } , . . .
e r ( ) { c o n s t { d a t a , s t a t u s } = t h i s . s t a t e ; i f ( s t a t u s = = = n u l l ) { . . . / / L o a d i n g } e l s e i f ( s t a t u s = = = f a l s e ) { . . . / / S e r v e r e r r o r } e l s e i f ( ! d a t a . l e n g t h ) { . . . / / E m p t y d a t a } e l s e { . . . / / V a l i d d a t a } } }
o m m e n t s e x t e n d s C o m p o n e n t { . . . r e n d e r ( ) { c o n s t c o n t e n t = t h i s . s t a t e . d a t a . m a p ( i t e m = > ( ) ; } } c l a s s C o m m e n t e x t e n d s C o m p o n e n t { s t a t i c d e f a u l t P r o p s = { d a t a : { } } , p r o p T y p e s = { d a t a : P r o p T y p e s . s h a p e ( { . . . } ) } , r e n d e r ( ) { r e t u r n ( . . . ) } } < C o m m e n t d a t a = { i t e m } k e y = { " c o m m e n t - " + i t e m . i d } / > )
is Dumb Component Higher Order Components Data loading Events handling Dumb Components Set of reusable Components Shareable across one and many projects
m p o r t a s y n c i o @ a s y n c i o . c o r o u t i n e d e f h e l l o ( ) : r e t u r n " H e l l o , w o r l d ! " l o o p = a s y n c i o . g e t _ e v e n t _ l o o p ( ) c o n t e n t = l o o p . r u n _ u n t i l _ c o m p l e t e ( h e l l o ( ) ) p r i n t ( c o n t e n t ) l o o p . c l o s e ( ) Included in Python 3.4 and later Available in Python 3.3 with $ p i p i n s t a l l a s y n c i o Backported to Python 2.7 as trollius (I don't recommend to use it anyway)
6 . 5 http://aiohttp.readthedocs.org/ i m p o r t a s y n c i o i m p o r t a i o h t t p @ a s y n c i o . c o r o u t i n e d e f f e t c h _ p a g e ( u r l ) : r e s p o n s e = y i e l d f r o m a i o h t t p . r e q u e s t ( ' G E T ' , u r l ) a s s e r t r e s p o n s e . s t a t u s = = 2 0 0 r e t u r n ( y i e l d f r o m r e s p o n s e . r e a d ( ) ) l o o p = a s y n c i o . g e t _ e v e n t _ l o o p ( ) c o n t e n t = l o o p . r u n _ u n t i l _ c o m p l e t e ( f e t c h _ p a g e ( ' h t t p : / / e p 2 0 1 5 . e u r o p y t h o n . e u / ' ) ) p r i n t ( c o n t e n t ) l o o p . c l o s e ( )
r t a s y n c i o f r o m a i o h t t p i m p o r t w e b @ a s y n c i o . c o r o u t i n e d e f h e l l o ( r e q u e s t ) : r e t u r n w e b . R e s p o n s e ( b o d y = ' H e l l o , w o r l d ! ' , c o n t e n t _ t y p e = ' t e x t / p l a i n ' ) a p p = w e b . A p p l i c a t i o n ( ) a p p . r o u t e r . a d d _ r o u t e ( ' G E T ' , ' / ' , h e l l o ) $ g u n i c o r n - k a i o h t t p . w o r k e r . G u n i c o r n W e b W o r k e r - w 9 - t 6 0 a p p : a p p
. 7 . 0 http://aiopg.readthedocs.org/ i m p o r t a s y n c i o f r o m a i o p g i m p o r t c r e a t e _ p o o l @ a s y n c i o . c o r o u t i n e d e f h e l l o ( d s n ) : p o o l = y i e l d f r o m c r e a t e _ p o o l ( d s n ) w i t h ( y i e l d f r o m p o o l . c u r s o r ( ) ) a s c u r s o r : y i e l d f r o m c u r s o r . e x e c u t e ( ' S E L E C T 1 ' ) s e l e c t e d = y i e l d f r o m c u r s o r . f e t c h o n e ( ) a s s e r t s e l e c t e d = = ( 1 , ) l o o p = a s y n c i o . g e t _ e v e n t _ l o o p ( ) l o o p . r u n _ u n t i l _ c o m p l e t e ( h e l l o ( ' d b n a m e = a i o p g u s e r = . . . p a s s w o r d = . . . h o s t = . . . ' ) ) l o o p . c l o s e ( )
i o r e d i s from a i o - l i b s Latest version: 0 . 1 . 5 http://aioredis.readthedocs.org/ a s y n c i o _ r e d i s from third-party developers Latest version: 0 . 1 3 . 4 http://asyncio-redis.readthedocs.org/
be a coroutine, and return w e b . R e s p o n s e i m p o r t a s y n c i o f r o m a i o h t t p i m p o r t w e b @ a s y n c i o . c o r o u t i n e d e f i n d e x ( r e q u e s t ) : r e t u r n w e b . R e s p o n s e ( b o d y = ' H e l l o , w o r l d ! ' , c o n t e n t _ t y p e = ' t e x t / p l a i n ' ) It's good idea to put all view functions to v i e w s . p y module
. A p p l i c a t i o n And register handler for a request f r o m a i o h t t p i m p o r t w e b f r o m . i m p o r t v i e w s a p p = w e b . A p p l i c a t i o n ( ) a p p . r o u t e r . a d d _ r o u t e ( ' G E T ' , ' / ' , v i e w s . i n d e x ) Obvious to put application code to a p p . p y module
to use Gunicorn $ g u n i c o r n - b 0 . 0 . 0 . 0 : 8 0 0 0 - k a i o h t t p . w o r k e r . G u n i c o r n W e b W o r k e r - w 9 - t 6 0 p r o j e c t . a p p : a p p Add - - r e l o a d flag to automatically reload Gunicorn server on code change
c i o . c o r o u t i n e d e f s e a r c h ( r e q u e s t ) : " " " S e a r c h b y q u e r y f r o m G E T p a r a m s . " " " q u e r y = r e q u e s t . G E T [ ' q u e r y ' ] l o c a l e = r e q u e s t . G E T . g e t ( ' l o c a l e ' , ' u k _ U A ' ) . . . r e t u r n w e b . R e s p o n s e ( . . . )
c i o . c o r o u t i n e d e f s u b m i t ( r e q u e s t ) : " " " S u b m i t f o r m P O S T d a t a . " " " d a t a = y i e l d f r o m r e q u e s t . p o s t ( ) # N o w P O S T d a t a a v a i l a b l e a s ` ` r e q u e s t . P O S T ` ` . . . r e t u r n w e b . R e s p o n s e ( . . . )
o u t e r . a d d _ r o u t e ( ' G E T ' , ' / s e a r c h ' , v i e w s . s e a r c h ) a p p . r o u t e r . a d d _ r o u t e ( ' P O S T ' , ' / s u b m i t ' , v i e w s . s u b m i t )
c i o . c o r o u t i n e d e f p r o j e c t ( r e q u e s t ) : p r o j e c t _ i d = r e q u e s t . m a t c h _ i n f o [ ' p r o j e c t _ i d ' ] . . . r e t u r n w e b . R e s p o n s e ( . . . )
o u t e r . a d d _ r o u t e ( ' G E T ' , ' / p r o j e c t s / { p r o j e c t _ i d } ' , v i e w s . p r o j e c t ) Or even, a p p . r o u t e r . a d d _ r o u t e ( ' G E T ' , ' / p r o j e c t s / { p r o j e c t _ i d : \ d + } ' , v i e w s . p r o j e c t )
p . r o u t e r . a d d _ r o u t e ( ' G E T ' , ' / p r o j e c t s ' , v i e w s . p r o j e c t s , n a m e = ' p r o j e c t s ' ) a p p . r o u t e r . a d d _ r o u t e ( ' P O S T ' , ' / p r o j e c t s ' , v i e w s . a d d _ p r o j e c t )
s y n c i o . c o r o u t i n e d e f a d d _ p r o j e c t ( r e q u e s t ) : d a t a = y i e l d f r o m r e q u e s t . p o s t ( ) . . . u r l = r e q u e s t . a p p . r o u t e r [ ' p r o j e c t s ' ] . u r l ( ) r e t u r n w e b . H T T P F o u n d ( u r l ) @ a s y n c i o . c o r o u t i n e d e f p r o j e c t s ( r e q u e s t ) : . . .
p i m p o r t a p p Or f r o m f l a s k i m p o r t c u r r e n t _ a p p either Request contains a p p instance for all your needs In app.py, f r o m . i m p o r t s e t t i n g s . . . a p p [ ' s e t t i n g s ' ] = s e t t i n g s
p i m p o r t a p p In views.py, @ a s y n c i o . c o r o u t i n e d e f s e a r c h ( r e q u e s t ) : s e t t i n g s = r e q u e s t . a p p [ ' s e t t i n g s ' ] q u e r y = r e q u e s t . G E T [ ' q u e r y ' ] l o c a l e = r e q u e s t . G E T . g e t ( ' l o c a l e ' , s e t t i n g s . D E F A U L T _ L O C A L E ) . . . r e t u r n w e b . R e s p o n s e ( . . . )
c a t i o n accepts optional middlewares factories sequence Middleware Factory should be a coroutine and returns a coroutine In app.py, @ a s y n c i o . c o r o u t i n e d e f t r i v i a l _ m i d d l e w a r e ( a p p , h a n d l e r ) : @ a s y n c i o . c o r o u t i n e d e f m i d d l e w a r e ( r e q u e s t ) : r e t u r n ( y i e l d f r o m h a n d l e r ( r e q u e s t ) ) r e t u r n m i d d l e w a r e . . . a p p = w e b . A p p l i c a t i o n ( m i d d l e w a r e s = [ t r i v i a l _ m i d d l e w a r e ] )
h t t p _ s e s s i o n Debug Toolbar, a i o h t t p _ d e b u g t o o l b a r In app.py, i m p o r t a i o h t t p _ d e b u g t o o l b a r f r o m a i o h t t p _ d e b u g t o o l b a r i m p o r t t o o l b a r _ m i d d l e w a r e _ f a c t o r y f r o m a i o h t t p _ s e s s i o n i m p o r t s e s s i o n _ m i d d l e w a r e f r o m a i o h t t p _ s e s s i o n . c o o k i e _ s t o r a g e i m p o r t E n c r y p t e d C o o k i e S t o r a g e a p p = w e b . A p p l i c a t i o n ( m i d d l e w a r e s = [ t o o l b a r _ m i d d l e w a r e _ f a c t o r y , s e s s i o n _ m i d d l e w a r e ( E n c r y p t e d C o o k i e S t o r a g e ( b ' 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 ' ) ) ] ) a i o h t t p _ d e b u g t o o l b a r . s e t u p ( a p p )
c i o . c o r o u t i n e d e f e r r o r h a n d l e r _ m i d d l e w a r e ( a p p , h a n d l e r ) : @ a s y n c i o . c o r o u t i n e d e f m i d d l e w a r e ( r e q u e s t ) : t r y : r e t u r n ( y i e l d f r o m h a n d l e r ( r e q u e s t ) ) e x c e p t w e b . H T T P E r r o r a s e r r : # A s i t s p e c i a l c a s e w e c o u l d p a s s ` ` e r r ` ` a s s e c o n d a r g u m e n t t o # e r r o r h a n d l e r r e t u r n ( y i e l d f r o m v i e w s . e r r o r ( r e q u e s t , e r r ) ) r e t u r n m i d d l e w a r e
Supports storing session data in encrypted cookie or redis Enabled by passing s e s s i o n _ m i d d l e w a r e to middleware factories sequence In views.py, f r o m a i o h t t p _ s e s s i o n i m p o r t g e t _ s e s s i o n @ a s y n c i o . c o r o u t i n e d e f l o g i n ( r e q u e s t ) : . . . s e s s i o n = y i e l d f r o m g e t _ s e s s i o n ( r e q u e s t ) s e s s i o n [ ' u s e r _ i d ' ] = u s e r _ i d r e t u r n w e b . R e s p o n s e ( . . . )
Jinja2 Support In app.py, i m p o r t a i o h t t p _ j i n j a 2 i m p o r t j i n j a 2 . . . a i o h t t p _ j i n j a 2 . s e t u p ( a p p , l o a d e r = j i n j a 2 . F i l e S y s t e m L o a d e r ( ' / p a t h / t o / t e m p l a t e s ' ) )
r t a i o h t t p _ j i n j a 2 @ a i o h t t p _ j i n j a 2 . t e m p l a t e ( ' i n d e x . h t m l ' ) d e f i n d e x ( r e q u e s t ) : r e t u r n { ' i s _ i n d e x ' : T r u e }
a i o h t t p _ j i n j a 2 i m p o r t r e n d e r _ t e m p l a t e @ a s y n c i o . c o r o u t i n e d e f i n d e x ( r e q u e s t ) : r e t u r n r e n d e r _ t e m p l a t e ( ' i n d e x . h t m l ' , r e q u e s t , { ' i s _ i n d e x ' : T r u e } )
u j s o n f r o m a i o h t t p i m p o r t w e b d e f j s o n _ r e s p o n s e ( d a t a , * * k w a r g s ) : # S o m e t i m e s u s e r n e e d s t o o v e r r i d e d e f a u l t c o n t e n t t y p e f o r J S O N k w a r g s . s e t d e f a u l t ( ' c o n t e n t _ t y p e ' , ' a p p l i c a t i o n / j s o n ' ) r e t u r n w e b . R e s p o n s e ( u j s o n . d u m p s ( d a t a ) , * * k w a r g s ) Note: I recommend to use ujson for work with JSON data in Python, cause of speed.
t i l s i m p o r t j s o n _ r e s p o n s e @ a s y n c i o . c o r o u t i n e d e f a p i _ b r o w s e r ( r e q u e s t ) : r e t u r n j s o n _ r e s p o n s e ( { ' p r o j e c t s _ u r l ' : r e q u e s t . a p p . r o u t e r [ ' p r o j e c t s ' ] . u r l ( ) , } )
Apache, or other web server for serving static files in production. In app.py, a p p . r o u t e r . a d d _ s t a t i c ( ' / s t a t i c ' , ' / p a t h / t o / s t a t i c ' , n a m e = ' s t a t i c ' )
t t p _ j i n j a 2 . t e m p l a t e ( ' i n d e x . h t m l ' ) d e f i n d e x ( r e q u e s t ) : r e t u r n { ' a p p ' : r e q u e s t . a p p , ' i s _ i n d e x ' : T r u e }
p t s r c = " { { a p p . r o u t e r . s t a t i c . u r l ( f i l e n a m e = " d i s t / j s / p r o j e c t . j s " ) } } " t y p e = " t e x t / j a v a s c r i p t " > < / s c r i p t >
n t e x t l i b i m p o r t c o n t e x t m a n a g e r @ c o n t e x t m a n a g e r d e f a d d _ r o u t e _ c o n t e x t ( a p p , v i e w s , u r l _ p r e f i x = N o n e , n a m e _ p r e f i x = N o n e ) : d e f a d d _ r o u t e ( m e t h o d , u r l , n a m e ) : v i e w = g e t a t t r ( v i e w s , n a m e ) u r l = ( ' / ' . j o i n ( ( u r l _ p r e f i x . r s t r i p ( ' / ' ) , u r l . l s t r i p ( ' / ' ) ) ) i f u r l _ p r e f i x e l s e u r l ) n a m e = ' . ' . j o i n ( ( n a m e _ p r e f i x , n a m e ) ) i f n a m e _ p r e f i x e l s e n a m e r e t u r n a p p . r o u t e r . a d d _ r o u t e ( m e t h o d , u r l , v i e w , n a m e = n a m e ) r e t u r n a d d _ r o u t e
. a p i i m p o r t v i e w s a s a p i _ v i e w s w i t h a d d _ r o u t e _ c o n t e x t ( a p p , a p i _ v i e w s , ' / a p i ' , ' a p i ' ) a s a d d _ r o u t e : a d d _ r o u t e ( ' G E T ' , ' / ' , ' i n d e x ' ) a d d _ r o u t e ( ' G E T ' , ' / p r o j e c t s ' , ' p r o j e c t s ' ) a d d _ r o u t e ( ' P O S T ' , ' / p r o j e c t s ' , ' a d d _ p r o j e c t ' ) a d d _ r o u t e ( ' G E T ' , ' / p r o j e c t / { p r o j e c t _ i d : \ d + } ' , ' p r o j e c t ' ) a d d _ r o u t e ( ' P U T ' , ' / p r o j e c t / { p r o j e c t _ i d : \ d + } ' , ' e d i t _ p r o j e c t ' ) a d d _ r o u t e ( ' D E L E T E ' , ' / p r o j e c t / { p r o j e c t _ i d : \ d + } ' , ' d e l e t e _ p r o j e c t ' )
r t a s y n c i o f r o m . . u t i l s i m p o r t j s o n _ r e s p o n s e @ a s y n c i o . c o r o u t i n e d e f i n d e x ( r e q u e s t ) : r o u t e r = r e q u e s t . a p p . r o u t e r p r o j e c t _ u r l = r o u t e r [ ' a p i . p r o e j c t ' ] . u r l ( p a r t s = { ' p r o j e c t _ i d ' : 4 2 } ) p r o j e c t _ u r l = p r o j e c t _ u r l . r e p l a c e ( ' 4 2 ' , ' { p r o j e c t _ i d } ' ) r e t u r n j s o n _ r e s p o n s e ( { ' u r l s ' : { ' a d d _ p r o j e c t ' : r o u t e r [ ' a p i . a d d _ p r o j e c t ' ] . u r l ( ) , ' p r o j e c t ' : p r o j e c t _ u r l , ' p r o j e c t s ' : r o u t e r [ ' a p i . p r o j e c t s ' ] . u r l ( ) , } } )
n g T y p e P r o x y Settings shouldn't be changed across the app Welcome, rororo.settings In app.py, f r o m r o r o r o . s e t t i n g s i m p o r t i m m u t a b l e _ s e t t i n g s f r o m . i m p o r t s e t t i n g s d e f c r e a t e _ a p p ( * * o p t i o n s ) : s e t t i n g s _ d i c t = i m m u t a b l e _ s e t t i n g s ( s e t t i n g s , * * o p t i o n s ) a p p = w e b . A p p l i c a t i o n ( ) a p p [ ' s e t t i n g s ' ] = s e t t i n g s _ d i c t . . . r e t u r n a p p
c t _ s e t t i n g s s e t u p _ l o c a l e s e t u p _ l o g g i n g s e t u p _ t i m e z o m e t o _ b o o l rororo.logger d e f a u l t _ l o g g i n g _ d i c t u p d a t e _ s e n t r y _ l o g g i n g
A p p l i c a t i o n ( w e b . A p p l i c a t i o n ) : d e f _ _ i n i t _ _ ( s e l f , * * k w a r g s ) : s e l f [ ' s e t t i n g s ' ] = k w a r g s . p o p ( ' s e t t i n g s ' ) s u p e r ( ) . _ _ i n i t _ _ ( * * k w a r g s ) d e f m a k e _ h a n d l e r ( s e l f , * * k w a r g s ) : k w a r g s [ ' d e b u g ' ] = s e l f [ ' s e t t i n g s ' ] [ ' D E B U G ' ] k w a r g s [ ' l o o p ' ] = s e l f . l o o p r e t u r n s e l f . _ h a n d l e r _ f a c t o r y ( s e l f , s e l f . r o u t e r , * * k w a r g s )
JSON Schema for validation Describe Schemas with jsl Welcome, rororo.schemas In api/views.py, f r o m r o r o r o . s c h e m a s i m p o r t S c h e m a f r o m . i m p o r t s c h e m a s @ a s y n c i o . c o r o u t i n e d e f a d d _ p r o j e c t ( r e q u e s t ) : s c h e m a = S c h e m a ( s c h e m a s . a d d _ p r o j e c t , r e s p o n s e _ f a c t o r y = j s o n _ r e s p o n s e ) d a t a = s c h e m a . v a l i d a t e _ r e q u e s t ( ( y i e l d f r o m r e q u e s t . p o s t ( ) ) ) . . . r e t u r n s c h e m a . m a k e _ r e s p o n s e ( p r o j e c t _ d i c t )
s l i m p o r t D o c u m e n t , I n t e g e r F i e l d , S t r i n g F i e l d c l a s s P r o j e c t ( D o c u m e n t ) : n a m e = S t r i n g F i e l d ( m i n _ l e n g t h = 1 , m a x _ l e n g t h = 3 2 , r e q u i r e d = T r u e ) s l u g = S t r i n g F i e l d ( m i n _ l e n g t h = 1 , m a x _ l e n g t h = 3 2 , r e q u i r e d = T r u e ) d e s c r i p t i o n = S t r i n g F i e l d ( m a x _ l e n g t h = 2 5 5 ) c l a s s R e s p o n s e ( P r o j e c t ) : i d = I n t e g e r F i e l d ( m i n i m u m = 0 , r e q u i r e d = T r u e ) r e q u e s t = P r o j e c t . g e t _ s c h e m a ( ) r e s p o n s e = R e s p o n s e . g e t _ s c h e m a ( ) Or use plain Python dicts instead
step in right direction Many tools around JS is maturing too Bundling is easy, meet webpack Linting is easy, meet eslint Making UI is easy, meet react And I still not talking about DX tools :)
Use Python 3.4 for all good things a i o h t t p . w e b , easy to start and easy to use a i o p g . s a allows you to forget about ORM r o r o r o contains useful helpers for a i o h t t p . w e b apps If you miss something, port it to Asyncio stack by yourself Don't forget to payback to Open Source Software
f l o g o u t ( r e q u e s t ) : s e s s i o n = a w a i t g e t _ s e s s i o n ( r e q u e s t ) s e s s i o n . i n v a l i d a t e ( ) r e t u r n R e s p o n s e ( s t a t u s = 2 0 4 ) a s y n c d e f p r o j e c t s ( r e q u e s t ) : p r o j e c t s = [ ] a s y n c w i t h c r e a t e _ e n g i n e ( D S N ) a s c o n n : q u e r y = . . . a s y n c f o r p r o j e c t i n c o n n . e x e c u t e ( q u e r y ) : p r o j e c t s . a p p e n d ( p r o j e c t ) r e t u r n j s o n _ r e s p o n s e ( p r o j e c t s )