$30 off During Our Annual Pro Sale. View Details »

Asyncio Stack & React.js or Development on the Edge

Asyncio Stack & React.js or Development on the Edge

Slides from my EuroPython 2015 talk about developing modern web applications with React.js on frontend and Python 3 Asyncio stack on backend

Igor Davydenko

July 20, 2015
Tweet

More Decks by Igor Davydenko

Other Decks in Programming

Transcript

  1. Asyncio Stack & React.js
    or Development on the Edge
    Igor Davydenko
    EuroPython 2015

    View Slide

  2. Intro

    View Slide

  3. I am...
    Igor Davydenko
    Python & React.js developer
    From Kyiv, Ukraine
    Works on Ezhome Inc.
    Primarly designs & develops backend API
    Personal Site
    @ GitHub
    @ Twitter

    View Slide

  4. My Path
    Everything started from Microsoft FrontPage, early 2002
    Met 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

    View Slide

  5. My Path
    Outsorcing career, 2008-2011
    Django, Django, Django
    oDesk PS, 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

    View Slide

  6. In Total
    Python developer for past 8 years
    Using Django from 0.96
    Using Flask from 0.7
    Still not satisfied

    View Slide

  7. View Slide

  8. Hello, JavaScript!

    View Slide

  9. View Slide

  10. JavaScript was bad
    Prototype was big and hard
    jQuery was small and easy. Somewhen, decades ago
    jQuery UI :(
    jQuery plugins :( :(

    View Slide

  11. JavaScript was bad
    My motto was: Let someone else make frontend Tasks
    Backbone? Okay, but not in big teams
    Angular? No, no, no. Just no
    Vanilla JS? Cool, but not in big teams

    View Slide

  12. JavaScript problems
    No standart modules
    <
    s
    c
    r
    i
    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

    View Slide

  13. But then...
    node.js happens
    npm installs dependencies
    CommonJS allows reuse your code
    browserify builds bundles from your code
    jshint/jslint/jsrc lints your code
    Even some people starts write backends in node.js

    View Slide

  14. Before
    In template.html,
    <
    s
    c
    r
    i
    p
    t 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
    >

    View Slide

  15. Now
    In template.html,
    <
    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
    >

    View Slide

  16. Now
    In js/external-links.js,
    i
    m
    p
    o
    r
    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
    }
    ;

    View Slide

  17. Welcome ECMAScript 2015
    Previously known as ES6

    View Slide

  18. ES2015. Modules
    ./lib/myLibrary.js
    e
    x
    p
    o
    r
    t f
    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
    "
    ;

    View Slide

  19. ES2015. Let + Const
    c
    o
    n
    s
    t u
    n
    c
    h
    a
    n
    g
    a
    b
    l
    e = t
    r
    u
    e
    ;
    l
    e
    t c
    h
    a
    n
    g
    e
    a
    b
    l
    e
    ;
    c
    h
    a
    n
    g
    e
    a
    b
    l
    e = t
    r
    u
    e
    ;
    u
    n
    c
    h
    a
    n
    g
    e
    a
    b
    l
    e = f
    a
    l
    s
    e
    ; /
    / E
    r
    r
    o
    r

    View Slide

  20. ES2015. Arrows
    c
    o
    n
    s
    t e
    p
    i
    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
    (
    )
    ;
    }
    )

    View Slide

  21. ES2015. Classes
    c
    l
    a
    s
    s A
    N
    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
    (
    )
    ;

    View Slide

  22. ES2015. Template Strings
    c
    o
    n
    s
    t e
    p
    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
    .
    `

    View Slide

  23. ES2015. Destructing
    c
    o
    n
    s
    t [
    f
    i
    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
    } = {
    .
    .
    .
    }
    ;

    View Slide

  24. ES2015. Map + Set
    v
    a
    r m
    a
    p
    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
    ;

    View Slide

  25. And More
    Learn ES2015
    Default + Rest + Spread
    Iterators + For..Of
    Generators
    Improved Unicode
    Module Loaders
    Proxies
    Symbols
    ...

    View Slide

  26. And More
    ES2016, ES2017, ...
    Comprehensions
    Class Properties
    Function Bind
    Async Functions
    Decorators
    ...

    View Slide

  27. View Slide

  28. How to Use?
    Use Babel for all good things!
    Supports browserify, webpack, ...
    Emerges eslint as your one and only JS linter

    View Slide

  29. So here comes React.js

    View Slide

  30. React.js
    Painless UI Framework
    Virtual DOM
    One-way reactive data flow
    Has a strong community around

    View Slide

  31. React.js. A Simple Component
    i
    m
    p
    o
    r
    t 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
    "
    )
    )
    ;

    View Slide

  32. React.js. A Stateful Component
    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 {
    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
    "
    )
    )
    ;

    View Slide

  33. React.js. Using Components
    i
    m
    p
    o
    r
    t M
    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
    >
    )

    View Slide

  34. React.js. Fetching data
    c
    l
    a
    s
    s C
    o
    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
    }
    )
    ;
    }
    )
    )
    ;
    }
    ,
    .
    .
    .

    View Slide

  35. React.js. Fetching data
    .
    .
    .
    r
    e
    n
    d
    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
    }
    }
    }

    View Slide

  36. React.js. One-way data binding
    c
    l
    a
    s
    s C
    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
    } /
    >
    )

    View Slide

  37. React.js. One-way data binding
    Comments is Higher Order Component
    Comment is Dumb Component
    Higher Order Components
    Data loading
    Events handling
    Dumb Components
    Set of reusable Components
    Shareable across one and many projects

    View Slide

  38. And More
    React DOM is separate package from 0.14
    React Native, React Canvas
    Routing via react-router
    Reusable Components
    react-bootstrap
    react-dnd
    Flux
    Relay
    GraphQL

    View Slide

  39. View Slide

  40. JavaScript is good now,
    but what about Python?

    View Slide

  41. Let me introduce Asyncio Stack

    View Slide

  42. asyncio
    Asynchronous I/O, event loop, coroutines, and tasks
    https://docs.python.org/3/library/asyncio.html
    i
    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)

    View Slide

  43. aiohttp
    HTTP client/server for asyncio
    Latest version: 0
    .
    1
    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
    (
    )

    View Slide

  44. aiohttp.web
    Web framework for asyncio
    http://aiohttp.readthedocs.org/en/v0.16.5/web.html
    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 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

    View Slide

  45. aiopg
    Accessing PostgreSQL database from the asyncio
    Latest version: 0
    .
    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
    (
    )

    View Slide

  46. aioredis / asyncio_redis
    Accessing Redis datasotre from the asyncio
    a
    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/

    View Slide

  47. And many others
    Python Asyncio Resources
    MySQL: aiomysql
    Mongo: asyncio_mongo
    CouchDB: aiocouchdb
    ElasticSearch: aioes
    Memcached: aiomcache
    AMQP: aioamqp
    ØMQ: aiozmq

    View Slide

  48. And many others
    All Asyncio projects @ PyPI
    S3: aio-s3
    SSH: asyncssh
    Autobahn, WebSocket & WAMP
    RxPY, Reactive Extensions for Python
    Pulsar, Concurrent framework for Python

    View Slide

  49. Even web-frameworks available
    muffin
    Induction
    Spanner.py
    Growler

    View Slide

  50. aiohttp.web

    View Slide

  51. Architecture
    All starts from view functions (handlers)
    View functions should 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

    View Slide

  52. Architecture
    Next you need to create an w
    e
    b
    .
    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

    View Slide

  53. Architecture
    Now you ready to serve your application
    I recommend 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

    View Slide

  54. Handling GET/POST data
    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
    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
    (
    .
    .
    .
    )

    View Slide

  55. Handling GET/POST data
    In views.py,
    @
    a
    s
    y
    n
    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
    (
    .
    .
    .
    )

    View Slide

  56. Handling GET/POST data
    In app.py,
    a
    p
    p
    .
    r
    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
    )

    View Slide

  57. Handling variable routes
    In views.py,
    @
    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
    (
    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
    (
    .
    .
    .
    )

    View Slide

  58. Handling variable routes
    In app.py,
    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
    }
    '
    , 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
    )

    View Slide

  59. Named routes, reverse constructing, and redirect
    In app.py,
    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
    '
    , 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
    )

    View Slide

  60. Named routes, reverse constructing, and redirect
    In views.py,
    @
    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
    )
    :
    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
    )
    :
    .
    .
    .

    View Slide

  61. You don't need to f
    r
    o
    m a
    p
    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

    View Slide

  62. You don't need to f
    r
    o
    m a
    p
    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
    (
    .
    .
    .
    )

    View Slide

  63. Middlewares
    w
    e
    b
    .
    A
    p
    p
    l
    i
    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
    ]
    )

    View Slide

  64. Middlewares
    Ready to use Middlewares
    User Sessions, a
    i
    o
    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
    )

    View Slide

  65. Middlewares
    Handling Exceptions
    In app.py,
    @
    a
    s
    y
    n
    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

    View Slide

  66. User Sessions
    aiohttp_session
    Latest version: 0
    .
    1
    .
    1
    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
    (
    .
    .
    .
    )

    View Slide

  67. Rendering Templates
    Jinja2 & Mako supported via aiohttp_jinja2 & aiohttp_mako
    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
    '
    )
    )

    View Slide

  68. Rendering Templates
    Jinja2 Support
    In views.py,
    i
    m
    p
    o
    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
    }

    View Slide

  69. Rendering Templates
    Jinja2 Support
    In views.py,
    f
    r
    o
    m 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
    }
    )

    View Slide

  70. Rendering JSON
    In utils.py,
    i
    m
    p
    o
    r
    t 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.

    View Slide

  71. Rendering JSON
    In views.py,
    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 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
    (
    )
    ,
    }
    )

    View Slide

  72. Serving Static Files
    Important: It's highly recommend to use nginx, 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
    '
    )

    View Slide

  73. Serving Static Files
    In views.py,
    @
    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 {
    '
    a
    p
    p
    '
    : r
    e
    q
    u
    e
    s
    t
    .
    a
    p
    p
    , '
    i
    s
    _
    i
    n
    d
    e
    x
    '
    : T
    r
    u
    e
    }

    View Slide

  74. Serving Static Files
    In index.html,
    <
    s
    c
    r
    i
    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
    >

    View Slide

  75. And More
    WebSockets
    Expect Header
    Custom Conditions for Routes Lookup
    Class Based Handlers
    And I say it again, WebSockets

    View Slide

  76. View Slide

  77. Real World Usage

    View Slide

  78. Structure
    yourproject
    api
    storage.py
    views.py
    auth
    api.py
    views.py
    static
    templates
    app.py
    settings.py
    storage.py
    views.py

    View Slide

  79. Add Route Context Manager
    f
    r
    o
    m c
    o
    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

    View Slide

  80. Add Route Context Manager
    In app.py,
    f
    r
    o
    m .
    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
    '
    )

    View Slide

  81. Add Route Context Manager
    In api/views.py,
    i
    m
    p
    o
    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
    (
    )
    ,
    }
    }
    )

    View Slide

  82. Immutable Settings
    Python 3.3+ has M
    a
    p
    p
    i
    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

    View Slide

  83. Other Settings & Logging Helpers
    rororo.settings
    i
    n
    j
    e
    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

    View Slide

  84. Supports DEBUG Mode from Settings
    c
    l
    a
    s
    s 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
    )

    View Slide

  85. Schemas
    You need to validate request & response data
    Use 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
    )

    View Slide

  86. Schemas
    Describing Schemas
    In api/schemas/add_project.py,
    f
    r
    o
    m j
    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

    View Slide

  87. Schemas
    Describing Schemas
    In api/schemas/__init__.py,
    f
    r
    o
    m . i
    m
    p
    o
    r
    t a
    d
    d
    _
    p
    r
    o
    j
    e
    c
    t # n
    o
    q
    a

    View Slide

  88. Why you might need
    Asyncio Stack?

    View Slide

  89. View Slide

  90. Cause it cool and trendy!

    View Slide

  91. Database-less API

    View Slide

  92. Requests to the external API

    View Slide

  93. Async code execution

    View Slide

  94. Predictable async IO

    View Slide

  95. Summary

    View Slide

  96. JavaScript is quite good right now
    ES2015 is a great 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 :)

    View Slide

  97. Asyncio Stack is ready for usage
    The Future is Here!
    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

    View Slide

  98. View Slide

  99. Questions?

    View Slide

  100. Bonus. Python 3.5
    a
    s
    y
    n
    c d
    e
    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
    )

    View Slide