Skip to content

Commit 3039461

Browse files
authored
Merge pull request #45 from realpython/understanding-async-python
Understanding async python
2 parents f17a46e + f3f8981 commit 3039461

File tree

9 files changed

+282
-0
lines changed

9 files changed

+282
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import queue
2+
3+
4+
def task(name, work_queue):
5+
if work_queue.empty():
6+
print(f"Task {name} nothing to do")
7+
else:
8+
while not work_queue.empty():
9+
count = work_queue.get()
10+
total = 0
11+
print(f"Task {name} running")
12+
for x in range(count):
13+
total += 1
14+
print(f"Task {name} total: {total}")
15+
16+
17+
def main():
18+
"""
19+
This is the main entry point for the program
20+
"""
21+
# Create the queue of 'work'
22+
work_queue = queue.Queue()
23+
24+
# Put some 'work' in the queue
25+
for work in [15, 10, 5, 2]:
26+
work_queue.put(work)
27+
28+
# Create some synchronous tasks
29+
tasks = [(task, "One", work_queue), (task, "Two", work_queue)]
30+
31+
# Run the tasks
32+
for t, n, q in tasks:
33+
t(n, q)
34+
35+
36+
if __name__ == "__main__":
37+
main()
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import queue
2+
3+
4+
def task(name, queue):
5+
while not queue.empty():
6+
count = queue.get()
7+
total = 0
8+
print(f"Task {name} running")
9+
for x in range(count):
10+
total += 1
11+
yield
12+
print(f"Task {name} total: {total}")
13+
14+
15+
def main():
16+
"""
17+
This is the main entry point for the program
18+
"""
19+
# Create the queue of 'work'
20+
work_queue = queue.Queue()
21+
22+
# Put some 'work' in the queue
23+
for work in [15, 10, 5, 2]:
24+
work_queue.put(work)
25+
26+
# Create some tasks
27+
tasks = [task("One", work_queue), task("Two", work_queue)]
28+
29+
# Run the tasks
30+
done = False
31+
while not done:
32+
for t in tasks:
33+
try:
34+
next(t)
35+
except StopIteration:
36+
tasks.remove(t)
37+
if len(tasks) == 0:
38+
done = True
39+
40+
41+
if __name__ == "__main__":
42+
main()
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import time
2+
import queue
3+
from lib.elapsed_time import ET
4+
5+
6+
def task(name, queue):
7+
while not queue.empty():
8+
delay = queue.get()
9+
et = ET()
10+
print(f"Task {name} running")
11+
time.sleep(delay)
12+
print(f"Task {name} total elapsed time: {et():.1f}")
13+
yield
14+
15+
16+
def main():
17+
"""
18+
This is the main entry point for the program
19+
"""
20+
# Create the queue of 'work'
21+
work_queue = queue.Queue()
22+
23+
# Put some 'work' in the queue
24+
for work in [15, 10, 5, 2]:
25+
work_queue.put(work)
26+
27+
tasks = [task("One", work_queue), task("Two", work_queue)]
28+
29+
# Run the tasks
30+
et = ET()
31+
done = False
32+
while not done:
33+
for t in tasks:
34+
try:
35+
next(t)
36+
except StopIteration:
37+
tasks.remove(t)
38+
if len(tasks) == 0:
39+
done = True
40+
41+
print(f"\nTotal elapsed time: {et():.1f}")
42+
43+
44+
if __name__ == "__main__":
45+
main()
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import asyncio
2+
from lib.elapsed_time import ET
3+
4+
5+
async def task(name, work_queue):
6+
while not work_queue.empty():
7+
delay = await work_queue.get()
8+
et = ET()
9+
print(f"Task {name} running")
10+
await asyncio.sleep(delay)
11+
print(f"Task {name} total elapsed time: {et():.1f}")
12+
13+
14+
async def main():
15+
"""
16+
This is the main entry point for the program
17+
"""
18+
# Create the queue of 'work'
19+
work_queue = asyncio.Queue()
20+
21+
# Put some 'work' in the queue
22+
for work in [15, 10, 5, 2]:
23+
await work_queue.put(work)
24+
25+
# Run the tasks
26+
et = ET()
27+
await asyncio.gather(
28+
asyncio.create_task(task("One", work_queue)),
29+
asyncio.create_task(task("Two", work_queue)),
30+
)
31+
print(f"\nTotal elapsed time: {et():.1f}")
32+
33+
34+
if __name__ == "__main__":
35+
asyncio.run(main())
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import queue
2+
import requests
3+
from lib.elapsed_time import ET
4+
5+
6+
def task(name, work_queue):
7+
with requests.Session() as session:
8+
while not work_queue.empty():
9+
url = work_queue.get()
10+
print(f"Task {name} getting URL: {url}")
11+
et = ET()
12+
session.get(url)
13+
print(f"Task {name} total elapsed time: {et():.1f}")
14+
yield
15+
16+
17+
def main():
18+
"""
19+
This is the main entry point for the program
20+
"""
21+
# Create the queue of 'work'
22+
work_queue = queue.Queue()
23+
24+
# Put some 'work' in the queue
25+
for url in [
26+
"http://google.com",
27+
"http://yahoo.com",
28+
"http://linkedin.com",
29+
"http://apple.com",
30+
"http://microsoft.com",
31+
"http://facebook.com",
32+
"http://twitter.com",
33+
]:
34+
work_queue.put(url)
35+
36+
tasks = [task("One", work_queue), task("Two", work_queue)]
37+
38+
# Run the tasks
39+
et = ET()
40+
done = False
41+
while not done:
42+
for t in tasks:
43+
try:
44+
next(t)
45+
except StopIteration:
46+
tasks.remove(t)
47+
if len(tasks) == 0:
48+
done = True
49+
50+
print(f"\nTotal elapsed time: {et():.1f}")
51+
52+
53+
if __name__ == "__main__":
54+
main()
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import asyncio
2+
import aiohttp
3+
from lib.elapsed_time import ET
4+
5+
6+
async def task(name, work_queue):
7+
async with aiohttp.ClientSession() as session:
8+
while not work_queue.empty():
9+
url = await work_queue.get()
10+
print(f"Task {name} getting URL: {url}")
11+
et = ET()
12+
async with session.get(url) as response:
13+
await response.text()
14+
print(f"Task {name} total elapsed time: {et():.1f}")
15+
16+
17+
async def main():
18+
"""
19+
This is the main entry point for the program
20+
"""
21+
# Create the queue of 'work'
22+
work_queue = asyncio.Queue()
23+
24+
# Put some 'work' in the queue
25+
for url in [
26+
"http://google.com",
27+
"http://yahoo.com",
28+
"http://linkedin.com",
29+
"http://apple.com",
30+
"http://microsoft.com",
31+
"http://facebook.com",
32+
"http://twitter.com",
33+
]:
34+
await work_queue.put(url)
35+
36+
# Run the tasks
37+
et = ET()
38+
await asyncio.gather(
39+
asyncio.create_task(task("One", work_queue)),
40+
asyncio.create_task(task("Two", work_queue)),
41+
)
42+
print(f"\nTotal elapsed time: {et():.1f}")
43+
44+
45+
if __name__ == "__main__":
46+
asyncio.run(main())

understanding-asynchronous-programming/lib/__init__.py

Whitespace-only changes.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""
2+
This module contains a simple class to measure elapsed time
3+
"""
4+
5+
import time
6+
7+
8+
class ET(object):
9+
def __init__(self):
10+
self.start_time = time.time()
11+
12+
def __call__(self):
13+
return time.time() - self.start_time
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
aiohttp==3.5.4
2+
async-timeout==3.0.1
3+
attrs==19.1.0
4+
certifi==2019.3.9
5+
chardet==3.0.4
6+
idna==2.8
7+
multidict==4.5.2
8+
requests==2.21.0
9+
urllib3==1.24.2
10+
yarl==1.3.0

0 commit comments

Comments
 (0)