forked from fluentpython/example-code
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
some chapter 17 examples updated for Python 3.7
- Loading branch information
Showing
7 changed files
with
254 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
.vscode/ | ||
.venv3?/ | ||
*.sublime-project | ||
*.sublime-workspace | ||
.env* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
Updated sample code for Chapter 17 - "Concurrency with futures" | ||
|
||
From the book "Fluent Python" by Luciano Ramalho (O'Reilly, 2015) | ||
http://shop.oreilly.com/product/0636920032519.do | ||
|
||
This directory contains code updated to run with Python 3.7 and | ||
**aiohttp** 3.5. When the first edition of "Fluent Python" was | ||
written, the **asyncio** package was provisional, and the latest | ||
version of **aiohttp** was 0.13.1. The API for both packages had | ||
significant breaking changes. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
"""Download flags of top 20 countries by population | ||
Sequential version | ||
Sample run:: | ||
$ python3 flags.py | ||
BD BR CD CN DE EG ET FR ID IN IR JP MX NG PH PK RU TR US VN | ||
20 flags downloaded in 5.49s | ||
""" | ||
# BEGIN FLAGS_PY | ||
import os | ||
import time | ||
import sys | ||
|
||
import requests # <1> | ||
|
||
POP20_CC = ('CN IN US ID BR PK NG BD RU JP ' | ||
'MX PH VN ET EG DE IR TR CD FR').split() # <2> | ||
|
||
BASE_URL = 'http://flupy.org/data/flags' # <3> | ||
|
||
DEST_DIR = 'downloads/' # <4> | ||
|
||
|
||
def save_flag(img, filename): # <5> | ||
path = os.path.join(DEST_DIR, filename) | ||
with open(path, 'wb') as fp: | ||
fp.write(img) | ||
|
||
|
||
def get_flag(cc): # <6> | ||
url = '{}/{cc}/{cc}.gif'.format(BASE_URL, cc=cc.lower()) | ||
resp = requests.get(url) | ||
return resp.content | ||
|
||
|
||
def show(text): # <7> | ||
print(text, end=' ') | ||
sys.stdout.flush() | ||
|
||
|
||
def download_many(cc_list): # <8> | ||
for cc in sorted(cc_list): # <9> | ||
image = get_flag(cc) | ||
show(cc) | ||
save_flag(image, cc.lower() + '.gif') | ||
|
||
return len(cc_list) | ||
|
||
|
||
def main(): # <10> | ||
t0 = time.time() | ||
count = download_many(POP20_CC) | ||
elapsed = time.time() - t0 | ||
msg = '\n{} flags downloaded in {:.2f}s' | ||
print(msg.format(count, elapsed)) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() | ||
# END FLAGS_PY |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
"""Download flags of top 20 countries by population | ||
asyncio + aiottp version | ||
Sample run:: | ||
$ python3 flags_asyncio.py | ||
CN EG BR IN ID RU NG VN JP DE TR PK FR ET MX PH US IR CD BD | ||
20 flags downloaded in 0.35s | ||
""" | ||
# BEGIN FLAGS_ASYNCIO | ||
import os | ||
import time | ||
import sys | ||
import asyncio # <1> | ||
|
||
import aiohttp # <2> | ||
|
||
|
||
POP20_CC = ('CN IN US ID BR PK NG BD RU JP ' | ||
'MX PH VN ET EG DE IR TR CD FR').split() | ||
|
||
BASE_URL = 'http://flupy.org/data/flags' | ||
|
||
DEST_DIR = 'downloads/' | ||
|
||
|
||
def save_flag(img, filename): | ||
path = os.path.join(DEST_DIR, filename) | ||
with open(path, 'wb') as fp: | ||
fp.write(img) | ||
|
||
|
||
async def get_flag(session, cc): # <3> | ||
url = '{}/{cc}/{cc}.gif'.format(BASE_URL, cc=cc.lower()) | ||
async with session.get(url) as resp: # <4> | ||
return await resp.read() # <5> | ||
|
||
|
||
def show(text): | ||
print(text, end=' ') | ||
sys.stdout.flush() | ||
|
||
|
||
async def download_one(session, cc): # <6> | ||
image = await get_flag(session, cc) # <7> | ||
show(cc) | ||
save_flag(image, cc.lower() + '.gif') | ||
return cc | ||
|
||
|
||
async def download_many(cc_list): | ||
async with aiohttp.ClientSession() as session: # <8> | ||
res = await asyncio.gather( # <9> | ||
*[asyncio.create_task(download_one(session, cc)) | ||
for cc in sorted(cc_list)]) | ||
|
||
return len(res) | ||
|
||
|
||
def main(): # <10> | ||
t0 = time.time() | ||
count = asyncio.run(download_many(POP20_CC)) | ||
elapsed = time.time() - t0 | ||
msg = '\n{} flags downloaded in {:.2f}s' | ||
print(msg.format(count, elapsed)) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() | ||
# END FLAGS_ASYNCIO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
"""Download flags of top 20 countries by population | ||
ThreadPoolExecutor version | ||
Sample run:: | ||
$ python3 flags_threadpool.py | ||
DE FR BD CN EG RU IN TR VN ID JP BR NG MX PK ET PH CD US IR | ||
20 flags downloaded in 0.35s | ||
""" | ||
# BEGIN FLAGS_THREADPOOL | ||
import os | ||
import time | ||
import sys | ||
from concurrent import futures # <1> | ||
|
||
import requests | ||
|
||
POP20_CC = ('CN IN US ID BR PK NG BD RU JP ' | ||
'MX PH VN ET EG DE IR TR CD FR').split() | ||
|
||
BASE_URL = 'http://flupy.org/data/flags' | ||
|
||
DEST_DIR = 'downloads/' | ||
|
||
MAX_WORKERS = 20 # <2> | ||
|
||
def save_flag(img, filename): | ||
path = os.path.join(DEST_DIR, filename) | ||
with open(path, 'wb') as fp: | ||
fp.write(img) | ||
|
||
|
||
def get_flag(cc): | ||
url = '{}/{cc}/{cc}.gif'.format(BASE_URL, cc=cc.lower()) | ||
resp = requests.get(url) | ||
return resp.content | ||
|
||
|
||
def show(text): | ||
print(text, end=' ') | ||
sys.stdout.flush() | ||
|
||
|
||
def download_one(cc): # <3> | ||
image = get_flag(cc) | ||
show(cc) | ||
save_flag(image, cc.lower() + '.gif') | ||
return cc | ||
|
||
|
||
def download_many(cc_list): | ||
workers = min(MAX_WORKERS, len(cc_list)) # <4> | ||
with futures.ThreadPoolExecutor(workers) as executor: # <5> | ||
res = executor.map(download_one, sorted(cc_list)) # <6> | ||
|
||
return len(list(res)) # <7> | ||
|
||
|
||
def main(): # <10> | ||
t0 = time.time() | ||
count = download_many(POP20_CC) | ||
elapsed = time.time() - t0 | ||
msg = '\n{} flags downloaded in {:.2f}s' | ||
print(msg.format(count, elapsed)) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() | ||
# END FLAGS_THREADPOOL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
requests==2.21.0 | ||
aiohttp==3.5.4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
""" | ||
Experiment with ``ThreadPoolExecutor.map`` | ||
""" | ||
# BEGIN EXECUTOR_MAP | ||
from time import sleep, strftime | ||
from concurrent import futures | ||
|
||
|
||
def display(*args): # <1> | ||
print(strftime('[%H:%M:%S]'), end=' ') | ||
print(*args) | ||
|
||
|
||
def loiter(n): # <2> | ||
msg = '{}loiter({}): doing nothing for {}s...' | ||
display(msg.format('\t'*n, n, n)) | ||
sleep(n) | ||
msg = '{}loiter({}): done.' | ||
display(msg.format('\t'*n, n)) | ||
return n * 10 # <3> | ||
|
||
|
||
def main(): | ||
display('Script starting.') | ||
executor = futures.ThreadPoolExecutor(max_workers=3) # <4> | ||
results = executor.map(loiter, range(5)) # <5> | ||
display('results:', results) # <6>. | ||
display('Waiting for individual results:') | ||
for i, result in enumerate(results): # <7> | ||
display('result {}: {}'.format(i, result)) | ||
|
||
|
||
main() | ||
# END EXECUTOR_MAP |