• Cooperative multitasking
• Built around futures/promises
• Single threaded
• Optimized for concurrent I/O
What is AsyncIO
Slide 8
Slide 8 text
• Cooperative multitasking
• Built around futures/promises
• Single threaded
• Optimized for concurrent I/O
What is AsyncIO
Slide 9
Slide 9 text
• Parallel execution
• Multithreaded
• Performance/speed improvement
• Optimized for computation
What AsyncIO is not
Slide 10
Slide 10 text
• Parallel execution
• Multithreaded
• Performance/speed improvement
• Optimized for computation
What AsyncIO is not
Slide 11
Slide 11 text
• Context switching
• Thread safety
• Control flow
• “How many?”
Why not threads?
Slide 12
Slide 12 text
• Context switching
• Thread safety
• Control flow
• “How many?”
Why not threads?
Slide 13
Slide 13 text
$ python3.7 1-threads.py
1299 runs of fib in 1.0s: 769.83 usec per run
Slide 14
Slide 14 text
No content
Slide 15
Slide 15 text
156 runs of fibs in 1.0s: 6.42 msec per run
151 runs of fibp in 1.0s: 6.65 msec per run
Slide 16
Slide 16 text
156 runs of fibs in 1.0s: 6.44 msec per run
387 runs of fibp in 1.0s: 2.59 msec per run
Slide 17
Slide 17 text
But what about I/O?
Slide 18
Slide 18 text
• Simple TCP server
• Accepts an upper bound k
• “Thinks about it”
• Returns a random integer [0,k]
Randint-as-a-service
$ python3.7 server.py
listening on 8080...
2 runs of many_random in 1.1s: 0.558 sec per run
1 runs of many_random in 1.4s: 1.351 sec per run
1 runs of many_random in 1.2s: 1.241 sec per run
0
0.001
0.002
0.003
0.004
32 64 128 256 512 1024
Slide 24
Slide 24 text
$ python3.7 3-asyncio-client.py
10 runs of get_random in 1.0s: 0.105 sec per run
Slide 25
Slide 25 text
7 runs of async_random in 1.0s: 0.147 sec per run
Slide 26
Slide 26 text
6 runs of async_random in 1.1s: 0.191 sec per run
4 runs of async_random in 1.1s: 0.280 sec per run
3 runs of async_random in 1.4s: 0.467 sec per run
0
0.001
0.002
0.003
0.004
32 64 128 256 512 1024 128 256 512 1024
AsyncIO
Threads
Slide 27
Slide 27 text
How does AsyncIO work?
Slide 28
Slide 28 text
• Object that is not ready, or done
• “done” means success or exception
• Add callbacks, or periodically check state
• Result yields final value, or raise exception
Back to the futures
Slide 29
Slide 29 text
• Object that is not ready, or done
• “done” means success or exception
• Add callbacks, or periodically check state
• Result yields final value, or raise exception
Back to the futures
Slide 30
Slide 30 text
• Like futures, without polling or callbacks
• Object with __await__ method
• Must be “awaited” via await keyword
• Yields value when completed
Awaitables
Slide 31
Slide 31 text
• Asynchronous function
• Dedicated async def syntax
• Returns a coroutine object when called
• Only executes when awaited
Coroutines
Slide 32
Slide 32 text
• Event loop controls execution of pending tasks
• Tasks wrap and await futures automatically
• Tasks are awaitable, yield their wrapped futures
Event loops and tasks
Slide 33
Slide 33 text
• Executes current task until done or blocked
• Next task picked from queue
• Tasks can “starve” other tasks
Event loops and tasks
$ python3.7 5-starvation.py
getting food
full now, took 0.1s
Slide 42
Slide 42 text
getting food
nap time
nap over
full now, took 2.0s
Slide 43
Slide 43 text
getting food
nap time
nap over
full now, took 2.0s
Slide 44
Slide 44 text
getting food
nap time
full now, took 0.1s
nap over
Slide 45
Slide 45 text
No content
Slide 46
Slide 46 text
No content
Slide 47
Slide 47 text
0: counting to 100000
0: ... 99999 ... 100000
1: counting to 100000
1: ... 99999 ... 100000
2: counting to 100000
2: ... 99999 ... 100000
3: counting to 100000
3: ... 99999 ... 100000
Slide 48
Slide 48 text
No content
Slide 49
Slide 49 text
No content
Slide 50
Slide 50 text
0: counting to 100000
1: counting to 100000
2: counting to 100000
3: counting to 100000
0: ... 99999 ... 100000
1: ... 99999 ... 100000
2: ... 99999 ... 100000
3: ... 99999 ... 100000
Slide 51
Slide 51 text
Making AsyncIO useful
Slide 52
Slide 52 text
No content
Slide 53
Slide 53 text
No content
Slide 54
Slide 54 text
No content
Slide 55
Slide 55 text
No content
Slide 56
Slide 56 text
No content
Slide 57
Slide 57 text
No content
Slide 58
Slide 58 text
No content
Slide 59
Slide 59 text
$ curl http://0.0.0.0:8080/randint/25
15
$ curl http://0.0.0.0:8080/randint/2500
2318
$ python 6-aiohttp-server.py
======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)
Slide 60
Slide 60 text
$ python3.7 7-aiohttp-client.py
got (200, 14)
Slide 61
Slide 61 text
$ python3.7 7-aiohttp-client.py
got (200, 14)
Slide 62
Slide 62 text
No content
Slide 63
Slide 63 text
No content
Slide 64
Slide 64 text
No content
Slide 65
Slide 65 text
No content
Slide 66
Slide 66 text
No content
Slide 67
Slide 67 text
$ python3.7 8-aiosqlite.py
sender> Bob
recipient> Alice
message> I need your help.
inserted row id 1
Slide 68
Slide 68 text
row #1 from Bob to Alice: I need your help.
row #2 from Janet to Nina: What time is the developer sync?
row #3 from Nina to Janet: I think it's after the design review.
Slide 69
Slide 69 text
Designing Friendly APIs
Slide 70
Slide 70 text
• Focus on common use cases
• Make interfaces feel natural
• Use the most obvious syntax features
• Support multiple styles if possible
Obvious and natural
• Implement the __await__ special method
Awaitables
Slide 73
Slide 73 text
No content
Slide 74
Slide 74 text
$ python3.7 9-awaitables.py
7
Slide 75
Slide 75 text
$ python3.7 9-awaitables.py
23
5
Slide 76
Slide 76 text
• For use in async for loops
• Each iteration is an async coroutine
• Useful for iteration before all data is ready
• Iterate large, async datasets without blocking
Async Iterables
Slide 77
Slide 77 text
• Similar to normal iterables
• Use __aiter__ to create an iterator
• Use __anext__ to return the next value
• Raise StopAsyncIteration when exhausted
Async Iterables
Slide 78
Slide 78 text
No content
Slide 79
Slide 79 text
No content
Slide 80
Slide 80 text
No content
Slide 81
Slide 81 text
19
15
1
10
20
Slide 82
Slide 82 text
[34, 9, 28]
Slide 83
Slide 83 text
0
20
19
Slide 84
Slide 84 text
• Ephemeral actions, connections, transactions
• Async coroutines at enter and exit
• Ensure clean up on exit or exception
Async Context Managers
Slide 85
Slide 85 text
• Same pattern as regular context managers
• __aenter__ called when entering
• __aexit__ called at exit or exception
Async Context Managers
Slide 86
Slide 86 text
No content
Slide 87
Slide 87 text
$ python3.7 10-contexts.py
row #4 from Jack to Jill: I'm out of water.
row #5 from Jack to Terry: Do you know where my pail is?
Slide 88
Slide 88 text
No content
Slide 89
Slide 89 text
Mix Paradigms
Slide 90
Slide 90 text
Phew...
Slide 91
Slide 91 text
Read the [3.7] docs
Slide 92
Slide 92 text
Experimentation is key
Slide 93
Slide 93 text
Consider your workload
Slide 94
Slide 94 text
Don't be afraid to benchmark
Slide 95
Slide 95 text
Don't cross the streams
Slide 96
Slide 96 text
Don't cross the streams
Slide 97
Slide 97 text
Don't cross the streams
Slide 98
Slide 98 text
ai
o uvloop ai
ess aioredis aiobot
am aiofiles aiosqlite aiopg
s aiounittest aioslack trio uvloop
omysql aiohttp aiomultiprocess aioredis
lack trio uvloop aioitertools aiostream aiofiles a
ltiprocess aioredis aiobotocore aiodns aiounittest aiosl
aiostream aiofiles aiosqlite aiopg aiomysql aiohttp aiomultipro
e aiodns aiounittest aioslack trio uvloop aioitertools aiostream aiof
iopg aiomysql aiohttp aiomultiprocess aioredis aiobotocore aiodns
ack trio uvloop aioitertools aiostream aiofiles aiosqlite aiopg
s aioredis aiobotocore aiodns aiounittest aioslack tr
s aiosqlite aiopg aiomysql aiohttp aiomultipr
slack trio uvloop aioitertools aiostrea
iprocess aioredis aiobotocore
stream aiofiles aiosqli
aiounittest aio
http aio
a
Don't reinvent the wheel
Slide 99
Slide 99 text
ai
o uvloop ai
ess aioredis aiobot
am aiofiles aiosqlite aiopg
s aiounittest aioslack trio uvloop
omysql aiohttp aiomultiprocess aioredis
lack trio uvloop aioitertools aiostream aiofiles a
ltiprocess aioredis aiobotocore aiodns aiounittest aiosl
aiostream aiofiles aiosqlite aiopg aiomysql aiohttp aiomultipro
e aiodns aiounittest aioslack trio uvloop aioitertools aiostream aiof
iopg aiomysql aiohttp aiomultiprocess aioredis aiobotocore aiodns
ack trio uvloop aioitertools aiostream aiofiles aiosqlite aiopg
s aioredis aiobotocore aiodns aiounittest aioslack tr
s aiosqlite aiopg aiomysql aiohttp aiomultipr
slack trio uvloop aioitertools aiostrea
iprocess aioredis aiobotocore
stream aiofiles aiosqli
aiounittest aio
http aio
a
Slide 100
Slide 100 text
ai
o uvloop ai
ess aioredis aiobot
am aiofiles aiosqlite aiopg
s aiounittest aioslack trio uvloop
omysql aiohttp aiomultiprocess aioredis
lack trio uvloop aioitertools aiostream aiofiles a
ltiprocess aioredis aiobotocore aiodns aiounittest aiosl
aiostream aiofiles aiosqlite aiopg aiomysql aiohttp aiomultipro
e aiodns aiounittest aioslack trio uvloop aioitertools aiostream aiof
iopg aiomysql aiohttp aiomultiprocess aioredis aiobotocore aiodns
ack trio uvloop aioitertools aiostream aiofiles aiosqlite aiopg
s aioredis aiobotocore aiodns aiounittest aioslack tr
s aiosqlite aiopg aiomysql aiohttp aiomultipr
slack trio uvloop aioitertools aiostrea
iprocess aioredis aiobotocore
stream aiofiles aiosqli
aiounittest aio
http aio
a
Slide 101
Slide 101 text
ai
o uvloop ai
ess aioredis aiobot
am aiofiles aiosqlite aiopg
s aiounittest aioslack trio uvloop
omysql aiohttp aiomultiprocess aioredis
lack trio uvloop aioitertools aiostream aiofiles a
ltiprocess aioredis aiobotocore aiodns aiounittest aiosl
aiostream aiofiles aiosqlite aiopg aiomysql aiohttp aiomultipro
e aiodns aiounittest aioslack trio uvloop aioitertools aiostream aiof
iopg aiomysql aiohttp aiomultiprocess aioredis aiobotocore aiodns
ack trio uvloop aioitertools aiostream aiofiles aiosqlite aiopg
s aioredis aiobotocore aiodns aiounittest aioslack tr
s aiosqlite aiopg aiomysql aiohttp aiomultipr
slack trio uvloop aioitertools aiostrea
iprocess aioredis aiobotocore
stream aiofiles aiosqli
aiounittest aio
http aio
a
Slide 102
Slide 102 text
github.com/jreese/pycon
Slide 103
Slide 103 text
github.com/jreese/pycon
John Reese
Production Engineer, Python Foundation
@n7cmdr
github.com / jreese