Skip to content
This repository was archived by the owner on May 31, 2021. It is now read-only.

Commit b00bdce

Browse files
committed
Add beginning of larger tutorial example.
1 parent 0fdea2b commit b00bdce

File tree

8 files changed

+408
-0
lines changed

8 files changed

+408
-0
lines changed

examples/aiohttp_client.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"""aiohttp-based client to retrieve web pages.
2+
"""
3+
4+
import asyncio
5+
from contextlib import closing
6+
import time
7+
8+
import aiohttp
9+
10+
11+
async def fetch_page(session, host, port=8000, wait=0):
12+
"""Get one page.
13+
"""
14+
url = '{}:{}/{}'.format(host, port, wait)
15+
with aiohttp.Timeout(10):
16+
async with session.get(url) as response:
17+
assert response.status == 200
18+
return await response.text()
19+
20+
21+
def get_multiple_pages(host, waits, port=8000, show_time=True):
22+
"""Get multiple pages.
23+
"""
24+
tasks = []
25+
pages = []
26+
start = time.perf_counter()
27+
with closing(asyncio.get_event_loop()) as loop:
28+
with aiohttp.ClientSession(loop=loop) as session:
29+
for wait in waits:
30+
tasks.append(fetch_page(session, host, port, wait))
31+
pages = loop.run_until_complete(asyncio.gather(*tasks))
32+
duration = time.perf_counter() - start
33+
sum_waits = sum(waits)
34+
if show_time:
35+
msg = 'It took {:4.2f} seconds for a total waiting time of {:4.2f}.'
36+
print(msg.format(duration, sum_waits))
37+
return pages
38+
39+
40+
if __name__ == '__main__':
41+
42+
def main():
43+
"""Test it.
44+
"""
45+
pages = get_multiple_pages(host='http://localhost', port='8000',
46+
waits=[1, 5, 3, 2])
47+
for page in pages:
48+
print(page)
49+
50+
main()

examples/async_client_blocking.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""Get "web pages.
2+
3+
Waiting until one pages is download before getting the next."
4+
"""
5+
6+
import asyncio
7+
from contextlib import closing
8+
import time
9+
10+
from async_page import get_page
11+
12+
13+
def get_multiple_pages(host, port, waits, show_time=True):
14+
"""Get multiple pages.
15+
"""
16+
start = time.perf_counter()
17+
pages = []
18+
with closing(asyncio.get_event_loop()) as loop:
19+
for wait in waits:
20+
pages.append(loop.run_until_complete(get_page(host, port, wait)))
21+
22+
duration = time.perf_counter() - start
23+
sum_waits = sum(waits)
24+
if show_time:
25+
msg = 'It took {:4.2f} seconds for a total waiting time of {:4.2f}.'
26+
print(msg.format(duration, sum_waits))
27+
return pages
28+
29+
if __name__ == '__main__':
30+
31+
def main():
32+
"""Test it.
33+
"""
34+
pages = get_multiple_pages(host='localhost', port='8000',
35+
waits=[1, 5, 3, 2])
36+
for page in pages:
37+
print(page)
38+
39+
main()
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""Get "web pages.
2+
3+
Waiting until one pages is download before getting the next."
4+
"""
5+
6+
import asyncio
7+
from contextlib import closing
8+
import time
9+
10+
from async_page import get_page
11+
12+
13+
def get_multiple_pages(host, port, waits, show_time=True):
14+
"""Get multiple pages.
15+
"""
16+
start = time.perf_counter()
17+
pages = []
18+
tasks = []
19+
with closing(asyncio.get_event_loop()) as loop:
20+
for wait in waits:
21+
tasks.append(get_page(host, port, wait))
22+
pages = loop.run_until_complete(asyncio.gather(*tasks))
23+
duration = time.perf_counter() - start
24+
sum_waits = sum(waits)
25+
if show_time:
26+
msg = 'It took {:4.2f} seconds for a total waiting time of {:4.2f}.'
27+
print(msg.format(duration, sum_waits))
28+
return pages
29+
30+
if __name__ == '__main__':
31+
32+
def main():
33+
"""Test it.
34+
"""
35+
pages = get_multiple_pages(host='localhost', port='8000',
36+
waits=[1, 5, 3, 2])
37+
for page in pages:
38+
print(page)
39+
40+
main()

examples/async_page.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""Get a "web page" asynchronously.
2+
"""
3+
4+
import asyncio
5+
6+
ENCODING = 'ISO-8859-1'
7+
8+
9+
def get_encoding(header):
10+
"""Find out encoding.
11+
"""
12+
for line in header:
13+
if line.lstrip().startswith('Content-type'):
14+
for entry in line.split(';'):
15+
if entry.strip().startswith('charset'):
16+
return entry.split('=')[1].strip()
17+
return ENCODING
18+
19+
20+
async def get_page(host, port, wait=0):
21+
"""Get a "web page" asynchronously.
22+
"""
23+
reader, writer = await asyncio.open_connection(host, port)
24+
writer.write(b'\r\n'.join([
25+
'GET /{} HTTP/1.0'.format(wait).encode(ENCODING),
26+
b'Host: %b' % host.encode(ENCODING),
27+
b'Connection: close',
28+
b'', b''
29+
]))
30+
msg_lines = []
31+
header = []
32+
async for raw_line in reader:
33+
line = raw_line.decode(ENCODING).strip()
34+
if not line.strip():
35+
break
36+
header.append(line)
37+
encoding = get_encoding(header)
38+
async for raw_line in reader:
39+
line = raw_line.decode(encoding).strip()
40+
msg_lines.append(line)
41+
writer.close()
42+
return '\n'.join(msg_lines)

examples/simple_server.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# file: simple_server.py
2+
3+
"""Simple HTTP server with GET that waits for given seconds.
4+
"""
5+
6+
from http.server import BaseHTTPRequestHandler, HTTPServer
7+
from socketserver import ThreadingMixIn
8+
import time
9+
10+
11+
ENCODING = 'utf-8'
12+
13+
14+
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
15+
"""Simple multi-threaded HTTP server.
16+
"""
17+
pass
18+
19+
20+
class MyRequestHandler(BaseHTTPRequestHandler):
21+
"""Very simple request handler. Only supports GET.
22+
"""
23+
24+
def do_GET(self): # pylint: disable=invalid-name
25+
"""Respond after seconds given in path.
26+
"""
27+
try:
28+
seconds = float(self.path[1:])
29+
except ValueError:
30+
seconds = 0.0
31+
text = "Waited for {:4.2f} seconds.\nThat's all.\n"
32+
msg = text.format(seconds).encode(ENCODING)
33+
time.sleep(seconds)
34+
self.send_response(200)
35+
self.send_header("Content-type", 'text/plain; charset=utf-8')
36+
self.send_header("Content-length", str(len(msg)))
37+
self.end_headers()
38+
self.wfile.write(msg)
39+
40+
41+
def run(server_class=ThreadingHTTPServer,
42+
handler_class=MyRequestHandler,
43+
port=8000):
44+
"""Run the simple server on given port.
45+
"""
46+
server_address = ('', port)
47+
httpd = server_class(server_address, handler_class)
48+
print('Serving from port {} ...'.format(port))
49+
httpd.serve_forever()
50+
51+
52+
if __name__ == '__main__':
53+
run()

examples/synchronous_client.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""Synchronous client to retrieve web pages.
2+
"""
3+
4+
5+
from urllib.request import urlopen
6+
import time
7+
8+
ENCODING = 'ISO-8859-1'
9+
10+
11+
def get_encoding(http_response):
12+
"""Find out encoding.
13+
"""
14+
content_type = http_response.getheader('Content-type')
15+
for entry in content_type.split(';'):
16+
if entry.strip().startswith('charset'):
17+
return entry.split('=')[1].strip()
18+
return ENCODING
19+
20+
21+
def get_page(host, port, wait=0):
22+
"""Get one page suppling `wait` time.
23+
24+
The path will be build with: `host:port/wait`
25+
"""
26+
full_url = '{}:{}/{}'.format(host, port, wait)
27+
with urlopen(full_url) as http_response:
28+
html = http_response.read().decode(get_encoding(http_response))
29+
return html
30+
31+
32+
def get_multiple_pages(host, port, waits, show_time=True):
33+
"""Get multiple pages.
34+
"""
35+
start = time.perf_counter()
36+
pages = [get_page(host, port, wait) for wait in waits]
37+
duration = time.perf_counter() - start
38+
sum_waits = sum(waits)
39+
if show_time:
40+
msg = 'It took {:4.2f} seconds for a total waiting time of {:4.2f}.'
41+
print(msg.format(duration, sum_waits))
42+
return pages
43+
44+
45+
if __name__ == '__main__':
46+
47+
def main():
48+
"""Test it.
49+
"""
50+
pages = get_multiple_pages(host='http://localhost', port='8000',
51+
waits=[1, 5, 3, 2])
52+
for page in pages:
53+
print(page)
54+
55+
main()

index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Chapter 1: First steps with asyncio
1313
hello_clock.rst
1414
http_client.rst
1515
twisted.rst
16+
webscraper.rst
1617
getting_help.rst
1718

1819

0 commit comments

Comments
 (0)