Repository: concurrency-in-python-with-asyncio/concurrency-in-python-with-asyncio
Branch: master
Commit: 6f9014428d66
Files: 232
Total size: 168.4 KB
Directory structure:
gitextract_usjcxz68/
├── README.md
├── chapter_01/
│ ├── __init__.py
│ ├── listing_1_1.py
│ ├── listing_1_2.py
│ ├── listing_1_3.py
│ ├── listing_1_4.py
│ ├── listing_1_5.py
│ ├── listing_1_6.py
│ ├── listing_1_7.py
│ └── listing_1_8.py
├── chapter_02/
│ ├── __init__.py
│ ├── listing_2_1.py
│ ├── listing_2_10.py
│ ├── listing_2_11.py
│ ├── listing_2_12.py
│ ├── listing_2_13.py
│ ├── listing_2_14.py
│ ├── listing_2_15.py
│ ├── listing_2_16.py
│ ├── listing_2_17.py
│ ├── listing_2_18.py
│ ├── listing_2_19.py
│ ├── listing_2_2.py
│ ├── listing_2_20.py
│ ├── listing_2_21.py
│ ├── listing_2_22.py
│ ├── listing_2_23.py
│ ├── listing_2_24.py
│ ├── listing_2_3.py
│ ├── listing_2_4.py
│ ├── listing_2_5.py
│ ├── listing_2_6.py
│ ├── listing_2_7.py
│ ├── listing_2_8.py
│ └── listing_2_9.py
├── chapter_03/
│ ├── __init__.py
│ ├── listing_3_1.py
│ ├── listing_3_10.py
│ ├── listing_3_2.py
│ ├── listing_3_3.py
│ ├── listing_3_4.py
│ ├── listing_3_5.py
│ ├── listing_3_6.py
│ ├── listing_3_7.py
│ ├── listing_3_8.py
│ └── listing_3_9.py
├── chapter_04/
│ ├── __init__.py
│ ├── listing_4_1.py
│ ├── listing_4_10.py
│ ├── listing_4_11.py
│ ├── listing_4_12.py
│ ├── listing_4_13.py
│ ├── listing_4_14.py
│ ├── listing_4_15.py
│ ├── listing_4_16.py
│ ├── listing_4_2.py
│ ├── listing_4_3.py
│ ├── listing_4_4.py
│ ├── listing_4_5.py
│ ├── listing_4_6.py
│ ├── listing_4_7.py
│ ├── listing_4_8.py
│ └── listing_4_9.py
├── chapter_05/
│ ├── __init__.py
│ ├── common_words.txt
│ ├── listing_5_1.py
│ ├── listing_5_10.py
│ ├── listing_5_11.py
│ ├── listing_5_12.py
│ ├── listing_5_13.py
│ ├── listing_5_14.py
│ ├── listing_5_15.py
│ ├── listing_5_16.py
│ ├── listing_5_17.py
│ ├── listing_5_2.py
│ ├── listing_5_3.py
│ ├── listing_5_4.py
│ ├── listing_5_5.py
│ ├── listing_5_6.py
│ ├── listing_5_7.py
│ ├── listing_5_8.py
│ └── listing_5_9.py
├── chapter_06/
│ ├── __init__.py
│ ├── listing_6_1.py
│ ├── listing_6_10.py
│ ├── listing_6_11.py
│ ├── listing_6_12.py
│ ├── listing_6_13.py
│ ├── listing_6_14.py
│ ├── listing_6_15.py
│ ├── listing_6_2.py
│ ├── listing_6_3.py
│ ├── listing_6_4.py
│ ├── listing_6_5.py
│ ├── listing_6_6.py
│ ├── listing_6_7.py
│ ├── listing_6_8.py
│ └── listing_6_9.py
├── chapter_07/
│ ├── __init__.py
│ ├── listing_7_1.py
│ ├── listing_7_10.py
│ ├── listing_7_11.py
│ ├── listing_7_12.py
│ ├── listing_7_13.py
│ ├── listing_7_14.py
│ ├── listing_7_15.py
│ ├── listing_7_16.py
│ ├── listing_7_17.py
│ ├── listing_7_18.py
│ ├── listing_7_19.py
│ ├── listing_7_2.py
│ ├── listing_7_3.py
│ ├── listing_7_4.py
│ ├── listing_7_5.py
│ ├── listing_7_6.py
│ ├── listing_7_7.py
│ ├── listing_7_8.py
│ └── listing_7_9.py
├── chapter_08/
│ ├── __init__.py
│ ├── listing_8_1.py
│ ├── listing_8_10.py
│ ├── listing_8_11.py
│ ├── listing_8_12.py
│ ├── listing_8_13.py
│ ├── listing_8_14.py
│ ├── listing_8_2.py
│ ├── listing_8_3.py
│ ├── listing_8_4.py
│ ├── listing_8_5.py
│ ├── listing_8_6.py
│ ├── listing_8_7.py
│ ├── listing_8_8.py
│ └── listing_8_9.py
├── chapter_09/
│ ├── __init__.py
│ ├── async_views/
│ │ ├── async_api/
│ │ │ ├── __init__.py
│ │ │ ├── admin.py
│ │ │ ├── apps.py
│ │ │ ├── migrations/
│ │ │ │ └── __init__.py
│ │ │ ├── models.py
│ │ │ ├── templates/
│ │ │ │ └── async_api/
│ │ │ │ └── requests.html
│ │ │ ├── tests.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── async_views/
│ │ │ ├── __init__.py
│ │ │ ├── asgi.py
│ │ │ ├── settings.py
│ │ │ ├── urls.py
│ │ │ └── wsgi.py
│ │ └── manage.py
│ ├── listing_9_1.py
│ ├── listing_9_10.html
│ ├── listing_9_2.py
│ ├── listing_9_3.py
│ ├── listing_9_4.py
│ ├── listing_9_5.py
│ ├── listing_9_6.py
│ ├── listing_9_7.py
│ ├── listing_9_8.py
│ └── listing_9_9.py
├── chapter_10/
│ ├── __init__.py
│ ├── listing_10_1.py
│ ├── listing_10_10.py
│ ├── listing_10_11.py
│ ├── listing_10_12.py
│ ├── listing_10_2.sql
│ ├── listing_10_3.sql
│ ├── listing_10_4.py
│ ├── listing_10_5.py
│ ├── listing_10_6.py
│ ├── listing_10_7.py
│ ├── listing_10_8.py
│ └── listing_10_9.py
├── chapter_11/
│ ├── __init__.py
│ ├── listing_11_1.py
│ ├── listing_11_10.py
│ ├── listing_11_11.py
│ ├── listing_11_12.py
│ ├── listing_11_13.py
│ ├── listing_11_14.py
│ ├── listing_11_15.py
│ ├── listing_11_2.py
│ ├── listing_11_3.py
│ ├── listing_11_4.py
│ ├── listing_11_5.py
│ ├── listing_11_6.py
│ ├── listing_11_7.py
│ ├── listing_11_8.py
│ └── listing_11_9.py
├── chapter_12/
│ ├── __init__.py
│ ├── listing_12_1.py
│ ├── listing_12_10.py
│ ├── listing_12_2.py
│ ├── listing_12_3.py
│ ├── listing_12_4.py
│ ├── listing_12_5.py
│ ├── listing_12_6.py
│ ├── listing_12_7.py
│ ├── listing_12_8.py
│ └── listing_12_9.py
├── chapter_13/
│ ├── __init__.py
│ ├── listing_13_1.py
│ ├── listing_13_10.py
│ ├── listing_13_11.py
│ ├── listing_13_12.py
│ ├── listing_13_13.py
│ ├── listing_13_14.py
│ ├── listing_13_2.py
│ ├── listing_13_3.py
│ ├── listing_13_4.py
│ ├── listing_13_5.py
│ ├── listing_13_6.py
│ ├── listing_13_7.py
│ ├── listing_13_8.py
│ └── listing_13_9.py
├── chapter_14/
│ ├── __init__.py
│ ├── listing_14_1.py
│ ├── listing_14_10.py
│ ├── listing_14_11.py
│ ├── listing_14_12.py
│ ├── listing_14_13.py
│ ├── listing_14_2.py
│ ├── listing_14_3.py
│ ├── listing_14_4.py
│ ├── listing_14_5.py
│ ├── listing_14_6.py
│ ├── listing_14_7.py
│ ├── listing_14_8.py
│ └── listing_14_9.py
├── requirements.txt
└── util/
├── __init__.py
├── async_timer.py
└── delay_functions.py
================================================
FILE CONTENTS
================================================
================================================
FILE: README.md
================================================
# Concurrency in Python with Asyncio
Source code to the Manning book *Concurrency in Python with Asyncio*.
## Running
This code ran successfully with Python version 3.10.2. Using a different version may give you different results or may not work.
**Steps to Run Code Listing**
1. Install Python 3.10.2, installers available at the bottom of the page at: https://www.python.org/downloads/release/python-3102/
2. Create a virtual environment and activate it. Instructions available [here](https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment).
3. Install the dependencies for the project by running `pip install -r requirements.txt` within your virtual environment.
3. Several functions are in the `util` module - for this to import properly you need to include this module in your `PYTHONPATH`. You can do this by running `export PYTHONPATH=${PYTHONPATH}:concurrency-in-python-with-asyncio/util` within your terminal, changing `concurrency-in-python-with-asyncio` to whichever path you have cloned this repository on your local machine.
5. You should now be able to run any code listing successfully with `python3 scriptname.py`, for example, `python3 chapter_01/listing_1_1.py` will run the first code listing from the first chapter.
================================================
FILE: chapter_01/__init__.py
================================================
================================================
FILE: chapter_01/listing_1_1.py
================================================
import requests
response = requests.get('https://www.example.com')
items = response.headers.items()
headers = [f'{key}: {header}' for key, header in items]
formatted_headers = '\n'.join(headers)
with open('headers.txt', 'w') as file:
file.write(formatted_headers)
================================================
FILE: chapter_01/listing_1_2.py
================================================
import os
import threading
print(f'Python process running with process id: {os.getpid()}')
total_threads = threading.active_count()
thread_name = threading.current_thread().name
print(f'Python is currently running {total_threads} thread(s)')
print(f'The current thread is {thread_name}')
================================================
FILE: chapter_01/listing_1_3.py
================================================
import threading
def hello_from_thread():
print(f'Hello from thread {threading.current_thread()}!')
hello_thread = threading.Thread(target=hello_from_thread)
hello_thread.start()
total_threads = threading.active_count()
thread_name = threading.current_thread().name
print(f'Python is currently running {total_threads} thread(s)')
print(f'The current thread is {thread_name}')
hello_thread.join()
================================================
FILE: chapter_01/listing_1_4.py
================================================
import multiprocessing
import os
def hello_from_process():
print(f'Hello from child process {os.getpid()}!')
if __name__ == '__main__':
hello_process = multiprocessing.Process(target=hello_from_process)
hello_process.start()
print(f'Hello from parent process {os.getpid()}')
hello_process.join()
================================================
FILE: chapter_01/listing_1_5.py
================================================
import time
def print_fib(number: int) -> None:
def fib(n: int) -> int:
if n == 1:
return 0
elif n == 2:
return 1
else:
return fib(n - 1) + fib(n - 2)
print(f'fib({number}) is {fib(number)}')
def fibs_no_threading():
print_fib(40)
print_fib(41)
start = time.time()
fibs_no_threading()
end = time.time()
print(f'Completed in {end - start:.4f} seconds.')
================================================
FILE: chapter_01/listing_1_6.py
================================================
import threading
import time
def print_fib(number: int) -> None:
def fib(n: int) -> int:
if n == 1:
return 0
elif n == 2:
return 1
else:
return fib(n - 1) + fib(n - 2)
print(f'fib({number}) is {fib(number)}')
def fibs_with_threads():
fortieth_thread = threading.Thread(target=print_fib, args=(40,))
forty_first_thread = threading.Thread(target=print_fib, args=(41,))
fortieth_thread.start()
forty_first_thread.start()
fortieth_thread.join()
forty_first_thread.join()
start_threads = time.time()
fibs_with_threads()
end_threads = time.time()
print(f'Threads took {end_threads - start_threads:.4f} seconds.')
================================================
FILE: chapter_01/listing_1_7.py
================================================
import time
import requests
def read_example() -> None:
response = requests.get('https://www.example.com')
print(response.status_code)
sync_start = time.time()
read_example()
read_example()
sync_end = time.time()
print(f'Running synchronously took {sync_end - sync_start:.4f} seconds.')
================================================
FILE: chapter_01/listing_1_8.py
================================================
import time
import threading
import requests
def read_example() -> None:
response = requests.get('https://www.example.com')
print(response.status_code)
thread_1 = threading.Thread(target=read_example)
thread_2 = threading.Thread(target=read_example)
thread_start = time.time()
thread_1.start()
thread_2.start()
print('All threads running!')
thread_1.join()
thread_2.join()
thread_end = time.time()
print(f'Running with threads took {thread_end - thread_start:.4f} seconds.')
================================================
FILE: chapter_02/__init__.py
================================================
================================================
FILE: chapter_02/listing_2_1.py
================================================
async def my_coroutine() -> None:
print('Hello world!')
================================================
FILE: chapter_02/listing_2_10.py
================================================
import asyncio
from util import delay
async def hello_every_second():
for i in range(2):
await asyncio.sleep(1)
print("I'm running other code while I'm waiting!")
async def main():
first_delay = asyncio.create_task(delay(3))
second_delay = asyncio.create_task(delay(3))
await hello_every_second()
await first_delay
await second_delay
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_11.py
================================================
import asyncio
from asyncio import CancelledError
from util import delay
async def main():
long_task = asyncio.create_task(delay(10))
seconds_elapsed = 0
while not long_task.done():
print('Task not finished, checking again in a second.')
await asyncio.sleep(1)
seconds_elapsed = seconds_elapsed + 1
if seconds_elapsed == 5:
long_task.cancel()
try:
await long_task
except CancelledError:
print('Our task was cancelled')
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_12.py
================================================
import asyncio
from util import delay
async def main():
delay_task = asyncio.create_task(delay(2))
try:
result = await asyncio.wait_for(delay_task, timeout=1)
print(result)
except asyncio.exceptions.TimeoutError:
print('Got a timeout!')
print(f'Was the task cancelled? {delay_task.cancelled()}')
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_13.py
================================================
import asyncio
from util import delay
async def main():
task = asyncio.create_task(delay(10))
try:
result = await asyncio.wait_for(asyncio.shield(task), 5)
print(result)
except asyncio.TimeoutError:
print("Task took longer than five seconds!")
result = await task
print(result)
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_14.py
================================================
from asyncio import Future
my_future = Future()
print(f'Is my_future done? {my_future.done()}')
my_future.set_result(42)
print(f'Is my_future done? {my_future.done()}')
print(f'What is the result of my_future? {my_future.result()}')
================================================
FILE: chapter_02/listing_2_15.py
================================================
from asyncio import Future
import asyncio
def make_request() -> Future:
future = Future()
asyncio.create_task(set_future_value(future))
return future
async def set_future_value(future) -> None:
await asyncio.sleep(1)
future.set_result(42)
async def main() -> None:
future = make_request()
print(f'Is the future done? {future.done()}')
value = await future
print(f'Is the future done? {future.done()}')
print(value)
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_16.py
================================================
import functools
import time
from typing import Callable, Any
def async_timed():
def wrapper(func: Callable) -> Callable:
@functools.wraps(func)
async def wrapped(*args, **kwargs) -> Any:
print(f'starting {func} with args {args} {kwargs}')
start = time.time()
try:
return await func(*args, **kwargs)
finally:
end = time.time()
total = end - start
print(f'finished {func} in {total:.4f} second(s)')
return wrapped
return wrapper
================================================
FILE: chapter_02/listing_2_17.py
================================================
import asyncio
from util import async_timed
@async_timed()
async def delay(delay_seconds: int) -> int:
print(f'sleeping for {delay_seconds} second(s)')
await asyncio.sleep(delay_seconds)
print(f'finished sleeping for {delay_seconds} second(s)')
return delay_seconds
@async_timed()
async def main():
task_one = asyncio.create_task(delay(2))
task_two = asyncio.create_task(delay(3))
await task_one
await task_two
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_18.py
================================================
import asyncio
from util import async_timed
@async_timed()
async def cpu_bound_work() -> int:
counter = 0
for i in range(100000000):
counter = counter + 1
return counter
@async_timed()
async def main():
task_one = asyncio.create_task(cpu_bound_work())
task_two = asyncio.create_task(cpu_bound_work())
await task_one
await task_two
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_19.py
================================================
import asyncio
from util import async_timed, delay
@async_timed()
async def cpu_bound_work() -> int:
counter = 0
for i in range(100000000):
counter = counter + 1
return counter
@async_timed()
async def main():
task_one = asyncio.create_task(cpu_bound_work())
task_two = asyncio.create_task(cpu_bound_work())
delay_task = asyncio.create_task(delay(4))
await task_one
await task_two
await delay_task
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_2.py
================================================
async def coroutine_add_one(number: int) -> int:
return number + 1
def add_one(number: int) -> int:
return number + 1
function_result = add_one(1)
coroutine_result = coroutine_add_one(1)
print(f'Function result is {function_result} and the type is {type(function_result)}')
print(f'Coroutine result is {coroutine_result} and the type is {type(coroutine_result)}')
================================================
FILE: chapter_02/listing_2_20.py
================================================
import asyncio
import requests
from util import async_timed
@async_timed()
async def get_example_status() -> int:
return requests.get('https://www.example.com').status_code
@async_timed()
async def main():
task_1 = asyncio.create_task(get_example_status())
task_2 = asyncio.create_task(get_example_status())
task_3 = asyncio.create_task(get_example_status())
await task_1
await task_2
await task_3
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_21.py
================================================
import asyncio
async def main():
await asyncio.sleep(1)
loop = asyncio.new_event_loop()
try:
loop.run_until_complete(main())
finally:
loop.close()
================================================
FILE: chapter_02/listing_2_22.py
================================================
import asyncio
from util import delay
def call_later():
print("I'm being called in the future!")
async def main():
loop = asyncio.get_running_loop()
loop.call_soon(call_later)
await delay(1)
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_23.py
================================================
import asyncio
from util import async_timed
@async_timed()
async def cpu_bound_work() -> int:
counter = 0
for i in range(100000000):
counter = counter + 1
return counter
async def main() -> None:
task_one = asyncio.create_task(cpu_bound_work())
await task_one
asyncio.run(main(), debug=True)
================================================
FILE: chapter_02/listing_2_24.py
================================================
import asyncio
async def main():
loop = asyncio.get_running_loop()
loop.slow_callback_duration = .250
asyncio.run(main(), debug=True)
================================================
FILE: chapter_02/listing_2_3.py
================================================
import asyncio
async def coroutine_add_one(number: int) -> int:
return number + 1
result = asyncio.run(coroutine_add_one(1))
print(result)
================================================
FILE: chapter_02/listing_2_4.py
================================================
import asyncio
async def add_one(number: int) -> int:
return number + 1
async def main() -> None:
one_plus_one = await add_one(1)
two_plus_one = await add_one(2)
print(one_plus_one)
print(two_plus_one)
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_5.py
================================================
import asyncio
async def hello_world_message() -> str:
await asyncio.sleep(1)
return "Hello World!"
async def main() -> None:
message = await hello_world_message()
print(message)
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_6.py
================================================
import asyncio
async def delay(delay_seconds: int) -> int:
print(f'sleeping for {delay_seconds} second(s)')
await asyncio.sleep(delay_seconds)
print(f'finished sleeping for {delay_seconds} second(s)')
return delay_seconds
================================================
FILE: chapter_02/listing_2_7.py
================================================
import asyncio
from util import delay
async def add_one(number: int) -> int:
return number + 1
async def hello_world_message() -> str:
await delay(1)
return 'Hello World!'
async def main() -> None:
message = await hello_world_message()
one_plus_one = await add_one(1)
print(one_plus_one)
print(message)
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_8.py
================================================
import asyncio
from util import delay
async def main():
sleep_for_three = asyncio.create_task(delay(3))
print(type(sleep_for_three))
result = await sleep_for_three
print(result)
asyncio.run(main())
================================================
FILE: chapter_02/listing_2_9.py
================================================
import asyncio
from util import delay
async def main():
sleep_for_three = asyncio.create_task(delay(3))
sleep_again = asyncio.create_task(delay(3))
sleep_once_more = asyncio.create_task(delay(3))
await sleep_for_three
await sleep_again
await sleep_once_more
asyncio.run(main())
================================================
FILE: chapter_03/__init__.py
================================================
================================================
FILE: chapter_03/listing_3_1.py
================================================
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('127.0.0.1', 8000)
server_socket.bind(server_address)
server_socket.listen()
connection, client_address = server_socket.accept()
print(f'I got a connection from {client_address}!')
server_socket.close()
================================================
FILE: chapter_03/listing_3_10.py
================================================
import asyncio
from asyncio import AbstractEventLoop
import socket
import logging
import signal
from typing import List
async def echo(connection: socket,
loop: AbstractEventLoop) -> None:
try:
while data := await loop.sock_recv(connection, 1024):
print('got data!')
if data == b'boom\r\n':
raise Exception("Unexpected network error")
await loop.sock_sendall(connection, data)
except Exception as ex:
logging.exception(ex)
finally:
connection.close()
echo_tasks = []
async def connection_listener(server_socket, loop):
while True:
connection, address = await loop.sock_accept(server_socket)
connection.setblocking(False)
print(f"Got a connection from {address}")
echo_task = asyncio.create_task(echo(connection, loop))
echo_tasks.append(echo_task)
class GracefulExit(SystemExit):
pass
def shutdown():
raise GracefulExit()
async def close_echo_tasks(echo_tasks: List[asyncio.Task]):
waiters = [asyncio.wait_for(task, 2) for task in echo_tasks]
for task in waiters:
try:
await task
except asyncio.exceptions.TimeoutError:
# We expect a timeout error here
pass
async def main():
server_socket = socket.socket()
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('127.0.0.1', 8000)
server_socket.setblocking(False)
server_socket.bind(server_address)
server_socket.listen()
for signame in {'SIGINT', 'SIGTERM'}:
loop.add_signal_handler(getattr(signal, signame), shutdown)
await connection_listener(server_socket, loop)
loop = asyncio.new_event_loop()
try:
loop.run_until_complete(main())
except GracefulExit:
loop.run_until_complete(close_echo_tasks(echo_tasks))
finally:
loop.close()
================================================
FILE: chapter_03/listing_3_2.py
================================================
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('127.0.0.1', 8000)
server_socket.bind(server_address)
server_socket.listen()
try:
connection, client_address = server_socket.accept()
print(f'I got a connection from {client_address}!')
buffer = b''
while buffer[-2:] != b'\r\n':
data = connection.recv(2)
if not data:
break
else:
print(f'I got data: {data}!')
buffer = buffer + data
print(f"All the data is: {buffer}")
finally:
server_socket.close()
================================================
FILE: chapter_03/listing_3_3.py
================================================
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('127.0.0.1', 8000)
server_socket.bind(server_address)
server_socket.listen()
connections = []
try:
while True:
connection, client_address = server_socket.accept()
print(f'I got a connection from {client_address}!')
connections.append(connection)
for connection in connections:
buffer = b''
while buffer[-2:] != b'\r\n':
data = connection.recv(2)
if not data:
break
else:
print(f'I got data: {data}!')
buffer = buffer + data
print(f"All the data is: {buffer}")
connection.send(buffer)
finally:
server_socket.close()
================================================
FILE: chapter_03/listing_3_4.py
================================================
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('127.0.0.1', 8000))
server_socket.listen()
server_socket.setblocking(False)
================================================
FILE: chapter_03/listing_3_5.py
================================================
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('127.0.0.1', 8000)
server_socket.bind(server_address)
server_socket.listen()
server_socket.setblocking(False) #A
connections = []
try:
while True:
connection, client_address = server_socket.accept()
connection.setblocking(False) #B
print(f'I got a connection from {client_address}!')
connections.append(connection)
for connection in connections:
buffer = b''
while buffer[-2:] != b'\r\n':
data = connection.recv(2)
if not data:
break
else:
print(f'I got data: {data}!')
buffer = buffer + data
print(f"All the data is: {buffer}")
connection.send(buffer)
finally:
server_socket.close()
================================================
FILE: chapter_03/listing_3_6.py
================================================
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('127.0.0.1', 8000)
server_socket.bind(server_address)
server_socket.listen()
server_socket.setblocking(False)
connections = []
try:
while True:
try:
connection, client_address = server_socket.accept()
connection.setblocking(False)
print(f'I got a connection from {client_address}!')
connections.append(connection)
except BlockingIOError:
pass
for connection in connections:
try:
buffer = b''
while buffer[-2:] != b'\r\n':
data = connection.recv(2)
if not data:
break
else:
print(f'I got data: {data}!')
buffer = buffer + data
print(f"All the data is: {buffer}")
connection.send(buffer)
except BlockingIOError:
pass
finally:
server_socket.close()
================================================
FILE: chapter_03/listing_3_7.py
================================================
import selectors
import socket
from selectors import SelectorKey
from typing import List, Tuple
selector = selectors.DefaultSelector()
server_socket = socket.socket()
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('127.0.0.1', 8000)
server_socket.setblocking(False)
server_socket.bind(server_address)
server_socket.listen()
selector.register(server_socket, selectors.EVENT_READ)
while True:
events: List[Tuple[SelectorKey, int]] = selector.select(timeout=1) #A
if len(events) == 0: #B
print('No events, waiting a bit more!')
for event, _ in events:
event_socket = event.fileobj #C
if event_socket == server_socket: #D
connection, address = server_socket.accept()
connection.setblocking(False)
print(f"I got a connection from {address}")
selector.register(connection, selectors.EVENT_READ) #E
else:
data = event_socket.recv(1024) #F
print(f"I got some data: {data}")
event_socket.send(data)
================================================
FILE: chapter_03/listing_3_8.py
================================================
import asyncio
import socket
from asyncio import AbstractEventLoop
async def echo(connection: socket,
loop: AbstractEventLoop) -> None:
while data := await loop.sock_recv(connection, 1024):
await loop.sock_sendall(connection, data)
async def listen_for_connection(server_socket: socket,
loop: AbstractEventLoop):
while True:
connection, address = await loop.sock_accept(server_socket)
connection.setblocking(False)
print(f"Got a connection from {address}")
asyncio.create_task(echo(connection, loop))
async def main():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('127.0.0.1', 8000)
server_socket.setblocking(False)
server_socket.bind(server_address)
server_socket.listen()
await listen_for_connection(server_socket, asyncio.get_event_loop())
asyncio.run(main())
================================================
FILE: chapter_03/listing_3_9.py
================================================
import asyncio
from asyncio import AbstractEventLoop
import signal
from typing import Set
from util import delay
def cancel_tasks():
print('Got a SIGINT!')
tasks: Set[asyncio.Task] = asyncio.all_tasks()
print(f'Cancelling {len(tasks)} task(s).')
[task.cancel() for task in tasks]
async def main():
loop: AbstractEventLoop = asyncio.get_running_loop()
loop.add_signal_handler(signal.SIGINT, cancel_tasks)
await delay(10)
asyncio.run(main())
================================================
FILE: chapter_04/__init__.py
================================================
import asyncio
from aiohttp import ClientSession
from util import async_timed
@async_timed()
async def fetch_status(session: ClientSession,
url: str,
delay: int = 0) -> int:
await asyncio.sleep(delay)
async with session.get(url) as result:
return result.status
================================================
FILE: chapter_04/listing_4_1.py
================================================
import asyncio
import socket
from types import TracebackType
from typing import Optional, Type
class ConnectedSocket:
def __init__(self, server_socket):
self._connection = None
self._server_socket = server_socket
async def __aenter__(self): #A
print('Entering context manager, waiting for connection')
loop = asyncio.get_event_loop()
connection, address = await loop.sock_accept(self._server_socket)
self._connection = connection
print('Accepted a connection')
return self._connection
async def __aexit__(self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType]): #B
print('Exiting context manager')
self._connection.close()
print('Closed connection')
async def main():
loop = asyncio.get_event_loop()
server_socket = socket.socket()
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('127.0.0.1', 8000)
server_socket.setblocking(False)
server_socket.bind(server_address)
server_socket.listen()
async with ConnectedSocket(server_socket) as connection: #C
data = await loop.sock_recv(connection, 1024)
print(data) #D
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_10.py
================================================
import asyncio
import aiohttp
from util import async_timed
from chapter_04 import fetch_status
@async_timed()
async def main():
async with aiohttp.ClientSession() as session:
fetchers = \
[asyncio.create_task(fetch_status(session, 'https://example.com')),
asyncio.create_task(fetch_status(session, 'https://example.com'))]
done, pending = await asyncio.wait(fetchers)
print(f'Done task count: {len(done)}')
print(f'Pending task count: {len(pending)}')
for done_task in done:
result = await done_task
print(result)
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_11.py
================================================
import asyncio
import aiohttp
import logging
from util import async_timed
from chapter_04 import fetch_status
@async_timed()
async def main():
async with aiohttp.ClientSession() as session:
good_request = fetch_status(session, 'https://www.example.com')
bad_request = fetch_status(session, 'python://bad')
fetchers = [asyncio.create_task(good_request),
asyncio.create_task(bad_request)]
done, pending = await asyncio.wait(fetchers)
print(f'Done task count: {len(done)}')
print(f'Pending task count: {len(pending)}')
for done_task in done:
# result = await done_task will throw an exception
if done_task.exception() is None:
print(done_task.result())
else:
logging.error("Request got an exception",
exc_info=done_task.exception())
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_12.py
================================================
import aiohttp
import asyncio
import logging
from chapter_04 import fetch_status
from util import async_timed
@async_timed()
async def main():
async with aiohttp.ClientSession() as session:
fetchers = \
[asyncio.create_task(fetch_status(session, 'python://bad.com')),
asyncio.create_task(fetch_status(session, 'https://www.example.com', delay=3)),
asyncio.create_task(fetch_status(session, 'https://www.example.com', delay=3))]
done, pending = await asyncio.wait(fetchers, return_when=asyncio.FIRST_EXCEPTION)
print(f'Done task count: {len(done)}')
print(f'Pending task count: {len(pending)}')
for done_task in done:
if done_task.exception() is None:
print(done_task.result())
else:
logging.error("Request got an exception",
exc_info=done_task.exception())
for pending_task in pending:
pending_task.cancel()
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_13.py
================================================
import asyncio
import aiohttp
from util import async_timed
from chapter_04 import fetch_status
@async_timed()
async def main():
async with aiohttp.ClientSession() as session:
url = 'https://www.example.com'
fetchers = [asyncio.create_task(fetch_status(session, url)),
asyncio.create_task(fetch_status(session, url)),
asyncio.create_task(fetch_status(session, url))]
done, pending = await asyncio.wait(fetchers, return_when=asyncio.FIRST_COMPLETED)
print(f'Done task count: {len(done)}')
print(f'Pending task count: {len(pending)}')
for done_task in done:
print(await done_task)
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_14.py
================================================
import asyncio
import aiohttp
from chapter_04 import fetch_status
from util import async_timed
@async_timed()
async def main():
async with aiohttp.ClientSession() as session:
url = 'https://www.example.com'
pending = [asyncio.create_task(fetch_status(session, url)),
asyncio.create_task(fetch_status(session, url)),
asyncio.create_task(fetch_status(session, url))]
while pending:
done, pending = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED)
print(f'Done task count: {len(done)}')
print(f'Pending task count: {len(pending)}')
for done_task in done:
print(await done_task)
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_15.py
================================================
import asyncio
import aiohttp
from chapter_04 import fetch_status
from util import async_timed
@async_timed()
async def main():
async with aiohttp.ClientSession() as session:
url = 'https://example.com'
fetchers = [asyncio.create_task(fetch_status(session, url)),
asyncio.create_task(fetch_status(session, url)),
asyncio.create_task(fetch_status(session, url, delay=3))]
done, pending = await asyncio.wait(fetchers, timeout=1)
print(f'Done task count: {len(done)}')
print(f'Pending task count: {len(pending)}')
for done_task in done:
result = await done_task
print(result)
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_16.py
================================================
import asyncio
import aiohttp
from chapter_04 import fetch_status
async def main():
async with aiohttp.ClientSession() as session:
api_a = fetch_status(session, 'https://www.example.com')
api_b = fetch_status(session, 'https://www.example.com', delay=2)
done, pending = await asyncio.wait([api_a, api_b], timeout=1)
for task in pending:
if task is api_b:
print('API B too slow, cancelling')
task.cancel()
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_2.py
================================================
import asyncio
import aiohttp
from aiohttp import ClientSession
from util import async_timed
@async_timed()
async def fetch_status(session: ClientSession, url: str) -> int:
async with session.get(url) as result:
return result.status
@async_timed()
async def main():
async with aiohttp.ClientSession() as session:
url = 'https://www.example.com'
status = await fetch_status(session, url)
print(f'Status for {url} was {status}')
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_3.py
================================================
import asyncio
import aiohttp
from aiohttp import ClientSession
async def fetch_status(session: ClientSession,
url: str) -> int:
ten_millis = aiohttp.ClientTimeout(total=0.01)
async with session.get(url, timeout=ten_millis) as result:
return result.status
async def main():
session_timeout = aiohttp.ClientTimeout(total=1, connect=.1)
async with aiohttp.ClientSession(timeout=session_timeout) as session:
await fetch_status(session, 'https://example.com')
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_4.py
================================================
import asyncio
from util import async_timed, delay
@async_timed()
async def main() -> None:
delay_times = [3, 3, 3]
[await asyncio.create_task(delay(seconds)) for seconds in delay_times]
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_5.py
================================================
import asyncio
from util import async_timed, delay
@async_timed()
async def main() -> None:
delay_times = [3, 3, 3]
tasks = [asyncio.create_task(delay(seconds)) for seconds in delay_times]
[await task for task in tasks]
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_6.py
================================================
import asyncio
import aiohttp
from chapter_04 import fetch_status
from util import async_timed
@async_timed()
async def main():
async with aiohttp.ClientSession() as session:
urls = ['https://example.com' for _ in range(1000)]
requests = [fetch_status(session, url) for url in urls]
status_codes = await asyncio.gather(*requests)
print(status_codes)
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_7.py
================================================
import asyncio
from util import delay
async def main():
results = await asyncio.gather(delay(3), delay(1))
print(results)
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_8.py
================================================
import asyncio
import aiohttp
from util import async_timed
from chapter_04 import fetch_status
@async_timed()
async def main():
async with aiohttp.ClientSession() as session:
fetchers = [fetch_status(session, 'https://www.example.com', 1),
fetch_status(session, 'https://www.example.com', 1),
fetch_status(session, 'https://www.example.com', 10)]
for finished_task in asyncio.as_completed(fetchers):
print(await finished_task)
asyncio.run(main())
================================================
FILE: chapter_04/listing_4_9.py
================================================
import asyncio
import aiohttp
from util import async_timed
from chapter_04 import fetch_status
@async_timed()
async def main():
async with aiohttp.ClientSession() as session:
fetchers = [fetch_status(session, 'https://example.com', 1),
fetch_status(session, 'https://example.com', 10),
fetch_status(session, 'https://example.com', 10)]
for done_task in asyncio.as_completed(fetchers, timeout=2):
try:
result = await done_task
print(result)
except asyncio.TimeoutError:
print('We got a timeout error!')
for task in asyncio.tasks.all_tasks():
print(task)
asyncio.run(main())
================================================
FILE: chapter_05/__init__.py
================================================
================================================
FILE: chapter_05/common_words.txt
================================================
the
of
to
and
a
in
is
it
you
that
he
was
for
on
are
with
as
I
his
they
be
at
one
have
this
from
or
had
by
not
word
but
what
some
we
can
out
other
were
all
there
when
up
use
your
how
said
an
each
she
which
do
their
time
if
will
way
about
many
then
them
write
would
like
so
these
her
long
make
thing
see
him
two
has
look
more
day
could
go
come
did
number
sound
no
most
people
my
over
know
water
than
call
first
who
may
down
side
been
now
find
any
new
work
part
take
get
place
made
live
where
after
back
little
only
round
man
year
came
show
every
good
me
give
our
under
name
very
through
just
form
sentence
great
think
say
help
low
line
differ
turn
cause
much
mean
before
move
right
boy
old
too
same
tell
does
set
three
want
air
well
also
play
small
end
put
home
read
hand
port
large
spell
add
even
land
here
must
big
high
such
follow
act
why
ask
men
change
went
light
kind
off
need
house
picture
try
us
again
animal
point
mother
world
near
build
self
earth
father
head
stand
own
page
should
country
found
answer
school
grow
study
still
learn
plant
cover
food
sun
four
between
state
keep
eye
never
last
let
thought
city
tree
cross
farm
hard
start
might
story
saw
far
sea
draw
left
late
run
don't
while
press
close
night
real
life
few
north
open
seem
together
next
white
children
begin
got
walk
example
ease
paper
group
always
music
those
both
mark
often
letter
until
mile
river
car
feet
care
second
book
carry
took
science
eat
room
friend
began
idea
fish
mountain
stop
once
base
hear
horse
cut
sure
watch
color
face
wood
main
enough
plain
girl
usual
young
ready
above
ever
red
list
though
feel
talk
bird
soon
body
dog
family
direct
pose
leave
song
measure
door
product
black
short
numeral
class
wind
question
happen
complete
ship
area
half
rock
order
fire
south
problem
piece
told
knew
pass
since
top
whole
king
space
heard
best
hour
better
true
during
hundred
five
remember
step
early
hold
west
ground
interest
reach
fast
verb
sing
listen
six
table
travel
less
morning
ten
simple
several
vowel
toward
war
lay
against
pattern
slow
center
love
person
money
serve
appear
road
map
rain
rule
govern
pull
cold
notice
voice
unit
power
town
fine
certain
fly
fall
lead
cry
dark
machine
note
wait
plan
figure
star
box
noun
field
rest
correct
able
pound
done
beauty
drive
stood
contain
front
teach
week
final
gave
green
oh
quick
develop
ocean
warm
free
minute
strong
special
mind
behind
clear
tail
produce
fact
street
inch
multiply
nothing
course
stay
wheel
full
force
blue
object
decide
surface
deep
moon
island
foot
system
busy
test
record
boat
common
gold
possible
plane
stead
dry
wonder
laugh
thousand
ago
ran
check
game
shape
equate
hot
miss
brought
heat
snow
tire
bring
yes
distant
fill
east
paint
language
among
grand
ball
yet
wave
drop
heart
am
present
heavy
dance
engine
position
arm
wide
sail
material
size
vary
settle
speak
weight
general
ice
matter
circle
pair
include
divide
syllable
felt
perhaps
pick
sudden
count
square
reason
length
represent
art
subject
region
energy
hunt
probable
bed
brother
egg
ride
cell
believe
fraction
forest
sit
race
window
store
summer
train
sleep
prove
lone
leg
exercise
wall
catch
mount
wish
sky
board
joy
winter
sat
written
wild
instrument
kept
glass
grass
cow
job
edge
sign
visit
past
soft
fun
bright
gas
weather
month
million
bear
finish
happy
hope
flower
clothe
strange
gone
jump
baby
eight
village
meet
root
buy
raise
solve
metal
whether
push
seven
paragraph
third
shall
held
hair
describe
cook
floor
either
result
burn
hill
safe
cat
century
consider
type
law
bit
coast
copy
phrase
silent
tall
sand
soil
roll
temperature
finger
industry
value
fight
lie
beat
excite
natural
view
sense
ear
else
quite
broke
case
middle
kill
son
lake
moment
scale
loud
spring
observe
child
straight
consonant
nation
dictionary
milk
speed
method
organ
pay
age
section
dress
cloud
surprise
quiet
stone
tiny
climb
cool
design
poor
lot
experiment
bottom
key
iron
single
stick
flat
twenty
skin
smile
crease
hole
trade
melody
trip
office
receive
row
mouth
exact
symbol
die
least
trouble
shout
except
wrote
seed
tone
join
suggest
clean
break
lady
yard
rise
bad
blow
oil
blood
touch
grew
cent
mix
team
wire
cost
lost
brown
wear
garden
equal
sent
choose
fell
fit
flow
fair
bank
collect
save
control
decimal
gentle
woman
captain
practice
separate
difficult
doctor
please
protect
noon
whose
locate
ring
character
insect
caught
period
indicate
radio
spoke
atom
human
history
effect
electric
expect
crop
modern
element
hit
student
corner
party
supply
bone
rail
imagine
provide
agree
thus
capital
won't
chair
danger
fruit
rich
thick
soldier
process
operate
guess
necessary
sharp
wing
create
neighbor
wash
bat
rather
crowd
corn
compare
poem
string
bell
depend
meat
rub
tube
famous
dollar
stream
fear
sight
thin
triangle
planet
hurry
chief
colony
clock
mine
tie
enter
major
fresh
search
send
yellow
gun
allow
print
dead
spot
desert
suit
current
lift
rose
continue
block
chart
hat
sell
success
company
subtract
event
particular
deal
swim
term
opposite
wife
shoe
shoulder
spread
arrange
camp
invent
cotton
born
determine
quart
nine
truck
noise
level
chance
gather
shop
stretch
throw
shine
property
column
molecule
select
wrong
gray
repeat
require
broad
prepare
salt
nose
plural
anger
claim
continent
oxygen
sugar
death
pretty
skill
women
season
solution
magnet
silver
thank
branch
match
suffix
especially
fig
afraid
huge
sister
steel
discuss
forward
similar
guide
experience
score
apple
bought
led
pitch
coat
mass
card
band
rope
slip
win
dream
evening
condition
feed
tool
total
basic
smell
valley
nor
double
seat
arrive
master
track
parent
shore
division
sheet
substance
favor
connect
post
spend
chord
fat
glad
original
share
station
dad
bread
charge
proper
bar
offer
segment
slave
duck
instant
market
degree
populate
chick
dear
enemy
reply
drink
occur
support
speech
nature
range
steam
motion
path
liquid
log
meant
quotient
teeth
shell
neck
================================================
FILE: chapter_05/listing_5_1.py
================================================
import asyncpg
import asyncio
async def main():
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='postgres',
password='password')
version = connection.get_server_version()
print(f'Connected! Postgres version is {version}')
await connection.close()
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_10.py
================================================
import asyncio
import logging
import asyncpg
async def main():
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='products',
password='password')
try:
async with connection.transaction():
insert_brand = "INSERT INTO brand VALUES(9999, 'big_brand')"
await connection.execute(insert_brand)
await connection.execute(insert_brand) # A
except Exception:
logging.exception('Error while running transaction') # B
finally:
query = """SELECT brand_name FROM brand
WHERE brand_name LIKE 'big_%'"""
brands = await connection.fetch(query) # C
print(f'Query result was: {brands}')
await connection.close()
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_11.py
================================================
import asyncio
import asyncpg
import logging
async def main():
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='products',
password='password')
async with connection.transaction():
await connection.execute("INSERT INTO brand VALUES(DEFAULT, 'my_new_brand')")
try:
async with connection.transaction():
await connection.execute("INSERT INTO product_color VALUES(1, 'black')")
except Exception as ex:
logging.warning('Ignoring error inserting product color', exc_info=ex)
await connection.close()
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_12.py
================================================
import asyncio
import asyncpg
from asyncpg.transaction import Transaction
async def main():
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='products',
password='password')
transaction: Transaction = connection.transaction() #A
await transaction.start() #B
try:
await connection.execute("INSERT INTO brand "
"VALUES(DEFAULT, 'brand_1')")
await connection.execute("INSERT INTO brand "
"VALUES(DEFAULT, 'brand_2')")
except asyncpg.PostgresError:
print('Errors, rolling back transaction!')
await transaction.rollback() #C
else:
print('No errors, committing transaction!')
await transaction.commit() #D
query = """SELECT brand_name FROM brand
WHERE brand_name LIKE 'brand%'"""
brands = await connection.fetch(query)
print(brands)
await connection.close()
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_13.py
================================================
def positive_integers(until: int):
for integer in range(until):
yield integer
positive_iterator = positive_integers(2)
print(next(positive_iterator))
print(next(positive_iterator))
================================================
FILE: chapter_05/listing_5_14.py
================================================
import asyncio
from util import delay, async_timed
async def positive_integers_async(until: int):
for integer in range(1, until):
await delay(integer)
yield integer
@async_timed()
async def main():
async_generator = positive_integers_async(3)
print(type(async_generator))
async for number in async_generator:
print(f'Got number {number}')
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_15.py
================================================
import asyncio
import asyncpg
async def main():
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='products',
password='password')
query = 'SELECT product_id, product_name FROM product'
async with connection.transaction():
async for product in connection.cursor(query):
print(product)
await connection.close()
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_16.py
================================================
import asyncpg
import asyncio
async def main():
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='products',
password='password')
async with connection.transaction():
query = 'SELECT product_id, product_name from product'
cursor = await connection.cursor(query) #A
await cursor.forward(500) #B
products = await cursor.fetch(100) #C
for product in products:
print(product)
await connection.close()
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_17.py
================================================
import asyncpg
import asyncio
async def take(generator, to_take: int):
item_count = 0
async for item in generator:
if item_count > to_take - 1:
return
item_count = item_count + 1
yield item
async def main():
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='products',
password='password')
async with connection.transaction():
query = 'SELECT product_id, product_name from product'
product_generator = connection.cursor(query)
async for product in take(product_generator, 5):
print(product)
print('Got the first five products!')
await connection.close()
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_2.py
================================================
CREATE_BRAND_TABLE = \
"""
CREATE TABLE IF NOT EXISTS brand(
brand_id SERIAL PRIMARY KEY,
brand_name TEXT NOT NULL
);"""
CREATE_PRODUCT_TABLE = \
"""
CREATE TABLE IF NOT EXISTS product(
product_id SERIAL PRIMARY KEY,
product_name TEXT NOT NULL,
brand_id INT NOT NULL,
FOREIGN KEY (brand_id) REFERENCES brand(brand_id)
);"""
CREATE_PRODUCT_COLOR_TABLE = \
"""
CREATE TABLE IF NOT EXISTS product_color(
product_color_id SERIAL PRIMARY KEY,
product_color_name TEXT NOT NULL
);"""
CREATE_PRODUCT_SIZE_TABLE = \
"""
CREATE TABLE IF NOT EXISTS product_size(
product_size_id SERIAL PRIMARY KEY,
product_size_name TEXT NOT NULL
);"""
CREATE_SKU_TABLE = \
"""
CREATE TABLE IF NOT EXISTS sku(
sku_id SERIAL PRIMARY KEY,
product_id INT NOT NULL,
product_size_id INT NOT NULL,
product_color_id INT NOT NULL,
FOREIGN KEY (product_id)
REFERENCES product(product_id),
FOREIGN KEY (product_size_id)
REFERENCES product_size(product_size_id),
FOREIGN KEY (product_color_id)
REFERENCES product_color(product_color_id)
);"""
COLOR_INSERT = \
"""
INSERT INTO product_color VALUES(1, 'Blue');
INSERT INTO product_color VALUES(2, 'Black');
"""
SIZE_INSERT = \
"""
INSERT INTO product_size VALUES(1, 'Small');
INSERT INTO product_size VALUES(2, 'Medium');
INSERT INTO product_size VALUES(3, 'Large');
"""
================================================
FILE: chapter_05/listing_5_3.py
================================================
import asyncpg
import asyncio
from chapter_05.listing_5_2 import *
async def main():
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='products',
password='password')
statements = [CREATE_BRAND_TABLE,
CREATE_PRODUCT_TABLE,
CREATE_PRODUCT_COLOR_TABLE,
CREATE_PRODUCT_SIZE_TABLE,
CREATE_SKU_TABLE,
SIZE_INSERT,
COLOR_INSERT]
print('Creating the product database...')
for statement in statements:
status = await connection.execute(statement)
print(status)
print('Finished creating the product database!')
await connection.close()
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_4.py
================================================
import asyncpg
import asyncio
from asyncpg import Record
from typing import List
async def main():
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='products',
password='password')
await connection.execute("INSERT INTO brand VALUES(DEFAULT, 'Levis')")
await connection.execute("INSERT INTO brand VALUES(DEFAULT, 'Seven')")
brand_query = 'SELECT brand_id, brand_name FROM brand'
results: List[Record] = await connection.fetch(brand_query)
for brand in results:
print(f'id: {brand["brand_id"]}, name: {brand["brand_name"]}')
await connection.close()
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_5.py
================================================
import asyncpg
import asyncio
from typing import List, Tuple, Union
from random import sample
def load_common_words() -> List[str]:
with open('common_words.txt') as common_words:
return common_words.readlines()
def generate_brand_names(words: List[str]) -> List[Tuple[Union[str, ]]]:
return [(words[index],) for index in sample(range(100), 100)]
async def insert_brands(common_words, connection) -> int:
brands = generate_brand_names(common_words)
insert_brands = "INSERT INTO brand VALUES(DEFAULT, $1)"
return await connection.executemany(insert_brands, brands)
async def main():
common_words = load_common_words()
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='products',
password='password')
await insert_brands(common_words, connection)
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_6.py
================================================
import asyncio
import asyncpg
from random import randint, sample
from typing import List, Tuple
from chapter_05.listing_5_5 import load_common_words
def gen_products(common_words: List[str],
brand_id_start: int,
brand_id_end: int,
products_to_create: int) -> List[Tuple[str, int]]:
products = []
for _ in range(products_to_create):
description = [common_words[index] for index in sample(range(1000), 10)]
brand_id = randint(brand_id_start, brand_id_end)
products.append((" ".join(description), brand_id))
return products
def gen_skus(product_id_start: int,
product_id_end: int,
skus_to_create: int) -> List[Tuple[int, int, int]]:
skus = []
for _ in range(skus_to_create):
product_id = randint(product_id_start, product_id_end)
size_id = randint(1, 3)
color_id = randint(1, 2)
skus.append((product_id, size_id, color_id))
return skus
async def main():
common_words = load_common_words()
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='products',
password='password')
product_tuples = gen_products(common_words,
brand_id_start=1,
brand_id_end=100,
products_to_create=1000)
await connection.executemany("INSERT INTO product VALUES(DEFAULT, $1, $2)",
product_tuples)
sku_tuples = gen_skus(product_id_start=1,
product_id_end=1000,
skus_to_create=100000)
await connection.executemany("INSERT INTO sku VALUES(DEFAULT, $1, $2, $3)",
sku_tuples)
await connection.close()
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_7.py
================================================
import asyncio
import asyncpg
product_query = \
"""
SELECT
p.product_id,
p.product_name,
p.brand_id,
s.sku_id,
pc.product_color_name,
ps.product_size_name
FROM product as p
JOIN sku as s on s.product_id = p.product_id
JOIN product_color as pc on pc.product_color_id = s.product_color_id
JOIN product_size as ps on ps.product_size_id = s.product_size_id
WHERE p.product_id = 100"""
async def query_product(pool):
async with pool.acquire() as connection:
return await connection.fetchrow(product_query)
async def main():
async with asyncpg.create_pool(host='127.0.0.1',
port=5432,
user='postgres',
password='password',
database='products',
min_size=6,
max_size=6) as pool: # A
await asyncio.gather(query_product(pool),
query_product(pool)) # B
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_8.py
================================================
import asyncio
import asyncpg
from util import async_timed
product_query = \
"""
SELECT
p.product_id,
p.product_name,
p.brand_id,
s.sku_id,
pc.product_color_name,
ps.product_size_name
FROM product as p
JOIN sku as s on s.product_id = p.product_id
JOIN product_color as pc on pc.product_color_id = s.product_color_id
JOIN product_size as ps on ps.product_size_id = s.product_size_id
WHERE p.product_id = 100"""
async def query_product(pool):
async with pool.acquire() as connection:
return await connection.fetchrow(product_query)
@async_timed()
async def query_products_synchronously(pool, queries):
return [await query_product(pool) for _ in range(queries)]
@async_timed()
async def query_products_concurrently(pool, queries):
queries = [query_product(pool) for _ in range(queries)]
return await asyncio.gather(*queries)
async def main():
async with asyncpg.create_pool(host='127.0.0.1',
port=5432,
user='postgres',
password='password',
database='products',
min_size=6,
max_size=6) as pool:
await query_products_synchronously(pool, 10000)
await query_products_concurrently(pool, 10000)
asyncio.run(main())
================================================
FILE: chapter_05/listing_5_9.py
================================================
import asyncio
import asyncpg
async def main():
connection = await asyncpg.connect(host='127.0.0.1',
port=5432,
user='postgres',
database='products',
password='password')
async with connection.transaction(): # A
await connection.execute("INSERT INTO brand "
"VALUES(DEFAULT, 'brand_1')")
await connection.execute("INSERT INTO brand "
"VALUES(DEFAULT, 'brand_2')")
query = """SELECT brand_name FROM brand
WHERE brand_name LIKE 'brand%'"""
brands = await connection.fetch(query) # B
print(brands)
await connection.close()
asyncio.run(main())
================================================
FILE: chapter_06/__init__.py
================================================
================================================
FILE: chapter_06/listing_6_1.py
================================================
import time
from multiprocessing import Process
def count(count_to: int) -> int:
start = time.time()
counter = 0
while counter < count_to:
counter = counter + 1
end = time.time()
print(f'Finished counting to {count_to} in {end-start}')
return counter
if __name__ == "__main__":
start_time = time.time()
to_one_hundred_million = Process(target=count, args=(100000000,))
to_two_hundred_million = Process(target=count, args=(200000000,))
to_one_hundred_million.start()
to_two_hundred_million.start()
to_one_hundred_million.join()
to_two_hundred_million.join()
end_time = time.time()
print(f'Completed in {end_time-start_time}')
================================================
FILE: chapter_06/listing_6_10.py
================================================
from multiprocessing import Process, Value, Array
def increment_value(shared_int: Value):
shared_int.value = shared_int.value + 1
def increment_array(shared_array: Array):
for index, integer in enumerate(shared_array):
shared_array[index] = integer + 1
if __name__ == '__main__':
integer = Value('i', 0)
integer_array = Array('i', [0, 0])
procs = [Process(target=increment_value, args=(integer,)),
Process(target=increment_array, args=(integer_array,))]
[p.start() for p in procs]
[p.join() for p in procs]
print(integer.value)
print(integer_array[:])
================================================
FILE: chapter_06/listing_6_11.py
================================================
from multiprocessing import Process, Value, cpu_count
def increment_value(shared_int: Value):
shared_int.value = shared_int.value + 1
if __name__ == '__main__':
print(cpu_count())
for _ in range(10000):
integer = Value('i', 0)
procs = [Process(target=increment_value, args=(integer,)),
Process(target=increment_value, args=(integer,))]
[p.start() for p in procs]
[p.join() for p in procs]
print(integer.value)
assert(integer.value == 2)
================================================
FILE: chapter_06/listing_6_12.py
================================================
from multiprocessing import Process, Value
def increment_value(shared_int: Value):
shared_int.get_lock().acquire()
shared_int.value = shared_int.value + 1
shared_int.get_lock().release()
if __name__ == '__main__':
for _ in range(100):
integer = Value('i', 0)
procs = [Process(target=increment_value, args=(integer,)),
Process(target=increment_value, args=(integer,))]
[p.start() for p in procs]
[p.join() for p in procs]
print(integer.value)
assert (integer.value == 2)
================================================
FILE: chapter_06/listing_6_13.py
================================================
from concurrent.futures import ProcessPoolExecutor
import asyncio
from multiprocessing import Value
shared_counter: Value
def init(counter: Value):
global shared_counter
shared_counter = counter
def increment():
with shared_counter.get_lock():
shared_counter.value += 1
async def main():
counter = Value('d', 0)
with ProcessPoolExecutor(initializer=init,
initargs=(counter,)) as pool:
await asyncio.get_running_loop().run_in_executor(pool, increment)
print(counter.value)
if __name__ == "__main__":
asyncio.run(main())
================================================
FILE: chapter_06/listing_6_14.py
================================================
from concurrent.futures import ProcessPoolExecutor
import functools
import asyncio
from multiprocessing import Value
from typing import List, Dict
from chapter_06.listing_6_8 import partition, merge_dictionaries
map_progress: Value
def init(progress: Value):
global map_progress
map_progress = progress
def map_frequencies(chunk: List[str]) -> Dict[str, int]:
counter = {}
for line in chunk:
word, _, count, _ = line.split('\t')
if counter.get(word):
counter[word] = counter[word] + int(count)
else:
counter[word] = int(count)
with map_progress.get_lock():
map_progress.value += 1
return counter
async def progress_reporter(total_partitions: int):
while map_progress.value < total_partitions:
print(f'Finished {map_progress.value}/{total_partitions} map operations')
await asyncio.sleep(1)
async def main(partiton_size: int):
global map_progress
with open('googlebooks-eng-all-1gram-20120701-a', encoding='utf-8') as f:
contents = f.readlines()
loop = asyncio.get_running_loop()
tasks = []
map_progress = Value('i', 0)
with ProcessPoolExecutor(initializer=init,
initargs=(map_progress,)) as pool:
total_partitions = len(contents) // partiton_size
reporter = asyncio.create_task(progress_reporter(total_partitions))
for chunk in partition(contents, partiton_size):
tasks.append(loop.run_in_executor(pool, functools.partial(map_frequencies, chunk)))
counters = await asyncio.gather(*tasks)
await reporter
final_result = functools.reduce(merge_dictionaries, counters)
print(f"Aardvark has appeared {final_result['Aardvark']} times.")
if __name__ == "__main__":
asyncio.run(main(partiton_size=60000))
================================================
FILE: chapter_06/listing_6_15.py
================================================
import asyncio
import asyncpg
from util import async_timed
from typing import List, Dict
from concurrent.futures.process import ProcessPoolExecutor
product_query = \
"""
SELECT
p.product_id,
p.product_name,
p.brand_id,
s.sku_id,
pc.product_color_name,
ps.product_size_name
FROM product as p
JOIN sku as s on s.product_id = p.product_id
JOIN product_color as pc on pc.product_color_id = s.product_color_id
JOIN product_size as ps on ps.product_size_id = s.product_size_id
WHERE p.product_id = 100"""
async def query_product(pool):
async with pool.acquire() as connection:
return await connection.fetchrow(product_query)
@async_timed()
async def query_products_concurrently(pool, queries):
queries = [query_product(pool) for _ in range(queries)]
return await asyncio.gather(*queries)
def run_in_new_loop(num_queries: int) -> List[Dict]:
async def run_queries():
async with asyncpg.create_pool(host='127.0.0.1',
port=5432,
user='postgres',
password='password',
database='products',
min_size=6,
max_size=6) as pool:
return await query_products_concurrently(pool, num_queries)
results = [dict(result) for result in asyncio.run(run_queries())] #A
return results
@async_timed()
async def main():
loop = asyncio.get_running_loop()
pool = ProcessPoolExecutor()
tasks = [loop.run_in_executor(pool, run_in_new_loop, 10000) for _ in range(5)] #B
all_results = await asyncio.gather(*tasks) #C
total_queries = sum([len(result) for result in all_results])
print(f'Retrieved {total_queries} products the product database.')
if __name__ == "__main__":
asyncio.run(main())
================================================
FILE: chapter_06/listing_6_2.py
================================================
from multiprocessing import Pool
def say_hello(name: str) -> str:
return f'Hi there, {name}'
if __name__ == "__main__":
with Pool() as process_pool: # A
hi_jeff = process_pool.apply(say_hello, args=('Jeff',)) # B
hi_john = process_pool.apply(say_hello, args=('John',))
print(hi_jeff)
print(hi_john)
================================================
FILE: chapter_06/listing_6_3.py
================================================
from multiprocessing import Pool
def say_hello(name: str) -> str:
return f'Hi there, {name}'
if __name__ == "__main__":
with Pool() as process_pool:
hi_jeff = process_pool.apply_async(say_hello, args=('Jeff',))
hi_john = process_pool.apply_async(say_hello, args=('John',))
print(hi_jeff.get())
print(hi_john.get())
================================================
FILE: chapter_06/listing_6_4.py
================================================
import time
from concurrent.futures import ProcessPoolExecutor
def count(count_to: int) -> int:
start = time.time()
counter = 0
while counter < count_to:
counter = counter + 1
end = time.time()
print(f'Finished counting to {count_to} in {end - start}')
return counter
if __name__ == "__main__":
with ProcessPoolExecutor() as process_pool:
numbers = [1, 3, 5, 22, 100000000]
for result in process_pool.map(count, numbers):
print(result)
================================================
FILE: chapter_06/listing_6_5.py
================================================
import asyncio
from asyncio.events import AbstractEventLoop
from concurrent.futures import ProcessPoolExecutor
from functools import partial
from typing import List
def countdown(count_from: int) -> int:
counter = 0
while counter < count_from:
counter = counter + 1
return counter
async def main():
with ProcessPoolExecutor() as process_pool:
loop: AbstractEventLoop = asyncio.get_running_loop()
nums = [1, 3, 5, 22, 100000000]
calls: List[partial[int]] = [partial(countdown, num) for num in nums]
call_coros = []
for call in calls:
call_coros.append(loop.run_in_executor(process_pool, call))
results = await asyncio.gather(*call_coros)
for result in results:
print(result)
if __name__ == "__main__":
asyncio.run(main())
================================================
FILE: chapter_06/listing_6_6.py
================================================
import functools
from typing import Dict
def map_frequency(text: str) -> Dict[str, int]:
words = text.split(' ')
frequencies = {}
for word in words:
if word in frequencies:
frequencies[word] = frequencies[word] + 1
else:
frequencies[word] = 1
return frequencies
def merge_dictionaries(first: Dict[str, int],
second: Dict[str, int]) -> Dict[str, int]:
merged = first
for key in second:
if key in merged:
merged[key] = merged[key] + second[key]
else:
merged[key] = second[key]
return merged
lines = ["I know what I know",
"I know that I know",
"I don't know much",
"They don't know much"]
mapped_results = [map_frequency(line) for line in lines]
for result in mapped_results:
print(result)
print(functools.reduce(merge_dictionaries, mapped_results))
================================================
FILE: chapter_06/listing_6_7.py
================================================
import time
freqs = {}
with open('googlebooks-eng-all-1gram-20120701-a', encoding='utf-8') as f:
lines = f.readlines()
start = time.time()
for line in lines:
data = line.split('\t')
word = data[0]
count = int(data[2])
if word in freqs:
freqs[word] = freqs[word] + count
else:
freqs[word] = count
end = time.time()
print(f'{end-start:.4f}')
================================================
FILE: chapter_06/listing_6_8.py
================================================
import asyncio
import concurrent.futures
import functools
import time
from typing import Dict, List
def partition(data: List,
chunk_size: int) -> List:
for i in range(0, len(data), chunk_size):
yield data[i:i + chunk_size]
def map_frequencies(chunk: List[str]) -> Dict[str, int]:
counter = {}
for line in chunk:
word, _, count, _ = line.split('\t')
if counter.get(word):
counter[word] = counter[word] + int(count)
else:
counter[word] = int(count)
return counter
def merge_dictionaries(first: Dict[str, int],
second: Dict[str, int]) -> Dict[str, int]:
merged = first
for key in second:
if key in merged:
merged[key] = merged[key] + second[key]
else:
merged[key] = second[key]
return merged
async def main(partition_size: int):
with open('googlebooks-eng-all-1gram-20120701-a', encoding='utf-8') as f:
contents = f.readlines()
loop = asyncio.get_running_loop()
tasks = []
start = time.time()
with concurrent.futures.ProcessPoolExecutor() as pool:
for chunk in partition(contents, partition_size):
tasks.append(loop.run_in_executor(pool, functools.partial(map_frequencies, chunk)))
intermediate_results = await asyncio.gather(*tasks)
final_result = functools.reduce(merge_dictionaries, intermediate_results)
print(f"Aardvark has appeared {final_result['Aardvark']} times.")
end = time.time()
print(f'MapReduce took: {(end - start):.4f} seconds')
if __name__ == "__main__":
asyncio.run(main(partition_size=60000))
================================================
FILE: chapter_06/listing_6_9.py
================================================
import asyncio
import concurrent.futures
import functools
import time
from typing import Dict, List
from chapter_06.listing_6_8 import partition, merge_dictionaries, map_frequencies
async def reduce(loop, pool, counters, chunk_size) -> Dict[str, int]:
chunks: List[List[Dict]] = list(partition(counters, chunk_size)) #A
reducers = []
while len(chunks[0]) > 1:
for chunk in chunks:
reducer = functools.partial(functools.reduce, merge_dictionaries, chunk) #B
reducers.append(loop.run_in_executor(pool, reducer))
reducer_chunks = await asyncio.gather(*reducers) #C
chunks = list(partition(reducer_chunks, chunk_size)) #D
reducers.clear()
return chunks[0][0]
async def main(partition_size: int):
with open('googlebooks-eng-all-1gram-20120701-a', encoding='utf-8') as f:
contents = f.readlines()
loop = asyncio.get_running_loop()
tasks = []
with concurrent.futures.ProcessPoolExecutor() as pool:
start = time.time()
for chunk in partition(contents, partition_size):
tasks.append(loop.run_in_executor(pool, functools.partial(map_frequencies, chunk)))
intermediate_results = await asyncio.gather(*tasks)
final_result = await reduce(loop, pool, intermediate_results, 500)
print(f"Aardvark has appeared {final_result['Aardvark']} times.")
end = time.time()
print(f'MapReduce took: {(end - start):.4f} seconds')
if __name__ == "__main__":
asyncio.run(main(partition_size=60000))
================================================
FILE: chapter_07/__init__.py
================================================
================================================
FILE: chapter_07/listing_7_1.py
================================================
from threading import Thread
import socket
def echo(client: socket):
while True:
data = client.recv(2048)
print(f'Received {data}, sending!')
client.sendall(data)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('127.0.0.1', 8000))
server.listen()
while True:
connection, _ = server.accept() # A
thread = Thread(target=echo, args=(connection,)) # B
thread.start() # C
================================================
FILE: chapter_07/listing_7_10.py
================================================
from threading import Lock
from typing import List
class IntListThreadsafe:
def __init__(self, wrapped_list: List[int]):
self._lock = Lock()
self._inner_list = wrapped_list
def indices_of(self, to_find: int) -> List[int]:
with self._lock:
enumerator = enumerate(self._inner_list)
return [index for index, value in enumerator if value == to_find]
def find_and_replace(self,
to_replace: int,
replace_with: int) -> None:
with self._lock:
indices = self.indices_of(to_replace)
for index in indices:
self._inner_list[index] = replace_with
threadsafe_list = IntListThreadsafe([1, 2, 1, 2, 1])
threadsafe_list.find_and_replace(1, 2)
================================================
FILE: chapter_07/listing_7_11.py
================================================
from threading import Lock, Thread
import time
lock_a = Lock()
lock_b = Lock()
def a():
with lock_a: #A
print('Acquired lock a from method a!')
time.sleep(1) #B
with lock_b: #C
print('Acquired both locks from method a!')
def b():
with lock_b: #D
print('Acquired lock b from method b!')
with lock_a: #E
print('Acquired both locks from method b!')
thread_1 = Thread(target=a)
thread_2 = Thread(target=b)
thread_1.start()
thread_2.start()
thread_1.join()
thread_2.join()
================================================
FILE: chapter_07/listing_7_12.py
================================================
import tkinter
from tkinter import ttk
window = tkinter.Tk()
window.title('Hello world app')
window.geometry('200x100')
def say_hello():
print('Hello there!')
hello_button = ttk.Button(window, text='Say hello', command=say_hello)
hello_button.pack()
window.mainloop()
================================================
FILE: chapter_07/listing_7_13.py
================================================
import asyncio
from concurrent.futures import Future
from asyncio import AbstractEventLoop
from typing import Callable, Optional
from aiohttp import ClientSession
class StressTest:
def __init__(self,
loop: AbstractEventLoop,
url: str,
total_requests: int,
callback: Callable[[int, int], None]):
self._completed_requests: int = 0
self._load_test_future: Optional[Future] = None
self._loop = loop
self._url = url
self._total_requests = total_requests
self._callback = callback
self._refresh_rate = total_requests // 100
def start(self):
future = asyncio.run_coroutine_threadsafe(self._make_requests(), self._loop)
self._load_test_future = future
def cancel(self):
if self._load_test_future:
self._loop.call_soon_threadsafe(self._load_test_future.cancel) # B
async def _get_url(self, session: ClientSession, url: str):
try:
await session.get(url)
except Exception as e:
print(e)
self._completed_requests = self._completed_requests + 1 # C
if self._completed_requests % self._refresh_rate == 0 \
or self._completed_requests == self._total_requests:
self._callback(self._completed_requests, self._total_requests)
async def _make_requests(self):
async with ClientSession() as session:
reqs = [self._get_url(session, self._url) for _ in range(self._total_requests)]
await asyncio.gather(*reqs)
================================================
FILE: chapter_07/listing_7_14.py
================================================
from queue import Queue
from tkinter import Tk
from tkinter import Label
from tkinter import Entry
from tkinter import ttk
from typing import Optional
from chapter_07.listing_7_13 import StressTest
class LoadTester(Tk):
def __init__(self, loop, *args, **kwargs): # A
Tk.__init__(self, *args, **kwargs)
self._queue = Queue()
self._refresh_ms = 25
self._loop = loop
self._load_test: Optional[StressTest] = None
self.title('URL Requester')
self._url_label = Label(self, text="URL:")
self._url_label.grid(column=0, row=0)
self._url_field = Entry(self, width=10)
self._url_field.grid(column=1, row=0)
self._request_label = Label(self, text="Number of requests:")
self._request_label.grid(column=0, row=1)
self._request_field = Entry(self, width=10)
self._request_field.grid(column=1, row=1)
self._submit = ttk.Button(self, text="Submit", command=self._start) # B
self._submit.grid(column=2, row=1)
self._pb_label = Label(self, text="Progress:")
self._pb_label.grid(column=0, row=3)
self._pb = ttk.Progressbar(self, orient="horizontal", length=200, mode="determinate")
self._pb.grid(column=1, row=3, columnspan=2)
def _update_bar(self, pct: int): # C
if pct == 100:
self._load_test = None
self._submit['text'] = 'Submit'
else:
self._pb['value'] = pct
self.after(self._refresh_ms, self._poll_queue)
def _queue_update(self, completed_requests: int, total_requests: int): # D
self._queue.put(int(completed_requests / total_requests * 100))
def _poll_queue(self): # E
if not self._queue.empty():
percent_complete = self._queue.get()
self._update_bar(percent_complete)
else:
if self._load_test:
self.after(self._refresh_ms, self._poll_queue)
def _start(self): # F
if self._load_test is None:
self._submit['text'] = 'Cancel'
test = StressTest(self._loop,
self._url_field.get(),
int(self._request_field.get()),
self._queue_update)
self.after(self._refresh_ms, self._poll_queue)
test.start()
self._load_test = test
else:
self._load_test.cancel()
self._load_test = None
self._submit['text'] = 'Submit'
================================================
FILE: chapter_07/listing_7_15.py
================================================
import asyncio
from asyncio import AbstractEventLoop
from threading import Thread
from chapter_07.listing_7_14 import LoadTester
class ThreadedEventLoop(Thread): #A
def __init__(self, loop: AbstractEventLoop):
super().__init__()
self._loop = loop
self.daemon = True
def run(self):
self._loop.run_forever()
loop = asyncio.new_event_loop()
asyncio_thread = ThreadedEventLoop(loop)
asyncio_thread.start() #B
app = LoadTester(loop) #C
app.mainloop()
================================================
FILE: chapter_07/listing_7_16.py
================================================
import hashlib
import os
import string
import time
import random
def random_password(length: int) -> bytes:
ascii_lowercase = string.ascii_lowercase.encode()
return b''.join(bytes(random.choice(ascii_lowercase)) for _ in range(length))
passwords = [random_password(10) for _ in range(10000)]
def hash(password: bytes) -> str:
salt = os.urandom(16)
return str(hashlib.scrypt(password, salt=salt, n=2048, p=1, r=8))
start = time.time()
for password in passwords:
hash(password)
end = time.time()
print(end - start)
================================================
FILE: chapter_07/listing_7_17.py
================================================
import asyncio
import functools
import hashlib
import os
from concurrent.futures.thread import ThreadPoolExecutor
import random
import string
from util import async_timed
def random_password(length: int) -> bytes:
ascii_lowercase = string.ascii_lowercase.encode()
return b''.join(bytes(random.choice(ascii_lowercase)) for _ in range(length))
passwords = [random_password(10) for _ in range(10000)]
def hash(password: bytes) -> str:
salt = os.urandom(16)
return str(hashlib.scrypt(password, salt=salt, n=2048, p=1, r=8))
@async_timed()
async def main():
loop = asyncio.get_running_loop()
tasks = []
with ThreadPoolExecutor() as pool:
for password in passwords:
tasks.append(loop.run_in_executor(pool, functools.partial(hash, password)))
await asyncio.gather(*tasks)
asyncio.run(main())
================================================
FILE: chapter_07/listing_7_18.py
================================================
import numpy as np
import time
data_points = 4000000000
rows = 50
columns = int(data_points / rows)
matrix = np.arange(data_points).reshape(rows, columns)
s = time.time()
res = np.mean(matrix, axis=1)
e = time.time()
print(e - s)
================================================
FILE: chapter_07/listing_7_19.py
================================================
import functools
from concurrent.futures.thread import ThreadPoolExecutor
import numpy as np
import asyncio
from util import async_timed
def mean_for_row(arr, row):
return np.mean(arr[row])
data_points = 4000000000
rows = 50
columns = int(data_points / rows)
matrix = np.arange(data_points).reshape(rows, columns)
@async_timed()
async def main():
loop = asyncio.get_running_loop()
with ThreadPoolExecutor() as pool:
tasks = []
for i in range(rows):
mean = functools.partial(mean_for_row, matrix, i)
tasks.append(loop.run_in_executor(pool, mean))
results = asyncio.gather(*tasks)
asyncio.run(main())
================================================
FILE: chapter_07/listing_7_2.py
================================================
from threading import Thread
import socket
class ClientEchoThread(Thread):
def __init__(self, client):
super().__init__()
self.client = client
def run(self):
try:
while True:
data = self.client.recv(2048)
if not data: #A
raise BrokenPipeError('Connection closed!')
print(f'Received {data}, sending!')
self.client.sendall(data)
except OSError as e: #B
print(f'Thread interrupted by {e} exception, shutting down!')
def close(self):
if self.is_alive(): #C
self.client.sendall(bytes('Shutting down!', encoding='utf-8'))
self.client.shutdown(socket.SHUT_RDWR) #D
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('127.0.0.1', 8000))
server.listen()
connection_threads = []
try:
while True:
connection, addr = server.accept()
thread = ClientEchoThread(connection)
connection_threads.append(thread)
thread.start()
except KeyboardInterrupt:
print('Shutting down!')
[thread.close() for thread in connection_threads] #E
================================================
FILE: chapter_07/listing_7_3.py
================================================
import requests
def get_status_code(url: str) -> int:
response = requests.get(url)
return response.status_code
url = 'https://www.example.com'
print(get_status_code(url))
print(get_status_code(url))
================================================
FILE: chapter_07/listing_7_4.py
================================================
import time
import requests
from concurrent.futures import ThreadPoolExecutor
def get_status_code(url: str) -> int:
response = requests.get(url)
return response.status_code
start = time.time()
with ThreadPoolExecutor(max_workers=1000) as pool:
urls = ['https://www.example.com' for _ in range(1000)]
results = pool.map(get_status_code, urls)
for result in results:
print(result)
end = time.time()
print(f'finished requests in {end - start:.4f} second(s)')
================================================
FILE: chapter_07/listing_7_5.py
================================================
import functools
import requests
import asyncio
from concurrent.futures import ThreadPoolExecutor
from util import async_timed
def get_status_code(url: str) -> int:
response = requests.get(url)
return response.status_code
@async_timed()
async def main():
loop = asyncio.get_running_loop()
with ThreadPoolExecutor() as pool:
urls = ['https://www.example.com' for _ in range(1000)]
tasks = [loop.run_in_executor(pool, functools.partial(get_status_code, url)) for url in urls]
results = await asyncio.gather(*tasks)
print(results)
asyncio.run(main())
================================================
FILE: chapter_07/listing_7_6.py
================================================
import functools
import requests
import asyncio
from util import async_timed
def get_status_code(url: str) -> int:
response = requests.get(url)
return response.status_code
@async_timed()
async def main():
loop = asyncio.get_running_loop()
urls = ['https://www.example.com' for _ in range(1000)]
tasks = [loop.run_in_executor(None, functools.partial(get_status_code, url)) for url in urls]
results = await asyncio.gather(*tasks)
print(results)
asyncio.run(main())
================================================
FILE: chapter_07/listing_7_7.py
================================================
import requests
import asyncio
from util import async_timed
def get_status_code(url: str) -> int:
response = requests.get(url)
return response.status_code
@async_timed()
async def main():
urls = ['https://www.example.com' for _ in range(1000)]
tasks = [asyncio.to_thread(get_status_code, url) for url in urls]
results = await asyncio.gather(*tasks)
print(results)
asyncio.run(main())
================================================
FILE: chapter_07/listing_7_8.py
================================================
import functools
import requests
import asyncio
from concurrent.futures import ThreadPoolExecutor
from threading import Lock
from util import async_timed
counter_lock = Lock()
counter: int = 0
def get_status_code(url: str) -> int:
global counter
response = requests.get(url)
with counter_lock:
counter = counter + 1
return response.status_code
async def reporter(request_count: int):
while counter < request_count:
print(f'Finished {counter}/{request_count} requests')
await asyncio.sleep(.5)
@async_timed()
async def main():
loop = asyncio.get_running_loop()
with ThreadPoolExecutor() as pool:
request_count = 200
urls = ['https://www.example.com' for _ in range(request_count)]
reporter_task = asyncio.create_task(reporter(request_count))
tasks = [loop.run_in_executor(pool, functools.partial(get_status_code, url)) for url in urls]
results = await asyncio.gather(*tasks)
await reporter_task
print(results)
asyncio.run(main())
================================================
FILE: chapter_07/listing_7_9.py
================================================
from threading import Lock, Thread
from typing import List
list_lock = Lock()
def sum_list(int_list: List[int]) -> int:
print('Waiting to acquire lock...')
with list_lock:
print('Acquired lock.')
if len(int_list) == 0:
print('Finished summing.')
return 0
else:
head, *tail = int_list
print('Summing rest of list.')
return head + sum_list(tail)
thread = Thread(target=sum_list, args=([1, 2, 3, 4],))
thread.start()
thread.join()
================================================
FILE: chapter_08/__init__.py
================================================
================================================
FILE: chapter_08/listing_8_1.py
================================================
import asyncio
from asyncio import Transport, Future, AbstractEventLoop
from typing import Optional
class HTTPGetClientProtocol(asyncio.Protocol):
def __init__(self, host: str, loop: AbstractEventLoop):
self._host: str = host
self._future: Future = loop.create_future()
self._transport: Optional[Transport] = None
self._response_buffer: bytes = b''
async def get_response(self): # A
return await self._future
def _get_request_bytes(self) -> bytes: # B
request = f"GET / HTTP/1.1\r\n" \
f"Connection: close\r\n" \
f"Host: {self._host}\r\n\r\n"
return request.encode()
def connection_made(self, transport: Transport):
print(f'Connection made to {self._host}')
self._transport = transport
self._transport.write(self._get_request_bytes()) # C
def data_received(self, data):
print(f'Data received!')
self._response_buffer = self._response_buffer + data # D
def eof_received(self) -> Optional[bool]:
self._future.set_result(self._response_buffer.decode()) # E
return False
def connection_lost(self, exc: Optional[Exception]) -> None: # F
if exc is None:
print('Connection closed without error.')
else:
self._future.set_exception(exc)
================================================
FILE: chapter_08/listing_8_10.py
================================================
import asyncio
import os
import tty
from collections import deque
from chapter_08.listing_8_5 import create_stdin_reader
from chapter_08.listing_8_7 import *
from chapter_08.listing_8_8 import read_line
from chapter_08.listing_8_9 import MessageStore
async def sleep(delay: int, message_store: MessageStore):
await message_store.append(f'Starting delay {delay}') #A
await asyncio.sleep(delay)
await message_store.append(f'Finished delay {delay}')
async def main():
tty.setcbreak(sys.stdin)
os.system('clear')
rows = move_to_bottom_of_screen()
async def redraw_output(items: deque): #B
save_cursor_position()
move_to_top_of_screen()
for item in items:
delete_line()
print(item)
restore_cursor_position()
messages = MessageStore(redraw_output, rows - 1)
stdin_reader = await create_stdin_reader()
while True:
line = await read_line(stdin_reader)
delay_time = int(line)
asyncio.create_task(sleep(delay_time, messages))
asyncio.run(main())
================================================
FILE: chapter_08/listing_8_11.py
================================================
import asyncio
import asyncpg
import os
import tty
from collections import deque
from asyncpg.pool import Pool
from chapter_08.listing_8_5 import create_stdin_reader
from chapter_08.listing_8_7 import *
from chapter_08.listing_8_8 import read_line
from chapter_08.listing_8_9 import MessageStore
async def run_query(query: str, pool: Pool, message_store: MessageStore):
async with pool.acquire() as connection:
try:
result = await connection.fetchrow(query)
await message_store.append(f'Fetched {len(result)} rows from: {query}')
except Exception as e:
await message_store.append(f'Got exception {e} from: {query}')
async def main():
tty.setcbreak(0)
os.system('clear')
rows = move_to_bottom_of_screen()
async def redraw_output(items: deque):
save_cursor_position()
move_to_top_of_screen()
for item in items:
delete_line()
print(item)
restore_cursor_position()
messages = MessageStore(redraw_output, rows - 1)
stdin_reader = await create_stdin_reader()
async with asyncpg.create_pool(host='127.0.0.1',
port=5432,
user='postgres',
password='password',
database='products',
min_size=6,
max_size=6) as pool:
while True:
query = await read_line(stdin_reader)
asyncio.create_task(run_query(query, pool, messages))
asyncio.run(main())
================================================
FILE: chapter_08/listing_8_12.py
================================================
import asyncio
import logging
from asyncio import StreamReader, StreamWriter
class ServerState:
def __init__(self):
self._writers = []
async def add_client(self, reader: StreamReader, writer: StreamWriter): #A
self._writers.append(writer)
await self._on_connect(writer)
asyncio.create_task(self._echo(reader, writer))
async def _on_connect(self, writer: StreamWriter): #B
writer.write(f'Welcome! {len(self._writers)} user(s) are online!\n'.encode())
await writer.drain()
await self._notify_all('New user connected!\n')
async def _echo(self, reader: StreamReader, writer: StreamWriter): #C
try:
while (data := await reader.readline()) != b'':
writer.write(data)
await writer.drain()
self._writers.remove(writer)
await self._notify_all(f'Client disconnected. {len(self._writers)} user(s) are online!\n')
except Exception as e:
logging.exception('Error reading from client.', exc_info=e)
self._writers.remove(writer)
async def _notify_all(self, message: str): #D
for writer in self._writers:
try:
writer.write(message.encode())
await writer.drain()
except ConnectionError as e:
logging.exception('Could not write to client.', exc_info=e)
self._writers.remove(writer)
async def main():
server_state = ServerState()
async def client_connected(reader: StreamReader, writer: StreamWriter) -> None: #E
await server_state.add_client(reader, writer)
server = await asyncio.start_server(client_connected, '127.0.0.1', 8000) #F
async with server:
await server.serve_forever()
asyncio.run(main())
================================================
FILE: chapter_08/listing_8_13.py
================================================
import asyncio
import logging
from asyncio import StreamReader, StreamWriter
class ChatServer:
def __init__(self):
self._username_to_writer = {}
async def start_chat_server(self, host: str, port: int):
server = await asyncio.start_server(self.client_connected, host, port)
async with server:
await server.serve_forever()
async def client_connected(self, reader: StreamReader, writer: StreamWriter): #A
command = await reader.readline()
print(f'CONNECTED {reader} {writer}')
command, args = command.split(b' ')
if command == b'CONNECT':
username = args.replace(b'\n', b'').decode()
self._add_user(username, reader, writer)
await self._on_connect(username, writer)
else:
logging.error('Got invalid command from client, disconnecting.')
writer.close()
await writer.wait_closed()
def _add_user(self, username: str, reader: StreamReader, writer: StreamWriter): #B
self._username_to_writer[username] = writer
asyncio.create_task(self._listen_for_messages(username, reader))
async def _on_connect(self, username: str, writer: StreamWriter): #C
writer.write(f'Welcome! {len(self._username_to_writer)} user(s) are online!\n'.encode())
await writer.drain()
await self._notify_all(f'{username} connected!\n')
async def _remove_user(self, username: str):
writer = self._username_to_writer[username]
del self._username_to_writer[username]
try:
writer.close()
await writer.wait_closed()
except Exception as e:
logging.exception('Error closing client writer, ignoring.', exc_info=e)
async def _listen_for_messages(self,
username: str,
reader: StreamReader): #D
try:
while (data := await asyncio.wait_for(reader.readline(), 60)) != b'':
await self._notify_all(f'{username}: {data.decode()}')
await self._notify_all(f'{username} has left the chat\n')
except Exception as e:
logging.exception('Error reading from client.', exc_info=e)
await self._remove_user(username)
async def _notify_all(self, message: str): #E
inactive_users = []
for username, writer in self._username_to_writer.items():
try:
writer.write(message.encode())
await writer.drain()
except ConnectionError as e:
logging.exception('Could not write to client.', exc_info=e)
inactive_users.append(username)
[await self._remove_user(username) for username in inactive_users]
async def main():
chat_server = ChatServer()
await chat_server.start_chat_server('127.0.0.1', 8000)
asyncio.run(main())
================================================
FILE: chapter_08/listing_8_14.py
================================================
import asyncio
import os
import logging
import tty
from asyncio import StreamReader, StreamWriter
from collections import deque
from chapter_08.listing_8_5 import create_stdin_reader
from chapter_08.listing_8_7 import *
from chapter_08.listing_8_8 import read_line
from chapter_08.listing_8_9 import MessageStore
async def send_message(message: str, writer: StreamWriter):
writer.write((message + '\n').encode())
await writer.drain()
async def listen_for_messages(reader: StreamReader,
message_store: MessageStore): # A
while (message := await reader.readline()) != b'':
await message_store.append(message.decode())
await message_store.append('Server closed connection.')
async def read_and_send(stdin_reader: StreamReader,
writer: StreamWriter): # B
while True:
message = await read_line(stdin_reader)
await send_message(message, writer)
async def main():
async def redraw_output(items: deque):
save_cursor_position()
move_to_top_of_screen()
for item in items:
delete_line()
sys.stdout.write(item)
restore_cursor_position()
tty.setcbreak(0)
os.system('clear')
rows = move_to_bottom_of_screen()
messages = MessageStore(redraw_output, rows - 1)
stdin_reader = await create_stdin_reader()
sys.stdout.write('Enter username: ')
username = await read_line(stdin_reader)
reader, writer = await asyncio.open_connection('127.0.0.1', 8000) # C
writer.write(f'CONNECT {username}\n'.encode())
await writer.drain()
message_listener = asyncio.create_task(listen_for_messages(reader, messages)) # D
input_listener = asyncio.create_task(read_and_send(stdin_reader, writer))
try:
await asyncio.wait([message_listener, input_listener], return_when=asyncio.FIRST_COMPLETED)
except Exception as e:
logging.exception(e)
writer.close()
await writer.wait_closed()
asyncio.run(main())
================================================
FILE: chapter_08/listing_8_2.py
================================================
import asyncio
from asyncio import AbstractEventLoop
from chapter_08.listing_8_1 import HTTPGetClientProtocol
async def make_request(host: str, port: int, loop: AbstractEventLoop) -> str:
def protocol_factory():
return HTTPGetClientProtocol(host, loop)
_, protocol = await loop.create_connection(protocol_factory, host=host, port=port)
return await protocol.get_response()
async def main():
loop = asyncio.get_running_loop()
result = await make_request('www.example.com', 80, loop)
print(result)
asyncio.run(main())
================================================
FILE: chapter_08/listing_8_3.py
================================================
import asyncio
from asyncio import StreamReader
from typing import AsyncGenerator
async def read_until_empty(stream_reader: StreamReader) -> AsyncGenerator[str, None]:
while response := await stream_reader.readline(): #A
yield response.decode()
async def main():
host: str = 'www.example.com'
request: str = f"GET / HTTP/1.1\r\n" \
f"Connection: close\r\n" \
f"Host: {host}\r\n\r\n"
stream_reader, stream_writer = await asyncio.open_connection('www.example.com', 80)
try:
stream_writer.write(request.encode()) #B
await stream_writer.drain()
responses = [response async for response in read_until_empty(stream_reader)] #C
print(''.join(responses))
finally:
stream_writer.close() #D
await stream_writer.wait_closed()
asyncio.run(main())
================================================
FILE: chapter_08/listing_8_4.py
================================================
import asyncio
from util import delay
async def main():
while True:
delay_time = input('Enter a time to sleep:')
asyncio.create_task(delay(int(delay_time)))
asyncio.run(main())
================================================
FILE: chapter_08/listing_8_5.py
================================================
import asyncio
import sys
from asyncio import StreamReader
async def create_stdin_reader() -> StreamReader:
stream_reader = asyncio.StreamReader()
protocol = asyncio.StreamReaderProtocol(stream_reader)
loop = asyncio.get_running_loop()
await loop.connect_read_pipe(lambda: protocol, sys.stdin)
return stream_reader
================================================
FILE: chapter_08/listing_8_6.py
================================================
import asyncio
from chapter_08.listing_8_5 import create_stdin_reader
from util import delay
async def main():
stdin_reader = await create_stdin_reader()
while True:
delay_time = await stdin_reader.readline()
asyncio.create_task(delay(int(delay_time)))
asyncio.run(main())
================================================
FILE: chapter_08/listing_8_7.py
================================================
import sys
import shutil
def save_cursor_position():
sys.stdout.write('\0337')
def restore_cursor_position():
sys.stdout.write('\0338')
def move_to_top_of_screen():
sys.stdout.write('\033[H')
def delete_line():
sys.stdout.write('\033[2K')
def clear_line():
sys.stdout.write('\033[2K\033[0G')
def move_back_one_char():
sys.stdout.write('\033[1D')
def move_to_bottom_of_screen() -> int:
_, total_rows = shutil.get_terminal_size()
input_row = total_rows - 1
sys.stdout.write(f'\033[{input_row}E')
return total_rows
================================================
FILE: chapter_08/listing_8_8.py
================================================
import sys
from asyncio import StreamReader
from collections import deque
from chapter_08.listing_8_7 import move_back_one_char, clear_line
async def read_line(stdin_reader: StreamReader) -> str:
def erase_last_char():
move_back_one_char()
sys.stdout.write(' ')
move_back_one_char()
delete_char = b'\x7f'
input_buffer = deque()
while (input_char := await stdin_reader.read(1)) != b'\n':
if input_char == delete_char:
if len(input_buffer) > 0:
input_buffer.pop()
erase_last_char()
sys.stdout.flush()
else:
input_buffer.append(input_char)
sys.stdout.write(input_char.decode())
sys.stdout.flush()
clear_line()
return b''.join(input_buffer).decode()
================================================
FILE: chapter_08/listing_8_9.py
================================================
from collections import deque
from typing import Callable, Deque, Awaitable
class MessageStore:
def __init__(self, callback: Callable[[Deque], Awaitable[None]], max_size: int):
self._deque = deque(maxlen=max_size)
self._callback = callback
async def append(self, item):
self._deque.append(item)
await self._callback(self._deque)
================================================
FILE: chapter_09/__init__.py
================================================
================================================
FILE: chapter_09/async_views/async_api/__init__.py
================================================
================================================
FILE: chapter_09/async_views/async_api/admin.py
================================================
from django.contrib import admin
# Register your models here.
================================================
FILE: chapter_09/async_views/async_api/apps.py
================================================
from django.apps import AppConfig
class AsyncApiConfig(AppConfig):
name = 'async_api'
================================================
FILE: chapter_09/async_views/async_api/migrations/__init__.py
================================================
================================================
FILE: chapter_09/async_views/async_api/models.py
================================================
from django.db import models
class Url(models.Model):
question_text = models.CharField(max_length=200)
================================================
FILE: chapter_09/async_views/async_api/templates/async_api/requests.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Request Summary</title>
</head>
<body>
<h1>Summary of requests:</h1>
<h2>Failures:</h2>
<table>
{% for failure in failed_results %}
<tr>
<td>{{failure}}</td>
</tr>
{% endfor %}
</table>
<h2>Successful Results:</h2>
<table>
<tr>
<td>Status code</td>
<td>Response time (microseconds)</td>
<td>Response size</td>
</tr>
{% for result in successful_results %}
<tr>
<td>{{result.status}}</td>
<td>{{result.time}}</td>
<td>{{result.body_length}}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
================================================
FILE: chapter_09/async_views/async_api/tests.py
================================================
from django.test import TestCase
# Create your tests here.
================================================
FILE: chapter_09/async_views/async_api/urls.py
================================================
from django.urls import path
from . import views
app_name = 'async_api'
urlpatterns = [
path('', views.requests_view, name='requests'),
path('sync_to_async', views.sync_to_async_view),
path('async_to_sync', views.requests_view_sync)
]
================================================
FILE: chapter_09/async_views/async_api/views.py
================================================
import asyncio
from datetime import datetime
from aiohttp import ClientSession
from django.shortcuts import render
import aiohttp
async def get_url_details(session: ClientSession, url: str):
start_time = datetime.now()
response = await session.get(url)
response_body = await response.text()
end_time = datetime.now()
return {'status': response.status,
'time': (end_time - start_time).microseconds,
'body_length': len(response_body)}
async def make_requests(url: str, request_num: int):
async with aiohttp.ClientSession() as session:
requests = [get_url_details(session, url) for _ in range(request_num)]
results = await asyncio.gather(*requests, return_exceptions=True)
failed_results = [str(result) for result in results if isinstance(result, Exception)]
successful_results = [result for result in results if not isinstance(result, Exception)]
return {'failed_results': failed_results, 'successful_results': successful_results}
async def requests_view(request):
url: str = request.GET['url']
request_num: int = int(request.GET['request_num'])
context = await make_requests(url, request_num)
return render(request, 'async_api/requests.html', context)
from functools import partial
from django.http import HttpResponse
from asgiref.sync import sync_to_async
def sleep(seconds: int):
import time
time.sleep(seconds)
async def sync_to_async_view(request):
sleep_time: int = int(request.GET['sleep_time'])
num_calls: int = int(request.GET['num_calls'])
thread_sensitive: bool = request.GET['thread_sensitive'] == 'True'
function = sync_to_async(partial(sleep, sleep_time), thread_sensitive=thread_sensitive)
await asyncio.gather(*[function() for _ in range(num_calls)])
return HttpResponse('')
from asgiref.sync import async_to_sync
def requests_view_sync(request):
url: str = request.GET['url']
request_num: int = int(request.GET['request_num'])
context = async_to_sync(partial(make_requests, url, request_num))()
return render(request, 'async_api/requests.html', context)
================================================
FILE: chapter_09/async_views/async_views/__init__.py
================================================
================================================
FILE: chapter_09/async_views/async_views/asgi.py
================================================
"""
ASGI config for async_views project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'async_views.settings')
application = get_asgi_application()
================================================
FILE: chapter_09/async_views/async_views/settings.py
================================================
"""
Django settings for async_views project.
Generated by 'django-admin startproject' using Django 3.1.3.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '0!8mh80vh&au77%mk25+n@i=2va0*@=cta_!l0r2)ad-g+*rue'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'async_api'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'async_views.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'async_views.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = '/static/'
================================================
FILE: chapter_09/async_views/async_views/urls.py
================================================
"""async_views URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('requests/', include('async_api.urls'))
]
================================================
FILE: chapter_09/async_views/async_views/wsgi.py
================================================
"""
WSGI config for async_views project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'async_views.settings')
application = get_wsgi_application()
================================================
FILE: chapter_09/async_views/manage.py
================================================
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'async_views.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
================================================
FILE: chapter_09/listing_9_1.py
================================================
from aiohttp import web
from datetime import datetime
from aiohttp.web_request import Request
from aiohttp.web_response import Response
routes = web.RouteTableDef()
@routes.get('/time') # A
async def time(request: Request) -> Response:
today = datetime.today()
result = {
'month': today.month,
'day': today.day,
'time': str(today.time())
}
return web.json_response(result) # B
app = web.Application() # C
app.add_routes(routes)
web.run_app(app)
================================================
FILE: chapter_09/listing_9_10.html
================================================
<!DOCTYPE html>
<html lang="">
<head>
<title>Starlette Web Sockets</title>
<script>
document.addEventListener("DOMContentLoaded", () => {
let socket = new WebSocket("ws://localhost:8000/counter");
socket.onmessage = (event) => {
const counter = document.querySelector("#counter");
counter.textContent = event.data;
};
});
</script>
</head>
<body>
<span>Users online: </span>
<span id="counter"></span>
</body>
</html>
================================================
FILE: chapter_09/listing_9_2.py
================================================
import asyncpg
from aiohttp import web
from aiohttp.web_app import Application
from aiohttp.web_request import Request
from aiohttp.web_response import Response
from asyncpg import Record
from asyncpg.pool import Pool
from typing import List, Dict
routes = web.RouteTableDef()
DB_KEY = 'database'
async def create_database_pool(app: Application): #A
print('Creating database pool.')
pool: Pool = await asyncpg.create_pool(host='127.0.0.1',
port=5432,
user='postgres',
password='password',
database='products',
min_size=6,
max_size=6)
app[DB_KEY] = pool
async def destroy_database_pool(app: Application): #B
print('Destroying database pool.')
pool: Pool = app[DB_KEY]
await pool.close()
@routes.get('/brands')
async def brands(request: Request) -> Response: #C
connection: Pool = request.app[DB_KEY]
brand_query = 'SELECT brand_id, brand_name FROM brand'
results: List[Record] = await connection.fetch(brand_query)
result_as_dict: List[Dict] = [dict(brand) for brand in results]
return web.json_response(result_as_dict)
app = web.Application()
app.on_startup.append(create_database_pool) #D
app.on_cleanup.append(destroy_database_pool)
app.add_routes(routes)
web.run_app(app)
================================================
FILE: chapter_09/listing_9_3.py
================================================
import asyncpg
from aiohttp import web
from aiohttp.web_app import Application
from aiohttp.web_request import Request
from aiohttp.web_response import Response
from asyncpg import Record
from asyncpg.pool import Pool
routes = web.RouteTableDef()
DB_KEY = 'database'
@routes.get('/products/{id}')
async def get_product(request: Request) -> Response:
try:
str_id = request.match_info['id'] #A
product_id = int(str_id)
query = \
"""
SELECT
product_id,
product_name,
brand_id
FROM product
WHERE product_id = $1
"""
connection: Pool = request.app[DB_KEY]
result: Record = await connection.fetchrow(query, product_id) #B
if result is not None: #C
return web.json_response(dict(result))
else:
raise web.HTTPNotFound()
except ValueError:
raise web.HTTPBadRequest()
async def create_database_pool(app: Application):
print('Creating database pool.')
pool: Pool = await asyncpg.create_pool(host='127.0.0.1',
port=5432,
user='postgres',
password='password',
database='products',
min_size=6,
max_size=6)
app[DB_KEY] = pool
async def destroy_database_pool(app: Application):
print('Destroying database pool.')
pool: Pool = app[DB_KEY]
await pool.close()
app = web.Application()
app.on_startup.append(create_database_pool)
app.on_cleanup.append(destroy_database_pool)
app.add_routes(routes)
web.run_app(app)
================================================
FILE: chapter_09/listing_9_4.py
================================================
from aiohttp import web
from aiohttp.web_request import Request
from aiohttp.web_response import Response
from chapter_09.listing_9_2 import create_database_pool, destroy_database_pool
routes = web.RouteTableDef()
DB_KEY = 'database'
@routes.post('/product')
async def create_product(request: Request) -> Response:
PRODUCT_NAME = 'product_name'
BRAND_ID = 'brand_id'
if not request.can_read_body:
raise web.HTTPBadRequest()
body = await request.json()
if PRODUCT_NAME in body and BRAND_ID in body:
db = request.app[DB_KEY]
await db.execute('''INSERT INTO product(product_id,
product_name,
brand_id)
VALUES(DEFAULT, $1, $2)''',
body[PRODUCT_NAME],
int(body[BRAND_ID]))
return web.Response(status=201)
else:
raise web.HTTPBadRequest()
app = web.Application()
app.on_startup.append(create_database_pool)
app.on_cleanup.append(destroy_database_pool)
app.add_routes(routes)
web.run_app(app)
================================================
FILE: chapter_09/listing_9_5.py
================================================
from flask import Flask, jsonify
import psycopg2
app = Flask(__name__)
conn_info = "dbname=products user=postgres password=password host=127.0.0.1"
db = psycopg2.connect(conn_info)
@app.route('/brands')
def brands():
cur = db.cursor()
cur.execute('SELECT brand_id, brand_name FROM brand')
rows = cur.fetchall()
cur.close()
return jsonify([{'brand_id': row[0], 'brand_name': row[1]} for row in rows])
================================================
FILE: chapter_09/listing_9_6.py
================================================
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"WSGI hello!"]
================================================
FILE: chapter_09/listing_9_7.py
================================================
async def application(scope, receive, send):
await send({
'type': 'http.response.start',
'status': 200,
'headers': [[b'content-type', b'text/html']]
})
await send({'type': 'http.response.body', 'body': b'ASGI hello!'})
================================================
FILE: chapter_09/listing_9_8.py
================================================
import asyncpg
from asyncpg import Record
from asyncpg.pool import Pool
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse, Response
from starlette.routing import Route
from typing import List, Dict
async def create_database_pool():
pool: Pool = await asyncpg.create_pool(host='127.0.0.1',
port=5432,
user='postgres',
password='password',
database='products',
min_size=6,
max_size=6)
app.state.DB = pool
async def destroy_database_pool():
pool = app.state.DB
await pool.close()
async def brands(request: Request) -> Response:
connection: Pool = request.app.state.DB
brand_query = 'SELECT brand_id, brand_name FROM brand'
results: List[Record] = await connection.fetch(brand_query)
result_as_dict: List[Dict] = [dict(brand) for brand in results]
return JSONResponse(result_as_dict)
app = Starlette(routes=[Route('/brands', brands)],
on_startup=[create_database_pool],
on_shutdown=[destroy_database_pool])
================================================
FILE: chapter_09/listing_9_9.py
================================================
import asyncio
from starlette.applications import Starlette
from starlette.endpoints import WebSocketEndpoint
from starlette.routing import WebSocketRoute
class UserCounter(WebSocketEndpoint):
encoding = 'text'
sockets = []
async def on_connect(self, websocket): # A
await websocket.accept()
UserCounter.sockets.append(websocket)
await self._send_count()
async def on_disconnect(self, websocket, close_code): # B
UserCounter.sockets.remove(websocket)
await self._send_count()
async def on_receive(self, websocket, data):
pass
async def _send_count(self): # C
if len(UserCounter.sockets) > 0:
count_str = str(len(UserCounter.sockets))
task_to_socket = {asyncio.create_task(websocket.send_text(count_str)): websocket
for websocket
in UserCounter.sockets}
done, pending = await asyncio.wait(task_to_socket)
for task in done:
if task.exception() is not None:
if task_to_socket[task] in UserCounter.sockets:
UserCounter.sockets.remove(task_to_socket[task])
app = Starlette(routes=[WebSocketRoute('/counter', UserCounter)])
================================================
FILE: chapter_10/__init__.py
================================================
================================================
FILE: chapter_10/listing_10_1.py
================================================
import asyncio
import random
from aiohttp import web
from aiohttp.web_request import Request
from aiohttp.web_response import Response
routes = web.RouteTableDef()
@routes.get('/products/{id}/inventory')
async def get_inventory(request: Request) -> Response:
delay: float = random.randint(0, 20) / 10
await asyncio.sleep(delay)
inventory: int = random.randint(0, 100)
return web.json_response({'inventory': inventory})
app = web.Application()
app.add_routes(routes)
web.run_app(app, port=8001)
================================================
FILE: chapter_10/listing_10_10.py
================================================
import asyncio
from chapter_10.listing_10_9 import retry, TooManyRetries
async def main():
async def always_fail():
raise Exception("I've failed!")
async def always_timeout():
await asyncio.sleep(1)
try:
await retry(always_fail,
max_retries=3,
timeout=.1,
retry_interval=.1)
except TooManyRetries:
print('Retried too many times!')
try:
await retry(always_timeout,
max_retries=3,
timeout=.1,
retry_interval=.1)
except TooManyRetries:
print('Retried too many times!')
asyncio.run(main())
================================================
FILE: chapter_10/listing_10_11.py
================================================
import asyncio
from datetime import datetime, timedelta
class CircuitOpenException(Exception):
pass
class CircuitBreaker:
def __init__(self,
callback,
timeout: float,
time_window: float,
max_failures: int,
reset_interval: float):
self.callback = callback
self.timeout = timeout
self.time_window = time_window
self.max_failures = max_failures
self.reset_interval = reset_interval
self.last_request_time = None
self.last_failure_time = None
self.current_failures = 0
async def request(self, *args, **kwargs):
if self.current_failures >= self.max_failures:
if datetime.now() > self.last_request_time + timedelta(seconds=self.reset_interval):
self._reset('Circuit is going from open to closed, resetting!')
return await self._do_request(*args, **kwargs)
else:
print('Circuit is open, failing fast!')
raise CircuitOpenException()
else:
if self.last_failure_time and datetime.now() > self.last_failure_time + timedelta(seconds=self.time_window):
self._reset('Interval since first failure elapsed, resetting!')
print('Circuit is closed, requesting!')
return await self._do_request(*args, **kwargs)
def _reset(self, msg: str):
print(msg)
self.last_failure_time = None
self.current_failures = 0
async def _do_request(self, *args, **kwargs):
try:
print('Making request!')
self.last_request_time = datetime.now()
return await asyncio.wait_for(self.callback(*args, **kwargs), timeout=self.timeout)
except Exception as e:
self.current_failures = self.current_failures + 1
if self.last_failure_time is None:
self.last_failure_time = datetime.now()
raise
================================================
FILE: chapter_10/listing_10_12.py
================================================
import asyncio
from chapter_10.listing_10_11 import CircuitBreaker
async def main():
async def slow_callback():
await asyncio.sleep(2)
cb = CircuitBreaker(slow_callback,
timeout=1.0,
time_window=5,
max_failures=2,
reset_interval=5)
for _ in range(4):
try:
await cb.request()
except Exception as e:
pass
print('Sleeping for 5 seconds so breaker closes...')
await asyncio.sleep(5)
for _ in range(4):
try:
await cb.request()
except Exception as e:
pass
asyncio.run(main())
================================================
FILE: chapter_10/listing_10_2.sql
================================================
CREATE TABLE user_cart(
user_id INT NOT NULL,
product_id INT NOT NULL
);
INSERT INTO user_cart VALUES (1, 1);
INSERT INTO user_cart VALUES (1, 2);
INSERT INTO user_cart VALUES (1, 3);
INSERT INTO user_cart VALUES (2, 1);
INSERT INTO user_cart VALUES (2, 2);
INSERT INTO user_cart VALUES (2, 5);
================================================
FILE: chapter_10/listing_10_3.sql
================================================
CREATE TABLE user_favorite
(
user_id INT NOT NULL,
product_id INT NOT NULL
);
INSERT INTO user_favorite VALUES (1, 1);
INSERT INTO user_favorite VALUES (1, 2);
INSERT INTO user_favorite VALUES (1, 3);
INSERT INTO user_favorite VALUES (3, 1);
INSERT INTO user_favorite VALUES (3, 2);
INSERT INTO user_favorite VALUES (3, 3);
================================================
FILE: chapter_10/listing_10_4.py
================================================
import asyncpg
from aiohttp.web_app import Application
from asyncpg.pool import Pool
DB_KEY = 'database'
async def create_database_pool(app: Application,
host: str,
port: int,
user: str,
database: str,
password: str):
pool: Pool = await asyncpg.create_pool(host=host,
port=port,
user=user,
password=password,
database=database,
min_size=6,
max_size=6)
app[DB_KEY] = pool
async def destroy_database_pool(app: Application):
pool: Pool = app[DB_KEY]
await pool.close()
================================================
FILE: chapter_10/listing_10_5.py
================================================
import functools
from aiohttp import web
from aiohttp.web_request import Request
from aiohttp.web_response import Response
from chapter_10.listing_10_4 import DB_KEY, create_database_pool, destroy_database_pool
routes = web.RouteTableDef()
@routes.get('/users/{id}/favorites')
async def favorites(request: Request) -> Response:
try:
str_id = request.match_info['id']
user_id = int(str_id)
db = request.app[DB_KEY]
favorite_query = 'SELECT product_id from user_favorite where user_id = $1'
result = await db.fetch(favorite_query, user_id)
if result is not None:
return web.json_response([dict(record) for record in result])
else:
raise web.HTTPNotFound()
except ValueError:
raise web.HTTPBadRequest()
app = web.Application()
app.on_startup.append(functools.partial(create_database_pool,
host='127.0.0.1',
port=5432,
user='postgres',
password='password',
database='favorites'))
app.on_cleanup.append(destroy_database_pool)
app.add_routes(routes)
web.run_app(app, port=8002)
================================================
FILE: chapter_10/listing_10_6.py
================================================
import functools
from aiohttp import web
from aiohttp.web_request import Request
from aiohttp.web_response import Response
from chapter_10.listing_10_4 import DB_KEY, create_database_pool, destroy_database_pool
routes = web.RouteTableDef()
@routes.get('/users/{id}/cart')
async def time(request: Request) -> Response:
try:
str_id = request.match_info['id']
user_id = int(str_id)
db = request.app[DB_KEY]
favorite_query = 'SELECT product_id from user_cart where user_id = $1'
result = await db.fetch(favorite_query, user_id)
if result is not None:
return web.json_response([dict(record) for record in result])
else:
raise web.HTTPNotFound()
except ValueError:
raise web.HTTPBadRequest()
app = web.Application()
app.on_startup.append(functools.partial(create_database_pool,
host='127.0.0.1',
port=5432,
user='postgres',
password='password',
database='cart'))
app.on_cleanup.append(destroy_database_pool)
app.add_routes(routes)
web.run_app(app, port=8003)
================================================
FILE: chapter_10/listing_10_7.py
================================================
import functools
from aiohttp import web
from aiohttp.web_request import Request
from aiohttp.web_response import Response
from chapter_10.listing_10_4 import DB_KEY, create_database_pool, destroy_database_pool
routes = web.RouteTableDef()
@routes.get('/products')
async def products(request: Request) -> Response:
db = request.app[DB_KEY]
product_query = 'SELECT product_id, product_name FROM product'
result = await db.fetch(product_query)
return web.json_response([dict(record) for record in result])
app = web.Application()
app.on_startup.append(functools.partial(create_database_pool,
host='127.0.0.1',
port=5432,
user='postgres',
password='password',
database='products'))
app.on_cleanup.append(destroy_database_pool)
app.add_routes(routes)
web.run_app(app, port=8000)
================================================
FILE: chapter_10/listing_10_8.py
================================================
import asyncio
from asyncio import Task
import aiohttp
from aiohttp import web, ClientSession
from aiohttp.web_request import Request
from aiohttp.web_response import Response
import logging
from typing import Dict, Set, Awaitable, Optional, List
routes = web.RouteTableDef()
PRODUCT_BASE = 'http://127.0.0.1:8000'
INVENTORY_BASE = 'http://127.0.0.1:8001'
FAVORITE_BASE = 'http://127.0.0.1:8002'
CART_BASE = 'http://127.0.0.1:8003'
@routes.get('/products/all')
async def all_products(request: Request) -> Response:
async with aiohttp.ClientSession() as session:
products = asyncio.create_task(session.get(f'{PRODUCT_BASE}/products'))
favorites = asyncio.create_task(session.get(f'{FAVORITE_BASE}/users/3/favorites'))
cart = asyncio.create_task(session.get(f'{CART_BASE}/users/3/cart'))
requests = [products, favorites, cart]
done, pending = await asyncio.wait(requests, timeout=1.0)
if products in pending:
[request.cancel() for request in requests]
return web.json_response({'error': 'Could not reach products service.'}, status=504)
elif products in done and products.exception() is not None:
[request.cancel() for request in requests]
logging.exception('Server error reaching product service.', exc_info=products.exception())
return web.json_response({'error': 'Server error reaching products service.'}, status=500)
else:
product_response = await products.result().json()
product_results: List[Dict] = await get_products_with_inventory(session, product_response)
cart_item_count: Optional[int] = await get_response_item_count(cart,
done,
pending,
'Error getting user cart.')
favorite_item_count: Optional[int] = await get_response_item_count(favorites,
done,
pending,
'Error getting user favorites.')
return web.json_response({'cart_items': cart_item_count,
'favorite_items': favorite_item_count,
'products': product_results})
async def get_products_with_inventory(session: ClientSession, product_response) -> List[Dict]:
def get_inventory(session: ClientSession, product_id: str) -> Task:
url = f"{INVENTORY_BASE}/products/{product_id}/inventory"
return asyncio.create_task(session.get(url))
def create_product_record(product_id: int, inventory: Optional[int]) -> Dict:
return {'product_id': product_id, 'inventory': inventory}
inventory_tasks_to_product_id = {
get_inventory(session, product['product_id']): product['product_id'] for product in product_response
}
inventory_done, inventory_pending = await asyncio.wait(inventory_tasks_to_product_id.keys(), timeout=1.0)
product_results = []
for done_task in inventory_done:
if done_task.exception() is None:
product_id = inventory_tasks_to_product_id[done_task]
inventory = await done_task.result().json()
product_results.append(create_product_record(product_id, inventory['inventory']))
else:
product_id = inventory_tasks_to_product_id[done_task]
product_results.append(create_product_record(product_id, None))
logging.exception(f'Error getting inventory for id {product_id}',
exc_info=inventory_tasks_to_product_id[done_task].exception())
for pending_task in inventory_pending:
pending_task.cancel()
product_id = inventory_tasks_to_product_id[pending_task]
product_results.append(create_product_record(product_id, None))
return product_results
async def get_response_item_count(task: Task,
done: Set[Awaitable],
pending: Set[Awaitable],
error_msg: str) -> Optional[int]:
if task in done and task.exception() is None:
return len(await task.result().json())
elif task in pending:
task.cancel()
else:
logging.exception(error_msg, exc_info=task.exception())
return None
app = web.Application()
app.add_routes(routes)
web.run_app(app, port=9000)
================================================
FILE: chapter_10/listing_10_9.py
================================================
import asyncio
import logging
from typing import Callable, Awaitable
class TooManyRetries(Exception):
pass
async def retry(coro: Callable[[], Awaitable],
max_retries: int,
timeout: float,
retry_interval: float):
for retry_num in range(0, max_retries):
try:
return await asyncio.wait_for(coro(), timeout=timeout)
except Exception as e:
logging.exception(f'Exception while waiting (tried {retry_num} times), retrying.', exc_info=e)
await asyncio.sleep(retry_interval)
raise TooManyRetries()
================================================
FILE: chapter_11/__init__.py
================================================
================================================
FILE: chapter_11/listing_11_1.py
================================================
import asyncio
counter: int = 0
async def increment():
global counter
await asyncio.sleep(0.01)
counter = counter + 1
async def main():
global counter
for _ in range(1000):
tasks = [asyncio.create_task(increment()) for _ in range(100)]
await asyncio.gather(*tasks)
print(f'Counter is {counter}')
assert counter == 100
counter = 0
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_10.py
================================================
import asyncio
import functools
from asyncio import Event
def trigger_event(event: Event):
event.set()
async def do_work_on_event(event: Event):
print('Waiting for event...')
await event.wait() #A
print('Performing work!')
await asyncio.sleep(1) #B
print('Finished work!')
event.clear() #C
async def main():
event = asyncio.Event()
asyncio.get_running_loop().call_later(5.0, functools.partial(trigger_event, event)) #D
await asyncio.gather(do_work_on_event(event), do_work_on_event(event))
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_11.py
================================================
import asyncio
from asyncio import StreamReader, StreamWriter
class FileUpload:
def __init__(self,
reader: StreamReader,
writer: StreamWriter):
self._reader = reader
self._writer = writer
self._finished_event = asyncio.Event()
self._buffer = b''
self._upload_task = None
def listen_for_uploads(self):
self._upload_task = asyncio.create_task(self._accept_upload()) #A
async def _accept_upload(self):
while data := await self._reader.read(1024):
self._buffer = self._buffer + data
self._finished_event.set()
self._writer.close()
await self._writer.wait_closed()
async def get_contents(self): #B
await self._finished_event.wait()
return self._buffer
================================================
FILE: chapter_11/listing_11_12.py
================================================
import asyncio
from asyncio import StreamReader, StreamWriter
from chapter_11.listing_11_11 import FileUpload
class FileServer:
def __init__(self, host: str, port: int):
self.host = host
self.port = port
self.upload_event = asyncio.Event()
async def start_server(self):
server = await asyncio.start_server(self._client_connected,
self.host,
self.port)
await server.serve_forever()
async def dump_contents_on_complete(self, upload: FileUpload):
file_contents = await upload.get_contents()
print(file_contents)
def _client_connected(self, reader: StreamReader, writer: StreamWriter):
upload = FileUpload(reader, writer)
upload.listen_for_uploads()
asyncio.create_task(self.dump_contents_on_complete(upload))
async def main():
server = FileServer('127.0.0.1', 9000)
await server.start_server()
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_13.py
================================================
import asyncio
from asyncio import Event
from contextlib import suppress
async def trigger_event_periodically(event: Event):
while True:
print('Triggering event!')
event.set()
await asyncio.sleep(1)
async def do_work_on_event(event: Event):
while True:
print('Waiting for event...')
await event.wait()
event.clear()
print('Performing work!')
await asyncio.sleep(5)
print('Finished work!')
async def main():
event = asyncio.Event()
trigger = asyncio.wait_for(trigger_event_periodically(event), 5.0)
with suppress(asyncio.TimeoutError):
await asyncio.gather(do_work_on_event(event), do_work_on_event(event), trigger)
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_14.py
================================================
import asyncio
from asyncio import Condition
async def do_work(condition: Condition):
while True:
print('Waiting for condition lock...')
async with condition:
print('Acquired lock, releasing and waiting for condition...')
await condition.wait()
print('Condition event fired, re-acquiring lock and doing work...')
await asyncio.sleep(1)
print('Work finished, lock released.')
async def fire_event(condition: Condition):
while True:
await asyncio.sleep(5)
print('About to notify, acquiring condition lock...')
async with condition:
print('Lock acquired, notifying all workers.')
condition.notify_all()
print('Notification finished, releasing lock.')
async def main():
condition = Condition()
asyncio.create_task(fire_event(condition))
await asyncio.gather(do_work(condition), do_work(condition))
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_15.py
================================================
import asyncio
from enum import Enum
class ConnectionState(Enum):
WAIT_INIT = 0
INITIALIZING = 1
INITIALIZED = 2
class Connection:
def __init__(self):
self._state = ConnectionState.WAIT_INIT
self._condition = asyncio.Condition()
async def initialize(self):
await self._change_state(ConnectionState.INITIALIZING)
print('initialize: Initializing connection...')
await asyncio.sleep(3) # simulate connection startup time
print('initialize: Finished initializing connection')
await self._change_state(ConnectionState.INITIALIZED)
async def execute(self, query: str):
async with self._condition:
print('execute: Waiting for connection to initialize')
await self._condition.wait_for(self._is_initialized)
print(f'execute: Running {query}!!!')
await asyncio.sleep(3) # simulate a long query
async def _change_state(self, state: ConnectionState):
async with self._condition:
print(f'change_state: State changing from {self._state} to {state}')
self._state = state
self._condition.notify_all()
def _is_initialized(self):
if self._state is not ConnectionState.INITIALIZED:
print(f'_is_initialized: Connection not finished initializing, state is {self._state}')
return False
print(f'_is_initialized: Connection is initialized!')
return True
async def main():
connection = Connection()
query_one = asyncio.create_task(connection.execute('select * from table'))
query_two = asyncio.create_task(connection.execute('select * from other_table'))
asyncio.create_task(connection.initialize())
await query_one
await query_two
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_2.py
================================================
import asyncio
counter: int = 0
async def increment():
global counter
temp_counter = counter
temp_counter = temp_counter + 1
await asyncio.sleep(0.01)
counter = temp_counter
async def main():
global counter
for _ in range(1000):
tasks = [asyncio.create_task(increment()) for _ in range(100)]
await asyncio.gather(*tasks)
print(f'Counter is {counter}')
assert counter == 100
counter = 0
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_3.py
================================================
import asyncio
class MockSocket:
def __init__(self):
self.socket_closed = False
async def send(self, msg: str):
if self.socket_closed:
raise Exception('Socket is closed!')
print(f'Sending: {msg}')
await asyncio.sleep(1)
print(f'Sent: {msg}')
def close(self):
self.socket_closed = True
user_names_to_sockets = {'John': MockSocket(),
'Terry': MockSocket(),
'Graham': MockSocket(),
'Eric': MockSocket()}
async def user_disconnect(username: str):
print(f'{username} disconnected!')
socket = user_names_to_sockets.pop(username)
socket.close()
async def message_all_users():
print('Creating message tasks')
messages = [socket.send(f'Hello {user}')
for user, socket
in user_names_to_sockets.items()]
await asyncio.gather(*messages)
async def main():
await asyncio.gather(message_all_users(), user_disconnect('Eric'))
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_4.py
================================================
import asyncio
from asyncio import Lock
from util import delay
async def a(lock: Lock):
print('Coroutine a waiting to acquire the lock')
async with lock:
print('Coroutine a is in the critical section')
await delay(2)
print('Coroutine a released the lock')
async def b(lock: Lock):
print('Coroutine b waiting to acquire the lock')
async with lock:
print('Coroutine b is in the critical section')
await delay(2)
print('Coroutine b released the lock')
async def main():
lock = Lock()
await asyncio.gather(a(lock), b(lock))
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_5.py
================================================
import asyncio
from asyncio import Lock
class MockSocket:
def __init__(self):
self.socket_closed = False
async def send(self, msg: str):
if self.socket_closed:
raise Exception('Socket is closed!')
print(f'Sending: {msg}')
await asyncio.sleep(1)
print(f'Sent: {msg}')
def close(self):
self.socket_closed = True
user_names_to_sockets = {'John': MockSocket(),
'Terry': MockSocket(),
'Graham': MockSocket(),
'Eric': MockSocket()}
async def user_disconnect(username: str, user_lock: Lock):
print(f'{username} disconnected!')
async with user_lock: #A
print(f'Removing {username} from dictionary')
socket = user_names_to_sockets.pop(username)
socket.close()
async def message_all_users(user_lock: Lock):
print('Creating message tasks')
async with user_lock: #B
messages = [socket.send(f'Hello {user}')
for user, socket
in user_names_to_sockets.items()]
await asyncio.gather(*messages)
async def main():
user_lock = Lock()
await asyncio.gather(message_all_users(user_lock),
user_disconnect('Eric', user_lock))
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_6.py
================================================
import asyncio
from asyncio import Semaphore
async def operation(semaphore: Semaphore):
print('Waiting to acquire semaphore...')
async with semaphore:
print('Semaphore acquired!')
await asyncio.sleep(2)
print('Semaphore released!')
async def main():
semaphore = Semaphore(2)
await asyncio.gather(*[operation(semaphore) for _ in range(4)])
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_7.py
================================================
import asyncio
from asyncio import Semaphore
from aiohttp import ClientSession
async def get_url(url: str,
session: ClientSession,
semaphore: Semaphore):
print('Waiting to acquire semaphore...')
async with semaphore:
print('Acquired semaphore, requesting...')
response = await session.get(url)
print('Finished requesting')
return response.status
async def main():
semaphore = Semaphore(10)
async with ClientSession() as session:
tasks = [get_url('https://www.example.com', session, semaphore)
for _ in range(1000)]
await asyncio.gather(*tasks)
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_8.py
================================================
import asyncio
from asyncio import Semaphore
async def acquire(semaphore: Semaphore):
print('Waiting to acquire')
async with semaphore:
print('Acquired')
await asyncio.sleep(5)
print('Releasing')
async def release(semaphore: Semaphore):
print('Releasing as a one off!')
semaphore.release()
print('Released as a one off!')
async def main():
semaphore = Semaphore(2)
print("Acquiring twice, releasing three times...")
await asyncio.gather(acquire(semaphore),
acquire(semaphore),
release(semaphore))
print("Acquiring three times...")
await asyncio.gather(acquire(semaphore),
acquire(semaphore),
acquire(semaphore))
asyncio.run(main())
================================================
FILE: chapter_11/listing_11_9.py
================================================
import asyncio
from asyncio import BoundedSemaphore
async def main():
semaphore = BoundedSemaphore(1)
await semaphore.acquire()
semaphore.release()
semaphore.release()
asyncio.run(main())
================================================
FILE: chapter_12/__init__.py
================================================
================================================
FILE: chapter_12/listing_12_1.py
================================================
import asyncio
from asyncio import Queue
from random import randrange
from typing import List
class Product:
def __init__(self, name: str, checkout_time: float):
self.name = name
self.checkout_time = checkout_time
class Customer:
def __init__(self, customer_id: int, products: List[Product]):
self.customer_id = customer_id
self.products = products
async def checkout_customer(queue: Queue, cashier_number: int):
while not queue.empty(): #A
customer: Customer = queue.get_nowait()
print(f'Cashier {cashier_number} '
f'checking out customer '
f'{customer.customer_id}')
for product in customer.products: #B
print(f"Cashier {cashier_number} "
f"checking out customer "
f"{customer.customer_id}'s {product.name}")
await asyncio.sleep(product.checkout_time)
print(f'Cashier {cashier_number} '
f'finished checking out customer '
f'{customer.customer_id}')
queue.task_done()
async def main():
customer_queue = Queue()
all_products = [Product('beer', 2),
Product('bananas', .5),
Product('sausage', .2),
Product('diapers', .2)]
for i in range(10): #C
products = [all_products[randrange(len(all_products))]
for _ in range(randrange(10))]
customer_queue.put_nowait(Customer(i, products))
cashiers = [asyncio.create_task(checkout_customer(customer_queue, i))
for i in range(3)] #D
await asyncio.gather(customer_queue.join(), *cashiers)
asyncio.run(main())
================================================
FILE: chapter_12/listing_12_10.py
================================================
import asyncio
from asyncio import Queue, LifoQueue
from dataclasses import dataclass, field
@dataclass(order=True)
class WorkItem:
priority: int
order: int
data: str = field(compare=False)
async def worker(queue: Queue):
while not queue.empty():
work_item: WorkItem = await queue.get() #A
print(f'Processing work item {work_item}')
queue.task_done()
async def main():
lifo_queue = LifoQueue()
work_items = [WorkItem(3, 1, 'Lowest priority first'),
WorkItem(3, 2, 'Lowest priority second'),
WorkItem(3, 3, 'Lowest priority third'),
WorkItem(2, 4, 'Medium priority'),
WorkItem(1, 5, 'High priority')]
worker_task = asyncio.create_task(worker(lifo_queue))
for work in work_items:
lifo_queue.put_nowait(work) #B
await asyncio.gather(lifo_queue.join(), worker_task)
asyncio.run(main())
================================================
FILE: chapter_12/listing_12_2.py
================================================
import asyncio
from asyncio import Queue
from random import randrange
class Product:
def __init__(self, name: str, checkout_time: float):
self.name = name
self.checkout_time = checkout_time
class Customer:
def __init__(self, customer_id, products):
self.customer_id = customer_id
self.products = products
async def checkout_customer(queue: Queue, cashier_number: int):
while True:
customer: Customer = await queue.get()
print(f'Cashier {cashier_number} '
f'checking out customer '
f'{customer.customer_id}')
for product in customer.products:
print(f"Cashier {cashier_number} "
f"checking out customer "
f"{customer.customer_id}'s {product.name}")
await asyncio.sleep(product.checkout_time)
print(f'Cashier {cashier_number} '
f'finished checking out customer '
f'{customer.customer_id}')
queue.task_done()
def generate_customer(customer_id: int) -> Customer: #A
all_products = [Product('beer', 2),
Product('bananas', .5),
Product('sausage', .2),
Product('diapers', .2)]
products = [all_products[randrange(len(all_products))]
for _ in range(randrange(10))]
return Customer(customer_id, products)
async def customer_generator(queue: Queue): #B
customer_count = 0
while True:
customers = [generate_customer(i)
for i in range(customer_count, customer_count + randrange(5))]
for customer in customers:
print('Waiting to put customer in line...')
await queue.put(customer)
print('Customer put in line!')
customer_count = customer_count + len(customers)
await asyncio.sleep(1)
async def main():
customer_queue = Queue(5)
customer_producer = asyncio.create_task(customer_generator(customer_queue))
cashiers = [asyncio.create_task(checkout_customer(customer_queue, i))
for i in range(3)]
await asyncio.gather(customer_producer, *cashiers)
asyncio.run(main())
================================================
FILE: chapter_12/listing_12_3.py
================================================
import asyncio
from asyncio import Queue, Task
from typing import List
from random import randrange
from aiohttp import web
from aiohttp.web_app import Application
from aiohttp.web_request import Request
from aiohttp.web_response import Response
routes = web.RouteTableDef()
QUEUE_KEY = 'order_queue'
TASKS_KEY = 'order_tasks'
async def process_order_worker(worker_id: int, queue: Queue): #A
while True:
print(f'Worker {worker_id}: Waiting for an order...')
order = await queue.get()
print(f'Worker {worker_id}: Processing order {order}')
await asyncio.sleep(order)
print(f'Worker {worker_id}: Processed order {order}')
queue.task_done()
@routes.post('/order')
async def place_order(request: Request) -> Response:
order_queue = app[QUEUE_KEY]
await order_queue.put(randrange(5)) #B
return Response(body='Order placed!')
async def create_order_queue(app: Application): #C
print('Creating order queue and tasks.')
queue: Queue = asyncio.Queue(10)
app[QUEUE_KEY] = queue
app[TASKS_KEY] = [asyncio.create_task(process_order_worker(i, queue))
for i in range(5)]
async def destroy_queue(app: Application): #D
order_tasks: List[Task] = app[TASKS_KEY]
queue: Queue = app[QUEUE_KEY]
print('Waiting for pending queue workers to finish....')
try:
await asyncio.wait_for(queue.join(), timeout=10)
finally:
print('Finished all pending items, canceling worker tasks...')
[task.cancel() for task in order_tasks]
app = web.Application()
app.on_startup.append(create_order_queue)
app.on_shutdown.append(destroy_queue)
app.add_routes(routes)
web.run_app(app)
================================================
FILE: chapter_12/listing_12_4.py
================================================
import asyncio
import aiohttp
import logging
from asyncio import Queue
from aiohttp import ClientSession
from bs4 import BeautifulSoup
class WorkItem:
def __init__(self, item_depth: int, url: str):
self.item_depth = item_depth
self.url = url
async def worker(worker_id: int, queue: Queue, session: ClientSession, max_depth: int):
print(f'Worker {worker_id}')
while True: #A
work_item: WorkItem = await queue.get()
print(f'Worker {worker_id}: Processing {work_item.url}')
await process_page(work_item, queue, session, max_depth)
print(f'Worker {worker_id}: Finished {work_item.url}')
queue.task_done()
async def process_page(work_item: WorkItem, queue: Queue, session: ClientSession, max_depth: int): #B
try:
response = await asyncio.wait_for(session.get(work_item.url), timeout=3)
if work_item.item_depth == max_depth:
print(f'Max depth reached, '
f'not processing more for {work_item.url}')
else:
body = await response.text()
soup = BeautifulSoup(body, 'html.parser')
links = soup.find_all('a', href=True)
for link in links:
queue.put_nowait(WorkItem(work_item.item_depth + 1,
link['href']))
except Exception as e:
logging.exception(f'Error processing url {work_item.url}')
async def main(): #C
start_url = 'http://example.com'
url_queue = Queue()
url_queue.put_nowait(WorkItem(0, start_url))
async with aiohttp.ClientSession() as session:
workers = [asyncio.create_task(worker(i, url_queue, session, 3))
for i in range(100)]
await url_queue.join()
[w.cancel() for w in workers]
asyncio.run(main())
================================================
FILE: chapter_12/listing_12_5.py
================================================
import asyncio
from asyncio import Queue, PriorityQueue
from typing import Tuple
async def worker(queue: Queue):
while not queue.empty():
work_item: Tuple[int, str] = await queue.get()
print(f'Processing work item {work_item}')
queue.task_done()
async def main():
priority_queue = PriorityQueue()
work_items = [(3, 'Lowest priority'),
(2, 'Medium priority'),
(1, 'High priority')]
worker_task = asyncio.create_task(worker(priority_queue))
for work in work_items:
priority_queue.put_nowait(work)
await asyncio.gather(priority_queue.join(), worker_task)
asyncio.run(main())
================================================
FILE: chapter_12/listing_12_6.py
================================================
import asyncio
from asyncio import Queue, PriorityQueue
from dataclasses import dataclass, field
@dataclass(order=True)
class WorkItem:
priority: int
data: str = field(compare=False)
async def worker(queue: Queue):
while not queue.empty():
work_item: WorkItem = await queue.get()
print(f'Processing work item {work_item}')
queue.task_done()
async def main():
priority_queue = PriorityQueue()
work_items = [WorkItem(3, 'Lowest priority'),
WorkItem(2, 'Medium priority'),
WorkItem(1, 'High priority')]
worker_task = asyncio.create_task(worker(priority_queue))
for work in work_items:
priority_queue.put_nowait(work)
await asyncio.gather(priority_queue.join(), worker_task)
asyncio.run(main())
================================================
FILE: chapter_12/listing_12_7.py
================================================
import asyncio
from asyncio import Queue, Task
from dataclasses import field, dataclass
from enum import IntEnum
from typing import List
from random import randrange
from aiohttp import web
from aiohttp.web_app import Application
from aiohttp.web_request import Request
from aiohttp.web_response import Response
routes = web.RouteTableDef()
QUEUE_KEY = 'order_queue'
TASKS_KEY = 'order_tasks'
class UserType(IntEnum):
POWER_USER = 1
NORMAL_USER = 2
@dataclass(order=True) #A
class Order:
user_type: UserType
order_delay: int = field(compare=False)
async def process_order_worker(worker_id: int, queue: Queue):
while True:
print(f'Worker {worker_id}: Waiting for an order...')
order = await queue.get()
print(f'Worker {worker_id}: Processing order {order}')
await asyncio.sleep(order.order_delay)
print(f'Worker {worker_id}: Processed order {order}')
queue.task_done()
@routes.post('/order')
async def place_order(request: Request) -> Response:
body = await request.json()
user_type = UserType.POWER_USER if body['power_user'] == 'True' else UserType.NORMAL_USER
order_queue = app[QUEUE_KEY]
await order_queue.put(Order(user_type, randrange(5))) # B
return Response(body='Order placed!')
async def create_order_queue(app: Application):
print('Creating order queue and tasks.')
queue: Queue = asyncio.PriorityQueue(10)
app[QUEUE_KEY] = queue
app[TASKS_KEY] = [asyncio.create_task(process_order_worker(i, queue))
for i in range(5)]
async def destroy_queue(app: Application):
order_tasks: List[Task] = app[TASKS_KEY]
queue: Queue = app[QUEUE_KEY]
print('Waiting for pending queue workers to finish....')
try:
await asyncio.wait_for(queue.join(), timeout=10)
finally:
print('Finished all pending items, canceling worker tasks...')
[task.cancel() for task in order_tasks]
app = web.Application()
app.on_startup.append(create_order_queue)
app.on_shutdown.append(destroy_queue)
app.add_routes(routes)
web.run_app(app)
================================================
FILE: chapter_12/listing_12_8.py
================================================
import asyncio
from asyncio import Queue, PriorityQueue
from dataclasses import dataclass, field
@dataclass(order=True)
class WorkItem:
priority: int
data: str = field(compare=False)
async def worker(queue: Queue):
while not queue.empty():
work_item: WorkItem = await queue.get()
print(f'Processing work item {work_item}')
queue.task_done()
async def main():
priority_queue = PriorityQueue()
work_items = [WorkItem(3, 'Lowest priority'),
WorkItem(3, 'Lowest priority second'),
WorkItem(3, 'Lowest priority third'),
WorkItem(2, 'Medium priority'),
WorkItem(1, 'High priority')]
worker_task = asyncio.create_task(worker(priority_queue))
for work in work_items:
priority_queue.put_nowait(work)
await asyncio.gather(priority_queue.join(), worker_task)
asyncio.run(main())
================================================
FILE: chapter_12/listing_12_9.py
================================================
import asyncio
from asyncio import Queue, PriorityQueue
from dataclasses import dataclass, field
@dataclass(order=True)
class WorkItem:
priority: int
order: int
data: str = field(compare=False)
async def worker(queue: Queue):
while not queue.empty():
work_item: WorkItem = await queue.get()
print(f'Processing work item {work_item}')
queue.task_done()
async def main():
priority_queue = PriorityQueue()
work_items = [WorkItem(3, 1, 'Lowest priority'),
WorkItem(3, 2, 'Lowest priority second'),
WorkItem(3, 3, 'Lowest priority third'),
WorkItem(2, 4, 'Medium priority'),
WorkItem(1, 5, 'High priority')]
worker_task = asyncio.create_task(worker(priority_queue))
for work in work_items:
priority_queue.put_nowait(work)
await asyncio.gather(priority_queue.join(), worker_task)
asyncio.run(main())
================================================
FILE: chapter_13/__init__.py
================================================
================================================
FILE: chapter_13/listing_13_1.py
================================================
import asyncio
from asyncio.subprocess import Process
async def main():
process: Process = await asyncio.create_subprocess_exec('ls', '-l')
print(f'Process pid is: {process.pid}')
status_code = await process.wait()
print(f'Status code: {status_code}')
asyncio.run(main())
================================================
FILE: chapter_13/listing_13_10.py
================================================
import asyncio
from asyncio.subprocess import Process
async def main():
program = ['python3', 'listing_13_9.py']
process: Process = await asyncio.create_subprocess_exec(*program,
stdout=asyncio.subprocess.PIPE,
stdin=asyncio.subprocess.PIPE)
stdout, stderr = await process.communicate(b'Zoot')
print(stdout)
print(stderr)
asyncio.run(main())
================================================
FILE: chapter_13/listing_13_11.py
================================================
user_input = ''
while user_input != 'quit':
user_input = input('Enter text to echo: ')
print(user_input)
================================================
FILE: chapter_13/listing_13_12.py
================================================
import asyncio
from asyncio import StreamWriter, StreamReader
from asyncio.subprocess import Process
async def consume_and_send(text_list, stdout: StreamReader, stdin: StreamWriter):
for text in text_list:
line = await stdout.read(2048)
print(line)
stdin.write(text.encode())
await stdin.drain()
async def main():
program = ['python3', 'listing_13_13.py']
process: Process = await asyncio.create_subprocess_exec(*program,
stdout=asyncio.subprocess.PIPE,
stdin=asyncio.subprocess.PIPE)
text_input = ['one\n', 'two\n', 'three\n', 'four\n', 'quit\n']
await asyncio.gather(consume_and_send(text_input, process.stdout, process.stdin), process.wait())
asyncio.run(main())
================================================
FILE: chapter_13/listing_13_13.py
================================================
from random import randrange
import time
user_input = ''
while user_input != 'quit':
user_input = input('Enter text to echo: ')
for i in range(randrange(10)):
time.sleep(.5)
print(user_input)
================================================
FILE: chapter_13/listing_13_14.py
================================================
import asyncio
from asyncio import StreamWriter, StreamReader, Event
from asyncio.subprocess import Process
async def output_consumer(input_ready_event: Event, stdout: StreamReader):
while (data := await stdout.read(1024)) != b'':
print(data)
if data.decode().endswith("Enter text to echo: "):
input_ready_event.set()
async def input_writer(text_data, input_ready_event: Event, stdin: StreamWriter):
for text in text_data:
await input_ready_event.wait()
stdin.write(text.encode())
await stdin.drain()
input_ready_event.clear()
async def main():
program = ['python3', 'listing_13_13.py']
process: Process = await asyncio.create_subprocess_exec(*program,
stdout=asyncio.subprocess.PIPE,
stdin=asyncio.subprocess.PIPE)
input_ready_event = asyncio.Event()
text_input = ['one\n', 'two\n', 'three\n', 'four\n', 'quit\n']
await asyncio.gather(output_consumer(input_ready_event, process.stdout),
input_writer(text_input, input_ready_event, process.stdin),
process.wait())
asyncio.run(main())
================================================
FILE: chapter_13/listing_13_2.py
================================================
import asyncio
from asyncio.subprocess import Process
async def main():
process: Process = await asyncio.create_subprocess_exec('sleep', '3')
print(f'Process pid is: {process.pid}')
try:
status_code = await asyncio.wait_for(process.wait(), timeout=1.0)
print(status_code)
except asyncio.TimeoutError:
print('Timed out waiting to finish, terminating...')
process.terminate()
status_code = await process.wait()
print(status_code)
asyncio.run(main())
================================================
FILE: chapter_13/listing_13_3.py
================================================
import asyncio
from asyncio import StreamReader
from asyncio.subprocess import Process
async def write_output(prefix: str, stdout: StreamReader):
while line := await stdout.readline():
print(f'[{prefix}]: {line.rstrip().decode()}')
async def main():
program = ['ls', '-la']
process: Process = await asyncio.create_subprocess_exec(*program,
stdout=asyncio.subprocess.PIPE)
print(f'Process pid is: {process.pid}')
stdout_task = asyncio.create_task(write_output(' '.join(program), process.stdout))
return_code, _ = await asyncio.gather(process.wait(), stdout_task)
print(f'Process returned: {return_code}')
asyncio.run(main())
================================================
FILE: chapter_13/listing_13_4.py
================================================
import sys
[sys.stdout.buffer.write(b'Hello there!!\n') for _ in range(1000000)]
sys.stdout.flush()
================================================
FILE: chapter_13/listing_13_5.py
================================================
import asyncio
from asyncio.subprocess import Process
async def main():
program = ['python3', 'listing_13_4.py']
process: Process = await asyncio.create_subprocess_exec(*program,
stdout=asyncio.subprocess.PIPE)
print(f'Process pid is: {process.pid}')
return_code = await process.wait()
print(f'Process returned: {return_code}')
asyncio.run(main())
================================================
FILE: chapter_13/listing_13_6.py
================================================
import asyncio
from asyncio.subprocess import Process
async def main():
program = ['python3', 'listing_13_4.py']
process: Process = await asyncio.create_subprocess_exec(*program,
stdout=asyncio.subprocess.PIPE)
print(f'Process pid is: {process.pid}')
stdout, stderr = await process.communicate()
print(stdout)
print(stderr)
print(f'Process returned: {process.returncode}')
asyncio.run(main())
================================================
FILE: chapter_13/listing_13_7.py
================================================
import asyncio
import random
import string
import time
from asyncio.subprocess import Process
async def encrypt(text: str) -> bytes:
program = ['gpg', '-c', '--batch', '--passphrase', '3ncryptm3', '--cipher-algo', 'TWOFISH']
process: Process = await asyncio.create_subprocess_exec(*program,
stdout=asyncio.subprocess.PIPE,
stdin=asyncio.subprocess.PIPE)
stdout, stderr = await process.communicate(text.encode())
return stdout
async def main():
text_list = [''.join(random.choice(string.ascii_letters) for _ in range(1000)) for _ in range(100)]
s = time.time()
tasks = [asyncio.create_task(encrypt(text)) for text in text_list]
encrypted_text = await asyncio.gather(*tasks)
e = time.time()
print(f'Total time: {e - s}')
print(encrypted_text)
asyncio.run(main())
================================================
FILE: chapter_13/listing_13_8.py
================================================
import asyncio
import random
import string
import time
import os
from asyncio import Semaphore
from asyncio.subprocess import Process
async def encrypt(sem: Semaphore, text: str) -> bytes:
program = ['gpg', '-c', '--batch', '--passphrase', '3ncryptm3', '--cipher-algo', 'TWOFISH']
async with sem:
process: Process = await asyncio.create_subprocess_exec(*program,
stdout=asyncio.subprocess.PIPE,
stdin=asyncio.subprocess.PIPE)
stdout, stderr = await process.communicate(text.encode())
return stdout
async def main():
text_list = [''.join(random.choice(string.ascii_letters) for _ in range(1000)) for _ in range(1000)]
semaphore = Semaphore(os.cpu_count())
s = time.time()
tasks = [asyncio.create_task(encrypt(semaphore, text)) for text in text_list]
encrypted_text = await asyncio.gather(*tasks)
e = time.time()
print(f'Total time: {e - s}')
asyncio.run(main())
================================================
FILE: chapter_13/listing_13_9.py
================================================
username = input('Please enter a username: ')
print(f'Your username is {username}')
================================================
FILE: chapter_14/__init__.py
================================================
================================================
FILE: chapter_14/listing_14_1.py
================================================
import asyncio
class TaskRunner:
def __init__(self):
self.loop = asyncio.new_event_loop()
self.tasks = []
def add_task(self, func):
self.tasks.append(func)
async def _run_all(self):
awaitable_tasks = []
for task in self.tasks:
if asyncio.iscoroutinefunction(task):
awaitable_tasks.append(asyncio.create_task(task()))
elif asyncio.iscoroutine(task):
awaitable_tasks.append(asyncio.create_task(task))
else:
self.loop.call_soon(task)
await asyncio.gather(*awaitable_tasks)
def run(self):
self.loop.run_until_complete(self._run_all())
if __name__ == "__main__":
def regular_function():
print('Hello from a regular function!')
async def coroutine_function():
print('Running coroutine, sleeping!')
await asyncio.sleep(1)
print('Finished sleeping!')
runner = TaskRunner()
runner.add_task(coroutine_function)
runner.add_task(coroutine_function())
runner.add_task(regular_function)
runner.run()
================================================
FILE: chapter_14/listing_14_10.py
================================================
import functools
import selectors
import socket
from listing_14_8 import CustomFuture
from selectors import BaseSelector
def accept_connection(future: CustomFuture, connection: socket): #A
print(f'We got a connection from {connection}!')
future.set_result(connection)
async def sock_accept(sel: BaseSelector, sock) -> socket: #B
print('Registering socket to listen for connections')
future = CustomFuture()
sel.register(sock, selectors.EVENT_READ, functools.partial(accept_connection, future))
print('Pausing to listen for connections...')
connection: socket = await future
return connection
async def main(sel: BaseSelector):
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', 8000))
sock.listen()
sock.setblocking(False)
print('Waiting for socket connection!')
connection = await sock_accept(sel, sock) #C
print(f'Got a connection {connection}!')
selector = selectors.DefaultSelector()
coro = main(selector)
while True: #D
try:
state = coro.send(None)
events = selector.select()
for key, mask in events:
print('Processing selector events...')
callback = key.data
callback(key.fileobj)
except StopIteration as si:
print('Application finished!')
break
================================================
FILE: chapter_14/listing_14_11.py
================================================
from chapter_14.listing_14_8 import CustomFuture
class CustomTask(CustomFuture):
def __init__(self, coro, loop):
super(CustomTask, self).__init__()
self._coro = coro
self._loop = loop
self._current_result = None
self._task_state = None
loop.register_task(self) # A
def step(self): # B
try:
if self._task_state is None:
self._task_state = self._coro.send(None)
if isinstance(self._task_state, CustomFuture): # C
self._task_state.add_done_callback(self._future_done)
except StopIteration as si:
self.set_result(si.value)
def _future_done(self, result): # D
self._current_result = result
try:
self._task_state = self._coro.send(self._current_result)
except StopIteration as si:
self.set_result(si.value)
================================================
FILE: chapter_14/listing_14_12.py
================================================
import functools
import selectors
from chapter_14.listing_14_8 import CustomFuture
class EventLoop:
def __init__(self):
self.selector = selectors.DefaultSelector()
self._tasks_to_run = []
self.current_result = None
def _register_socket_to_read(self, sock, callback):
future = CustomFuture()
try:
self.selector.get_key(sock)
except KeyError:
sock.setblocking(False)
self.selector.register(sock, selectors.EVENT_READ, functools.partial(callback, future))
else:
self.selector.modify(sock, selectors.EVENT_READ, functools.partial(callback, future))
return future
def _set_current_result(self, result):
self.current_result = result
async def sock_recv(self, sock):
print('Registering socket to listen for data...')
return await self._register_socket_to_read(sock, self.recieved_data)
async def sock_accept(self, sock):
print('Registering socket to accept connections...')
return await self._register_socket_to_read(sock, self.accept_connection)
def sock_close(self, sock):
self.selector.unregister(sock)
sock.close()
def register_task(self, task):
self._tasks_to_run.append(task)
def recieved_data(self, future, sock):
data = sock.recv(1024)
future.set_result(data)
def accept_connection(self, future, sock):
result = sock.accept()
future.set_result(result)
def run(self, coro):
self.current_result = coro.send(None)
while True:
try:
if isinstance(self.current_result, CustomFuture):
self.current_result.add_done_callback(self._set_current_result)
if self.current_result.result() is not None:
self.current_result = coro.send(self.current_result.result())
else:
self.current_result = coro.send(self.current_result)
except StopIteration as si:
return si.value
for task in self._tasks_to_run:
task.step()
self._tasks_to_run = [task for task in self._tasks_to_run if not task.is_finished()]
events = self.selector.select()
print('Selector has an event, processing...')
for key, mask in events:
callback = key.data
callback(key.fileobj)
================================================
FILE: chapter_14/listing_14_13.py
================================================
import socket
from chapter_14.listing_14_12 import EventLoop
from chapter_14.listing_14_11 import CustomTask
async def read_from_client(conn, loop: EventLoop): #A
print(f'Reading data from client {conn}')
try:
while data := await loop.sock_recv(conn):
print(f'Got {data} from client!')
finally:
loop.sock_close(conn)
async def listen_for_connections(sock, loop: EventLoop): #B
while True:
print('Waiting for connection...')
conn, addr = await loop.sock_accept(sock)
CustomTask(read_from_client(conn, loop), loop)
print(f'I got a new connection from {sock}!')
async def main(loop: EventLoop):
server_socket = socket.socket()
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('localhost', 8000))
server_socket.listen()
server_socket.setblocking(False)
await listen_for_connections(server_socket, loop)
event_loop = EventLoop() #C
event_loop.run(main(event_loop))
================================================
FILE: chapter_14/listing_14_2.py
================================================
import asyncio
from asyncio import StreamReader, StreamWriter
from contextvars import ContextVar
class Server:
user_address = ContextVar('user_address') #A
def __init__(self, host: str, port: int):
self.host = host
self.port = port
async def start_server(self):
server = await asyncio.start_server(self._client_connected, self.host, self.port)
await server.serve_forever()
def _client_connected(self, reader: StreamReader, writer: StreamWriter):
self.user_address.set(writer.get_extra_info('peername')) #B
asyncio.create_task(self.listen_for_messages(reader))
async def listen_for_messages(self, reader: StreamReader):
while data := await reader.readline():
print(f'Got message {data} from {self.user_address.get()}') #C
async def main():
server = Server('127.0.0.1', 9000)
await server.start_server()
asyncio.run(main())
================================================
FILE: chapter_14/listing_14_3.py
================================================
import asyncio
from util import delay
async def create_tasks_no_sleep():
task1 = asyncio.create_task(delay(1))
task2 = asyncio.create_task(delay(2))
print('Gathering tasks:')
await asyncio.gather(task1, task2)
async def create_tasks_sleep():
task1 = asyncio.create_task(delay(1))
await asyncio.sleep(0)
task2 = asyncio.create_task(delay(2))
await asyncio.sleep(0)
print('Gathering tasks:')
await asyncio.gather(task1, task2)
async def main():
print('--- Testing without asyncio.sleep(0) ---')
await create_tasks_no_sleep()
print('--- Testing with asyncio.sleep(0) ---')
await create_tasks_sleep()
asyncio.run(main())
================================================
FILE: chapter_14/listing_14_4.py
================================================
import asyncio
from asyncio import StreamReader, StreamWriter
import uvloop
async def connected(reader: StreamReader, writer: StreamWriter):
line = await reader.readline()
writer.write(line)
await writer.drain()
writer.close()
await writer.wait_closed()
async def main():
server = await asyncio.start_server(connected, port=9000)
await server.serve_forever()
uvloop.install() #A
asyncio.run(main())
================================================
FILE: chapter_14/listing_14_5.py
================================================
import asyncio
@asyncio.coroutine
def coroutine():
print('Sleeping!')
yield from asyncio.sleep(1)
print('Finished!')
asyncio.run(coroutine())
================================================
FILE: chapter_14/listing_14_6.py
================================================
from typing import Generator
def generator(start: int, end: int):
for i in range(start, end):
yield i
one_to_five = generator(1, 5)
five_to_ten = generator(5, 10)
def run_generator_step(gen: Generator[int, None, None]): #A
try:
return gen.send(None)
except StopIteration as si:
return si.value
while True: #B
one_to_five_result = run_generator_step(one_to_five)
five_to_ten_result = run_generator_step(five_to_ten)
print(one_to_five_result)
print(five_to_ten_result)
if one_to_five_result is None and five_to_ten_result is None:
break
================================================
FILE: chapter_14/listing_14_7.py
================================================
async def say_hello():
pri
gitextract_usjcxz68/
├── README.md
├── chapter_01/
│ ├── __init__.py
│ ├── listing_1_1.py
│ ├── listing_1_2.py
│ ├── listing_1_3.py
│ ├── listing_1_4.py
│ ├── listing_1_5.py
│ ├── listing_1_6.py
│ ├── listing_1_7.py
│ └── listing_1_8.py
├── chapter_02/
│ ├── __init__.py
│ ├── listing_2_1.py
│ ├── listing_2_10.py
│ ├── listing_2_11.py
│ ├── listing_2_12.py
│ ├── listing_2_13.py
│ ├── listing_2_14.py
│ ├── listing_2_15.py
│ ├── listing_2_16.py
│ ├── listing_2_17.py
│ ├── listing_2_18.py
│ ├── listing_2_19.py
│ ├── listing_2_2.py
│ ├── listing_2_20.py
│ ├── listing_2_21.py
│ ├── listing_2_22.py
│ ├── listing_2_23.py
│ ├── listing_2_24.py
│ ├── listing_2_3.py
│ ├── listing_2_4.py
│ ├── listing_2_5.py
│ ├── listing_2_6.py
│ ├── listing_2_7.py
│ ├── listing_2_8.py
│ └── listing_2_9.py
├── chapter_03/
│ ├── __init__.py
│ ├── listing_3_1.py
│ ├── listing_3_10.py
│ ├── listing_3_2.py
│ ├── listing_3_3.py
│ ├── listing_3_4.py
│ ├── listing_3_5.py
│ ├── listing_3_6.py
│ ├── listing_3_7.py
│ ├── listing_3_8.py
│ └── listing_3_9.py
├── chapter_04/
│ ├── __init__.py
│ ├── listing_4_1.py
│ ├── listing_4_10.py
│ ├── listing_4_11.py
│ ├── listing_4_12.py
│ ├── listing_4_13.py
│ ├── listing_4_14.py
│ ├── listing_4_15.py
│ ├── listing_4_16.py
│ ├── listing_4_2.py
│ ├── listing_4_3.py
│ ├── listing_4_4.py
│ ├── listing_4_5.py
│ ├── listing_4_6.py
│ ├── listing_4_7.py
│ ├── listing_4_8.py
│ └── listing_4_9.py
├── chapter_05/
│ ├── __init__.py
│ ├── common_words.txt
│ ├── listing_5_1.py
│ ├── listing_5_10.py
│ ├── listing_5_11.py
│ ├── listing_5_12.py
│ ├── listing_5_13.py
│ ├── listing_5_14.py
│ ├── listing_5_15.py
│ ├── listing_5_16.py
│ ├── listing_5_17.py
│ ├── listing_5_2.py
│ ├── listing_5_3.py
│ ├── listing_5_4.py
│ ├── listing_5_5.py
│ ├── listing_5_6.py
│ ├── listing_5_7.py
│ ├── listing_5_8.py
│ └── listing_5_9.py
├── chapter_06/
│ ├── __init__.py
│ ├── listing_6_1.py
│ ├── listing_6_10.py
│ ├── listing_6_11.py
│ ├── listing_6_12.py
│ ├── listing_6_13.py
│ ├── listing_6_14.py
│ ├── listing_6_15.py
│ ├── listing_6_2.py
│ ├── listing_6_3.py
│ ├── listing_6_4.py
│ ├── listing_6_5.py
│ ├── listing_6_6.py
│ ├── listing_6_7.py
│ ├── listing_6_8.py
│ └── listing_6_9.py
├── chapter_07/
│ ├── __init__.py
│ ├── listing_7_1.py
│ ├── listing_7_10.py
│ ├── listing_7_11.py
│ ├── listing_7_12.py
│ ├── listing_7_13.py
│ ├── listing_7_14.py
│ ├── listing_7_15.py
│ ├── listing_7_16.py
│ ├── listing_7_17.py
│ ├── listing_7_18.py
│ ├── listing_7_19.py
│ ├── listing_7_2.py
│ ├── listing_7_3.py
│ ├── listing_7_4.py
│ ├── listing_7_5.py
│ ├── listing_7_6.py
│ ├── listing_7_7.py
│ ├── listing_7_8.py
│ └── listing_7_9.py
├── chapter_08/
│ ├── __init__.py
│ ├── listing_8_1.py
│ ├── listing_8_10.py
│ ├── listing_8_11.py
│ ├── listing_8_12.py
│ ├── listing_8_13.py
│ ├── listing_8_14.py
│ ├── listing_8_2.py
│ ├── listing_8_3.py
│ ├── listing_8_4.py
│ ├── listing_8_5.py
│ ├── listing_8_6.py
│ ├── listing_8_7.py
│ ├── listing_8_8.py
│ └── listing_8_9.py
├── chapter_09/
│ ├── __init__.py
│ ├── async_views/
│ │ ├── async_api/
│ │ │ ├── __init__.py
│ │ │ ├── admin.py
│ │ │ ├── apps.py
│ │ │ ├── migrations/
│ │ │ │ └── __init__.py
│ │ │ ├── models.py
│ │ │ ├── templates/
│ │ │ │ └── async_api/
│ │ │ │ └── requests.html
│ │ │ ├── tests.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── async_views/
│ │ │ ├── __init__.py
│ │ │ ├── asgi.py
│ │ │ ├── settings.py
│ │ │ ├── urls.py
│ │ │ └── wsgi.py
│ │ └── manage.py
│ ├── listing_9_1.py
│ ├── listing_9_10.html
│ ├── listing_9_2.py
│ ├── listing_9_3.py
│ ├── listing_9_4.py
│ ├── listing_9_5.py
│ ├── listing_9_6.py
│ ├── listing_9_7.py
│ ├── listing_9_8.py
│ └── listing_9_9.py
├── chapter_10/
│ ├── __init__.py
│ ├── listing_10_1.py
│ ├── listing_10_10.py
│ ├── listing_10_11.py
│ ├── listing_10_12.py
│ ├── listing_10_2.sql
│ ├── listing_10_3.sql
│ ├── listing_10_4.py
│ ├── listing_10_5.py
│ ├── listing_10_6.py
│ ├── listing_10_7.py
│ ├── listing_10_8.py
│ └── listing_10_9.py
├── chapter_11/
│ ├── __init__.py
│ ├── listing_11_1.py
│ ├── listing_11_10.py
│ ├── listing_11_11.py
│ ├── listing_11_12.py
│ ├── listing_11_13.py
│ ├── listing_11_14.py
│ ├── listing_11_15.py
│ ├── listing_11_2.py
│ ├── listing_11_3.py
│ ├── listing_11_4.py
│ ├── listing_11_5.py
│ ├── listing_11_6.py
│ ├── listing_11_7.py
│ ├── listing_11_8.py
│ └── listing_11_9.py
├── chapter_12/
│ ├── __init__.py
│ ├── listing_12_1.py
│ ├── listing_12_10.py
│ ├── listing_12_2.py
│ ├── listing_12_3.py
│ ├── listing_12_4.py
│ ├── listing_12_5.py
│ ├── listing_12_6.py
│ ├── listing_12_7.py
│ ├── listing_12_8.py
│ └── listing_12_9.py
├── chapter_13/
│ ├── __init__.py
│ ├── listing_13_1.py
│ ├── listing_13_10.py
│ ├── listing_13_11.py
│ ├── listing_13_12.py
│ ├── listing_13_13.py
│ ├── listing_13_14.py
│ ├── listing_13_2.py
│ ├── listing_13_3.py
│ ├── listing_13_4.py
│ ├── listing_13_5.py
│ ├── listing_13_6.py
│ ├── listing_13_7.py
│ ├── listing_13_8.py
│ └── listing_13_9.py
├── chapter_14/
│ ├── __init__.py
│ ├── listing_14_1.py
│ ├── listing_14_10.py
│ ├── listing_14_11.py
│ ├── listing_14_12.py
│ ├── listing_14_13.py
│ ├── listing_14_2.py
│ ├── listing_14_3.py
│ ├── listing_14_4.py
│ ├── listing_14_5.py
│ ├── listing_14_6.py
│ ├── listing_14_7.py
│ ├── listing_14_8.py
│ └── listing_14_9.py
├── requirements.txt
└── util/
├── __init__.py
├── async_timer.py
└── delay_functions.py
SYMBOL INDEX (451 symbols across 185 files)
FILE: chapter_01/listing_1_3.py
function hello_from_thread (line 4) | def hello_from_thread():
FILE: chapter_01/listing_1_4.py
function hello_from_process (line 5) | def hello_from_process():
FILE: chapter_01/listing_1_5.py
function print_fib (line 4) | def print_fib(number: int) -> None:
function fibs_no_threading (line 16) | def fibs_no_threading():
FILE: chapter_01/listing_1_6.py
function print_fib (line 5) | def print_fib(number: int) -> None:
function fibs_with_threads (line 17) | def fibs_with_threads():
FILE: chapter_01/listing_1_7.py
function read_example (line 5) | def read_example() -> None:
FILE: chapter_01/listing_1_8.py
function read_example (line 6) | def read_example() -> None:
FILE: chapter_02/listing_2_1.py
function my_coroutine (line 1) | async def my_coroutine() -> None:
FILE: chapter_02/listing_2_10.py
function hello_every_second (line 5) | async def hello_every_second():
function main (line 11) | async def main():
FILE: chapter_02/listing_2_11.py
function main (line 6) | async def main():
FILE: chapter_02/listing_2_12.py
function main (line 5) | async def main():
FILE: chapter_02/listing_2_13.py
function main (line 5) | async def main():
FILE: chapter_02/listing_2_15.py
function make_request (line 5) | def make_request() -> Future:
function set_future_value (line 11) | async def set_future_value(future) -> None:
function main (line 16) | async def main() -> None:
FILE: chapter_02/listing_2_16.py
function async_timed (line 6) | def async_timed():
FILE: chapter_02/listing_2_17.py
function delay (line 6) | async def delay(delay_seconds: int) -> int:
function main (line 14) | async def main():
FILE: chapter_02/listing_2_18.py
function cpu_bound_work (line 6) | async def cpu_bound_work() -> int:
function main (line 14) | async def main():
FILE: chapter_02/listing_2_19.py
function cpu_bound_work (line 6) | async def cpu_bound_work() -> int:
function main (line 14) | async def main():
FILE: chapter_02/listing_2_2.py
function coroutine_add_one (line 1) | async def coroutine_add_one(number: int) -> int:
function add_one (line 5) | def add_one(number: int) -> int:
FILE: chapter_02/listing_2_20.py
function get_example_status (line 7) | async def get_example_status() -> int:
function main (line 12) | async def main():
FILE: chapter_02/listing_2_21.py
function main (line 4) | async def main():
FILE: chapter_02/listing_2_22.py
function call_later (line 5) | def call_later():
function main (line 9) | async def main():
FILE: chapter_02/listing_2_23.py
function cpu_bound_work (line 6) | async def cpu_bound_work() -> int:
function main (line 13) | async def main() -> None:
FILE: chapter_02/listing_2_24.py
function main (line 4) | async def main():
FILE: chapter_02/listing_2_3.py
function coroutine_add_one (line 4) | async def coroutine_add_one(number: int) -> int:
FILE: chapter_02/listing_2_4.py
function add_one (line 4) | async def add_one(number: int) -> int:
function main (line 8) | async def main() -> None:
FILE: chapter_02/listing_2_5.py
function hello_world_message (line 4) | async def hello_world_message() -> str:
function main (line 9) | async def main() -> None:
FILE: chapter_02/listing_2_6.py
function delay (line 4) | async def delay(delay_seconds: int) -> int:
FILE: chapter_02/listing_2_7.py
function add_one (line 5) | async def add_one(number: int) -> int:
function hello_world_message (line 9) | async def hello_world_message() -> str:
function main (line 14) | async def main() -> None:
FILE: chapter_02/listing_2_8.py
function main (line 5) | async def main():
FILE: chapter_02/listing_2_9.py
function main (line 5) | async def main():
FILE: chapter_03/listing_3_10.py
function echo (line 9) | async def echo(connection: socket,
function connection_listener (line 25) | async def connection_listener(server_socket, loop):
class GracefulExit (line 34) | class GracefulExit(SystemExit):
function shutdown (line 38) | def shutdown():
function close_echo_tasks (line 42) | async def close_echo_tasks(echo_tasks: List[asyncio.Task]):
function main (line 52) | async def main():
FILE: chapter_03/listing_3_8.py
function echo (line 6) | async def echo(connection: socket,
function listen_for_connection (line 12) | async def listen_for_connection(server_socket: socket,
function main (line 21) | async def main():
FILE: chapter_03/listing_3_9.py
function cancel_tasks (line 8) | def cancel_tasks():
function main (line 15) | async def main():
FILE: chapter_04/__init__.py
function fetch_status (line 7) | async def fetch_status(session: ClientSession,
FILE: chapter_04/listing_4_1.py
class ConnectedSocket (line 7) | class ConnectedSocket:
method __init__ (line 9) | def __init__(self, server_socket):
method __aenter__ (line 13) | async def __aenter__(self): #A
method __aexit__ (line 21) | async def __aexit__(self,
function main (line 30) | async def main():
FILE: chapter_04/listing_4_10.py
function main (line 8) | async def main():
FILE: chapter_04/listing_4_11.py
function main (line 9) | async def main():
FILE: chapter_04/listing_4_12.py
function main (line 9) | async def main():
FILE: chapter_04/listing_4_13.py
function main (line 8) | async def main():
FILE: chapter_04/listing_4_14.py
function main (line 8) | async def main():
FILE: chapter_04/listing_4_15.py
function main (line 8) | async def main():
FILE: chapter_04/listing_4_16.py
function main (line 6) | async def main():
FILE: chapter_04/listing_4_2.py
function fetch_status (line 8) | async def fetch_status(session: ClientSession, url: str) -> int:
function main (line 14) | async def main():
FILE: chapter_04/listing_4_3.py
function fetch_status (line 6) | async def fetch_status(session: ClientSession,
function main (line 13) | async def main():
FILE: chapter_04/listing_4_4.py
function main (line 6) | async def main() -> None:
FILE: chapter_04/listing_4_5.py
function main (line 6) | async def main() -> None:
FILE: chapter_04/listing_4_6.py
function main (line 8) | async def main():
FILE: chapter_04/listing_4_7.py
function main (line 5) | async def main():
FILE: chapter_04/listing_4_8.py
function main (line 8) | async def main():
FILE: chapter_04/listing_4_9.py
function main (line 8) | async def main():
FILE: chapter_05/listing_5_1.py
function main (line 5) | async def main():
FILE: chapter_05/listing_5_10.py
function main (line 6) | async def main():
FILE: chapter_05/listing_5_11.py
function main (line 6) | async def main():
FILE: chapter_05/listing_5_12.py
function main (line 6) | async def main():
FILE: chapter_05/listing_5_13.py
function positive_integers (line 1) | def positive_integers(until: int):
FILE: chapter_05/listing_5_14.py
function positive_integers_async (line 5) | async def positive_integers_async(until: int):
function main (line 12) | async def main():
FILE: chapter_05/listing_5_15.py
function main (line 5) | async def main():
FILE: chapter_05/listing_5_16.py
function main (line 5) | async def main():
FILE: chapter_05/listing_5_17.py
function take (line 5) | async def take(generator, to_take: int):
function main (line 14) | async def main():
FILE: chapter_05/listing_5_3.py
function main (line 6) | async def main():
FILE: chapter_05/listing_5_4.py
function main (line 7) | async def main():
FILE: chapter_05/listing_5_5.py
function load_common_words (line 7) | def load_common_words() -> List[str]:
function generate_brand_names (line 12) | def generate_brand_names(words: List[str]) -> List[Tuple[Union[str, ]]]:
function insert_brands (line 16) | async def insert_brands(common_words, connection) -> int:
function main (line 22) | async def main():
FILE: chapter_05/listing_5_6.py
function gen_products (line 8) | def gen_products(common_words: List[str],
function gen_skus (line 20) | def gen_skus(product_id_start: int,
function main (line 32) | async def main():
FILE: chapter_05/listing_5_7.py
function query_product (line 20) | async def query_product(pool):
function main (line 25) | async def main():
FILE: chapter_05/listing_5_8.py
function query_product (line 21) | async def query_product(pool):
function query_products_synchronously (line 26) | async def query_products_synchronously(pool, queries):
function query_products_concurrently (line 31) | async def query_products_concurrently(pool, queries):
function main (line 36) | async def main():
FILE: chapter_05/listing_5_9.py
function main (line 5) | async def main():
FILE: chapter_06/listing_6_1.py
function count (line 5) | def count(count_to: int) -> int:
FILE: chapter_06/listing_6_10.py
function increment_value (line 4) | def increment_value(shared_int: Value):
function increment_array (line 8) | def increment_array(shared_array: Array):
FILE: chapter_06/listing_6_11.py
function increment_value (line 4) | def increment_value(shared_int: Value):
FILE: chapter_06/listing_6_12.py
function increment_value (line 4) | def increment_value(shared_int: Value):
FILE: chapter_06/listing_6_13.py
function init (line 8) | def init(counter: Value):
function increment (line 13) | def increment():
function main (line 18) | async def main():
FILE: chapter_06/listing_6_14.py
function init (line 12) | def init(progress: Value):
function map_frequencies (line 17) | def map_frequencies(chunk: List[str]) -> Dict[str, int]:
function progress_reporter (line 32) | async def progress_reporter(total_partitions: int):
function main (line 38) | async def main(partiton_size: int):
FILE: chapter_06/listing_6_15.py
function query_product (line 24) | async def query_product(pool):
function query_products_concurrently (line 30) | async def query_products_concurrently(pool, queries):
function run_in_new_loop (line 35) | def run_in_new_loop(num_queries: int) -> List[Dict]:
function main (line 51) | async def main():
FILE: chapter_06/listing_6_2.py
function say_hello (line 4) | def say_hello(name: str) -> str:
FILE: chapter_06/listing_6_3.py
function say_hello (line 4) | def say_hello(name: str) -> str:
FILE: chapter_06/listing_6_4.py
function count (line 5) | def count(count_to: int) -> int:
FILE: chapter_06/listing_6_5.py
function countdown (line 8) | def countdown(count_from: int) -> int:
function main (line 15) | async def main():
FILE: chapter_06/listing_6_6.py
function map_frequency (line 5) | def map_frequency(text: str) -> Dict[str, int]:
function merge_dictionaries (line 16) | def merge_dictionaries(first: Dict[str, int],
FILE: chapter_06/listing_6_8.py
function partition (line 8) | def partition(data: List,
function map_frequencies (line 14) | def map_frequencies(chunk: List[str]) -> Dict[str, int]:
function merge_dictionaries (line 25) | def merge_dictionaries(first: Dict[str, int],
function main (line 36) | async def main(partition_size: int):
FILE: chapter_06/listing_6_9.py
function reduce (line 9) | async def reduce(loop, pool, counters, chunk_size) -> Dict[str, int]:
function main (line 22) | async def main(partition_size: int):
FILE: chapter_07/listing_7_1.py
function echo (line 5) | def echo(client: socket):
FILE: chapter_07/listing_7_10.py
class IntListThreadsafe (line 5) | class IntListThreadsafe:
method __init__ (line 7) | def __init__(self, wrapped_list: List[int]):
method indices_of (line 11) | def indices_of(self, to_find: int) -> List[int]:
method find_and_replace (line 16) | def find_and_replace(self,
FILE: chapter_07/listing_7_11.py
function a (line 8) | def a():
function b (line 16) | def b():
FILE: chapter_07/listing_7_12.py
function say_hello (line 9) | def say_hello():
FILE: chapter_07/listing_7_13.py
class StressTest (line 8) | class StressTest:
method __init__ (line 10) | def __init__(self,
method start (line 23) | def start(self):
method cancel (line 27) | def cancel(self):
method _get_url (line 31) | async def _get_url(self, session: ClientSession, url: str):
method _make_requests (line 41) | async def _make_requests(self):
FILE: chapter_07/listing_7_14.py
class LoadTester (line 10) | class LoadTester(Tk):
method __init__ (line 12) | def __init__(self, loop, *args, **kwargs): # A
method _update_bar (line 42) | def _update_bar(self, pct: int): # C
method _queue_update (line 50) | def _queue_update(self, completed_requests: int, total_requests: int):...
method _poll_queue (line 53) | def _poll_queue(self): # E
method _start (line 61) | def _start(self): # F
FILE: chapter_07/listing_7_15.py
class ThreadedEventLoop (line 7) | class ThreadedEventLoop(Thread): #A
method __init__ (line 8) | def __init__(self, loop: AbstractEventLoop):
method run (line 13) | def run(self):
FILE: chapter_07/listing_7_16.py
function random_password (line 8) | def random_password(length: int) -> bytes:
function hash (line 16) | def hash(password: bytes) -> str:
FILE: chapter_07/listing_7_17.py
function random_password (line 11) | def random_password(length: int) -> bytes:
function hash (line 19) | def hash(password: bytes) -> str:
function main (line 25) | async def main():
FILE: chapter_07/listing_7_19.py
function mean_for_row (line 8) | def mean_for_row(arr, row):
function main (line 20) | async def main():
FILE: chapter_07/listing_7_2.py
class ClientEchoThread (line 5) | class ClientEchoThread(Thread):
method __init__ (line 7) | def __init__(self, client):
method run (line 11) | def run(self):
method close (line 22) | def close(self):
FILE: chapter_07/listing_7_3.py
function get_status_code (line 4) | def get_status_code(url: str) -> int:
FILE: chapter_07/listing_7_4.py
function get_status_code (line 6) | def get_status_code(url: str) -> int:
FILE: chapter_07/listing_7_5.py
function get_status_code (line 8) | def get_status_code(url: str) -> int:
function main (line 14) | async def main():
FILE: chapter_07/listing_7_6.py
function get_status_code (line 7) | def get_status_code(url: str) -> int:
function main (line 13) | async def main():
FILE: chapter_07/listing_7_7.py
function get_status_code (line 6) | def get_status_code(url: str) -> int:
function main (line 12) | async def main():
FILE: chapter_07/listing_7_8.py
function get_status_code (line 12) | def get_status_code(url: str) -> int:
function reporter (line 20) | async def reporter(request_count: int):
function main (line 27) | async def main():
FILE: chapter_07/listing_7_9.py
function sum_list (line 7) | def sum_list(int_list: List[int]) -> int:
FILE: chapter_08/listing_8_1.py
class HTTPGetClientProtocol (line 6) | class HTTPGetClientProtocol(asyncio.Protocol):
method __init__ (line 8) | def __init__(self, host: str, loop: AbstractEventLoop):
method get_response (line 14) | async def get_response(self): # A
method _get_request_bytes (line 17) | def _get_request_bytes(self) -> bytes: # B
method connection_made (line 23) | def connection_made(self, transport: Transport):
method data_received (line 28) | def data_received(self, data):
method eof_received (line 32) | def eof_received(self) -> Optional[bool]:
method connection_lost (line 36) | def connection_lost(self, exc: Optional[Exception]) -> None: # F
FILE: chapter_08/listing_8_10.py
function sleep (line 11) | async def sleep(delay: int, message_store: MessageStore):
function main (line 17) | async def main():
FILE: chapter_08/listing_8_11.py
function run_query (line 13) | async def run_query(query: str, pool: Pool, message_store: MessageStore):
function main (line 22) | async def main():
FILE: chapter_08/listing_8_12.py
class ServerState (line 6) | class ServerState:
method __init__ (line 8) | def __init__(self):
method add_client (line 11) | async def add_client(self, reader: StreamReader, writer: StreamWriter)...
method _on_connect (line 16) | async def _on_connect(self, writer: StreamWriter): #B
method _echo (line 21) | async def _echo(self, reader: StreamReader, writer: StreamWriter): #C
method _notify_all (line 32) | async def _notify_all(self, message: str): #D
function main (line 42) | async def main():
FILE: chapter_08/listing_8_13.py
class ChatServer (line 6) | class ChatServer:
method __init__ (line 8) | def __init__(self):
method start_chat_server (line 11) | async def start_chat_server(self, host: str, port: int):
method client_connected (line 17) | async def client_connected(self, reader: StreamReader, writer: StreamW...
method _add_user (line 30) | def _add_user(self, username: str, reader: StreamReader, writer: Strea...
method _on_connect (line 34) | async def _on_connect(self, username: str, writer: StreamWriter): #C
method _remove_user (line 39) | async def _remove_user(self, username: str):
method _listen_for_messages (line 48) | async def _listen_for_messages(self,
method _notify_all (line 59) | async def _notify_all(self, message: str): #E
function main (line 72) | async def main():
FILE: chapter_08/listing_8_14.py
function send_message (line 13) | async def send_message(message: str, writer: StreamWriter):
function listen_for_messages (line 18) | async def listen_for_messages(reader: StreamReader,
function read_and_send (line 25) | async def read_and_send(stdin_reader: StreamReader,
function main (line 32) | async def main():
FILE: chapter_08/listing_8_2.py
function make_request (line 6) | async def make_request(host: str, port: int, loop: AbstractEventLoop) ->...
function main (line 15) | async def main():
FILE: chapter_08/listing_8_3.py
function read_until_empty (line 6) | async def read_until_empty(stream_reader: StreamReader) -> AsyncGenerato...
function main (line 11) | async def main():
FILE: chapter_08/listing_8_4.py
function main (line 5) | async def main():
FILE: chapter_08/listing_8_5.py
function create_stdin_reader (line 6) | async def create_stdin_reader() -> StreamReader:
FILE: chapter_08/listing_8_6.py
function main (line 6) | async def main():
FILE: chapter_08/listing_8_7.py
function save_cursor_position (line 5) | def save_cursor_position():
function restore_cursor_position (line 9) | def restore_cursor_position():
function move_to_top_of_screen (line 13) | def move_to_top_of_screen():
function delete_line (line 17) | def delete_line():
function clear_line (line 21) | def clear_line():
function move_back_one_char (line 25) | def move_back_one_char():
function move_to_bottom_of_screen (line 29) | def move_to_bottom_of_screen() -> int:
FILE: chapter_08/listing_8_8.py
function read_line (line 7) | async def read_line(stdin_reader: StreamReader) -> str:
FILE: chapter_08/listing_8_9.py
class MessageStore (line 5) | class MessageStore:
method __init__ (line 6) | def __init__(self, callback: Callable[[Deque], Awaitable[None]], max_s...
method append (line 10) | async def append(self, item):
FILE: chapter_09/async_views/async_api/apps.py
class AsyncApiConfig (line 4) | class AsyncApiConfig(AppConfig):
FILE: chapter_09/async_views/async_api/models.py
class Url (line 4) | class Url(models.Model):
FILE: chapter_09/async_views/async_api/views.py
function get_url_details (line 8) | async def get_url_details(session: ClientSession, url: str):
function make_requests (line 18) | async def make_requests(url: str, request_num: int):
function requests_view (line 27) | async def requests_view(request):
function sleep (line 39) | def sleep(seconds: int):
function sync_to_async_view (line 44) | async def sync_to_async_view(request):
function requests_view_sync (line 56) | def requests_view_sync(request):
FILE: chapter_09/async_views/manage.py
function main (line 7) | def main():
FILE: chapter_09/listing_9_1.py
function time (line 10) | async def time(request: Request) -> Response:
FILE: chapter_09/listing_9_2.py
function create_database_pool (line 14) | async def create_database_pool(app: Application): #A
function destroy_database_pool (line 26) | async def destroy_database_pool(app: Application): #B
function brands (line 33) | async def brands(request: Request) -> Response: #C
FILE: chapter_09/listing_9_3.py
function get_product (line 14) | async def get_product(request: Request) -> Response:
function create_database_pool (line 40) | async def create_database_pool(app: Application):
function destroy_database_pool (line 52) | async def destroy_database_pool(app: Application):
FILE: chapter_09/listing_9_4.py
function create_product (line 11) | async def create_product(request: Request) -> Response:
FILE: chapter_09/listing_9_5.py
function brands (line 11) | def brands():
FILE: chapter_09/listing_9_6.py
function application (line 1) | def application(env, start_response):
FILE: chapter_09/listing_9_7.py
function application (line 1) | async def application(scope, receive, send):
FILE: chapter_09/listing_9_8.py
function create_database_pool (line 11) | async def create_database_pool():
function destroy_database_pool (line 22) | async def destroy_database_pool():
function brands (line 27) | async def brands(request: Request) -> Response:
FILE: chapter_09/listing_9_9.py
class UserCounter (line 7) | class UserCounter(WebSocketEndpoint):
method on_connect (line 11) | async def on_connect(self, websocket): # A
method on_disconnect (line 16) | async def on_disconnect(self, websocket, close_code): # B
method on_receive (line 20) | async def on_receive(self, websocket, data):
method _send_count (line 23) | async def _send_count(self): # C
FILE: chapter_10/listing_10_1.py
function get_inventory (line 11) | async def get_inventory(request: Request) -> Response:
FILE: chapter_10/listing_10_10.py
function main (line 5) | async def main():
FILE: chapter_10/listing_10_11.py
class CircuitOpenException (line 5) | class CircuitOpenException(Exception):
class CircuitBreaker (line 9) | class CircuitBreaker:
method __init__ (line 11) | def __init__(self,
method request (line 26) | async def request(self, *args, **kwargs):
method _reset (line 40) | def _reset(self, msg: str):
method _do_request (line 45) | async def _do_request(self, *args, **kwargs):
FILE: chapter_10/listing_10_12.py
function main (line 5) | async def main():
FILE: chapter_10/listing_10_2.sql
type user_cart (line 1) | CREATE TABLE user_cart(
FILE: chapter_10/listing_10_3.sql
type user_favorite (line 1) | CREATE TABLE user_favorite
FILE: chapter_10/listing_10_4.py
function create_database_pool (line 8) | async def create_database_pool(app: Application,
function destroy_database_pool (line 24) | async def destroy_database_pool(app: Application):
FILE: chapter_10/listing_10_5.py
function favorites (line 11) | async def favorites(request: Request) -> Response:
FILE: chapter_10/listing_10_6.py
function time (line 11) | async def time(request: Request) -> Response:
FILE: chapter_10/listing_10_7.py
function products (line 11) | async def products(request: Request) -> Response:
FILE: chapter_10/listing_10_8.py
function all_products (line 19) | async def all_products(request: Request) -> Response:
function get_products_with_inventory (line 53) | async def get_products_with_inventory(session: ClientSession, product_re...
function get_response_item_count (line 88) | async def get_response_item_count(task: Task,
FILE: chapter_10/listing_10_9.py
class TooManyRetries (line 6) | class TooManyRetries(Exception):
function retry (line 10) | async def retry(coro: Callable[[], Awaitable],
FILE: chapter_11/listing_11_1.py
function increment (line 6) | async def increment():
function main (line 12) | async def main():
FILE: chapter_11/listing_11_10.py
function trigger_event (line 6) | def trigger_event(event: Event):
function do_work_on_event (line 10) | async def do_work_on_event(event: Event):
function main (line 19) | async def main():
FILE: chapter_11/listing_11_11.py
class FileUpload (line 5) | class FileUpload:
method __init__ (line 6) | def __init__(self,
method listen_for_uploads (line 15) | def listen_for_uploads(self):
method _accept_upload (line 18) | async def _accept_upload(self):
method get_contents (line 25) | async def get_contents(self): #B
FILE: chapter_11/listing_11_12.py
class FileServer (line 6) | class FileServer:
method __init__ (line 8) | def __init__(self, host: str, port: int):
method start_server (line 13) | async def start_server(self):
method dump_contents_on_complete (line 19) | async def dump_contents_on_complete(self, upload: FileUpload):
method _client_connected (line 23) | def _client_connected(self, reader: StreamReader, writer: StreamWriter):
function main (line 29) | async def main():
FILE: chapter_11/listing_11_13.py
function trigger_event_periodically (line 6) | async def trigger_event_periodically(event: Event):
function do_work_on_event (line 13) | async def do_work_on_event(event: Event):
function main (line 23) | async def main():
FILE: chapter_11/listing_11_14.py
function do_work (line 5) | async def do_work(condition: Condition):
function fire_event (line 16) | async def fire_event(condition: Condition):
function main (line 26) | async def main():
FILE: chapter_11/listing_11_15.py
class ConnectionState (line 5) | class ConnectionState(Enum):
class Connection (line 11) | class Connection:
method __init__ (line 13) | def __init__(self):
method initialize (line 17) | async def initialize(self):
method execute (line 24) | async def execute(self, query: str):
method _change_state (line 31) | async def _change_state(self, state: ConnectionState):
method _is_initialized (line 37) | def _is_initialized(self):
function main (line 45) | async def main():
FILE: chapter_11/listing_11_2.py
function increment (line 6) | async def increment():
function main (line 14) | async def main():
FILE: chapter_11/listing_11_3.py
class MockSocket (line 4) | class MockSocket:
method __init__ (line 5) | def __init__(self):
method send (line 8) | async def send(self, msg: str):
method close (line 15) | def close(self):
function user_disconnect (line 25) | async def user_disconnect(username: str):
function message_all_users (line 31) | async def message_all_users():
function main (line 39) | async def main():
FILE: chapter_11/listing_11_4.py
function a (line 6) | async def a(lock: Lock):
function b (line 14) | async def b(lock: Lock):
function main (line 22) | async def main():
FILE: chapter_11/listing_11_5.py
class MockSocket (line 5) | class MockSocket:
method __init__ (line 6) | def __init__(self):
method send (line 9) | async def send(self, msg: str):
method close (line 16) | def close(self):
function user_disconnect (line 26) | async def user_disconnect(username: str, user_lock: Lock):
function message_all_users (line 34) | async def message_all_users(user_lock: Lock):
function main (line 43) | async def main():
FILE: chapter_11/listing_11_6.py
function operation (line 5) | async def operation(semaphore: Semaphore):
function main (line 13) | async def main():
FILE: chapter_11/listing_11_7.py
function get_url (line 6) | async def get_url(url: str,
function main (line 17) | async def main():
FILE: chapter_11/listing_11_8.py
function acquire (line 5) | async def acquire(semaphore: Semaphore):
function release (line 13) | async def release(semaphore: Semaphore):
function main (line 19) | async def main():
FILE: chapter_11/listing_11_9.py
function main (line 5) | async def main():
FILE: chapter_12/listing_12_1.py
class Product (line 7) | class Product:
method __init__ (line 8) | def __init__(self, name: str, checkout_time: float):
class Customer (line 13) | class Customer:
method __init__ (line 14) | def __init__(self, customer_id: int, products: List[Product]):
function checkout_customer (line 19) | async def checkout_customer(queue: Queue, cashier_number: int):
function main (line 36) | async def main():
FILE: chapter_12/listing_12_10.py
class WorkItem (line 7) | class WorkItem:
function worker (line 13) | async def worker(queue: Queue):
function main (line 20) | async def main():
FILE: chapter_12/listing_12_2.py
class Product (line 6) | class Product:
method __init__ (line 7) | def __init__(self, name: str, checkout_time: float):
class Customer (line 12) | class Customer:
method __init__ (line 13) | def __init__(self, customer_id, products):
function checkout_customer (line 18) | async def checkout_customer(queue: Queue, cashier_number: int):
function generate_customer (line 35) | def generate_customer(customer_id: int) -> Customer: #A
function customer_generator (line 45) | async def customer_generator(queue: Queue): #B
function main (line 59) | async def main():
FILE: chapter_12/listing_12_3.py
function process_order_worker (line 16) | async def process_order_worker(worker_id: int, queue: Queue): #A
function place_order (line 27) | async def place_order(request: Request) -> Response:
function create_order_queue (line 33) | async def create_order_queue(app: Application): #C
function destroy_queue (line 41) | async def destroy_queue(app: Application): #D
FILE: chapter_12/listing_12_4.py
class WorkItem (line 9) | class WorkItem:
method __init__ (line 10) | def __init__(self, item_depth: int, url: str):
function worker (line 15) | async def worker(worker_id: int, queue: Queue, session: ClientSession, m...
function process_page (line 25) | async def process_page(work_item: WorkItem, queue: Queue, session: Clien...
function main (line 42) | async def main(): #C
FILE: chapter_12/listing_12_5.py
function worker (line 6) | async def worker(queue: Queue):
function main (line 13) | async def main():
FILE: chapter_12/listing_12_6.py
class WorkItem (line 7) | class WorkItem:
function worker (line 12) | async def worker(queue: Queue):
function main (line 19) | async def main():
FILE: chapter_12/listing_12_7.py
class UserType (line 18) | class UserType(IntEnum):
class Order (line 24) | class Order:
function process_order_worker (line 29) | async def process_order_worker(worker_id: int, queue: Queue):
function place_order (line 40) | async def place_order(request: Request) -> Response:
function create_order_queue (line 48) | async def create_order_queue(app: Application):
function destroy_queue (line 56) | async def destroy_queue(app: Application):
FILE: chapter_12/listing_12_8.py
class WorkItem (line 7) | class WorkItem:
function worker (line 12) | async def worker(queue: Queue):
function main (line 19) | async def main():
FILE: chapter_12/listing_12_9.py
class WorkItem (line 7) | class WorkItem:
function worker (line 13) | async def worker(queue: Queue):
function main (line 20) | async def main():
FILE: chapter_13/listing_13_1.py
function main (line 5) | async def main():
FILE: chapter_13/listing_13_10.py
function main (line 5) | async def main():
FILE: chapter_13/listing_13_12.py
function consume_and_send (line 6) | async def consume_and_send(text_list, stdout: StreamReader, stdin: Strea...
function main (line 14) | async def main():
FILE: chapter_13/listing_13_14.py
function output_consumer (line 6) | async def output_consumer(input_ready_event: Event, stdout: StreamReader):
function input_writer (line 13) | async def input_writer(text_data, input_ready_event: Event, stdin: Strea...
function main (line 21) | async def main():
FILE: chapter_13/listing_13_2.py
function main (line 5) | async def main():
FILE: chapter_13/listing_13_3.py
function write_output (line 6) | async def write_output(prefix: str, stdout: StreamReader):
function main (line 11) | async def main():
FILE: chapter_13/listing_13_5.py
function main (line 5) | async def main():
FILE: chapter_13/listing_13_6.py
function main (line 5) | async def main():
FILE: chapter_13/listing_13_7.py
function encrypt (line 8) | async def encrypt(text: str) -> bytes:
function main (line 18) | async def main():
FILE: chapter_13/listing_13_8.py
function encrypt (line 10) | async def encrypt(sem: Semaphore, text: str) -> bytes:
function main (line 21) | async def main():
FILE: chapter_14/listing_14_1.py
class TaskRunner (line 4) | class TaskRunner:
method __init__ (line 6) | def __init__(self):
method add_task (line 10) | def add_task(self, func):
method _run_all (line 13) | async def _run_all(self):
method run (line 26) | def run(self):
function regular_function (line 32) | def regular_function():
function coroutine_function (line 36) | async def coroutine_function():
FILE: chapter_14/listing_14_10.py
function accept_connection (line 8) | def accept_connection(future: CustomFuture, connection: socket): #A
function sock_accept (line 13) | async def sock_accept(sel: BaseSelector, sock) -> socket: #B
function main (line 22) | async def main(sel: BaseSelector):
FILE: chapter_14/listing_14_11.py
class CustomTask (line 4) | class CustomTask(CustomFuture):
method __init__ (line 6) | def __init__(self, coro, loop):
method step (line 14) | def step(self): # B
method _future_done (line 23) | def _future_done(self, result): # D
FILE: chapter_14/listing_14_12.py
class EventLoop (line 7) | class EventLoop:
method __init__ (line 9) | def __init__(self):
method _register_socket_to_read (line 14) | def _register_socket_to_read(self, sock, callback):
method _set_current_result (line 25) | def _set_current_result(self, result):
method sock_recv (line 28) | async def sock_recv(self, sock):
method sock_accept (line 32) | async def sock_accept(self, sock):
method sock_close (line 36) | def sock_close(self, sock):
method register_task (line 40) | def register_task(self, task):
method recieved_data (line 43) | def recieved_data(self, future, sock):
method accept_connection (line 47) | def accept_connection(self, future, sock):
method run (line 51) | def run(self, coro):
FILE: chapter_14/listing_14_13.py
function read_from_client (line 7) | async def read_from_client(conn, loop: EventLoop): #A
function listen_for_connections (line 16) | async def listen_for_connections(sock, loop: EventLoop): #B
function main (line 24) | async def main(loop: EventLoop):
FILE: chapter_14/listing_14_2.py
class Server (line 6) | class Server:
method __init__ (line 9) | def __init__(self, host: str, port: int):
method start_server (line 13) | async def start_server(self):
method _client_connected (line 17) | def _client_connected(self, reader: StreamReader, writer: StreamWriter):
method listen_for_messages (line 21) | async def listen_for_messages(self, reader: StreamReader):
function main (line 26) | async def main():
FILE: chapter_14/listing_14_3.py
function create_tasks_no_sleep (line 5) | async def create_tasks_no_sleep():
function create_tasks_sleep (line 12) | async def create_tasks_sleep():
function main (line 21) | async def main():
FILE: chapter_14/listing_14_4.py
function connected (line 6) | async def connected(reader: StreamReader, writer: StreamWriter):
function main (line 14) | async def main():
FILE: chapter_14/listing_14_5.py
function coroutine (line 5) | def coroutine():
FILE: chapter_14/listing_14_6.py
function generator (line 4) | def generator(start: int, end: int):
function run_generator_step (line 13) | def run_generator_step(gen: Generator[int, None, None]): #A
FILE: chapter_14/listing_14_7.py
function say_hello (line 1) | async def say_hello():
function say_goodbye (line 5) | async def say_goodbye():
function meet_and_greet (line 9) | async def meet_and_greet():
FILE: chapter_14/listing_14_8.py
class CustomFuture (line 1) | class CustomFuture:
method __init__ (line 3) | def __init__(self):
method result (line 8) | def result(self):
method is_finished (line 11) | def is_finished(self):
method set_result (line 14) | def set_result(self, result):
method add_done_callback (line 20) | def add_done_callback(self, fn):
method __await__ (line 23) | def __await__(self):
FILE: util/async_timer.py
function async_timed (line 6) | def async_timed():
FILE: util/delay_functions.py
function delay (line 4) | async def delay(delay_seconds: int) -> int:
[
{
"path": "README.md",
"chars": 1303,
"preview": "# Concurrency in Python with Asyncio\n\nSource code to the Manning book *Concurrency in Python with Asyncio*.\n\n## Running\n"
},
{
"path": "chapter_01/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_01/listing_1_1.py",
"chars": 273,
"preview": "import requests\n\nresponse = requests.get('https://www.example.com')\n\nitems = response.headers.items()\n\nheaders = [f'{key"
},
{
"path": "chapter_01/listing_1_2.py",
"chars": 291,
"preview": "import os\nimport threading\n\nprint(f'Python process running with process id: {os.getpid()}')\n\ntotal_threads = threading.a"
},
{
"path": "chapter_01/listing_1_3.py",
"chars": 407,
"preview": "import threading\n\n\ndef hello_from_thread():\n print(f'Hello from thread {threading.current_thread()}!')\n\n\nhello_thread"
},
{
"path": "chapter_01/listing_1_4.py",
"chars": 322,
"preview": "import multiprocessing\nimport os\n\n\ndef hello_from_process():\n print(f'Hello from child process {os.getpid()}!')\n\n\nif "
},
{
"path": "chapter_01/listing_1_5.py",
"chars": 438,
"preview": "import time\n\n\ndef print_fib(number: int) -> None:\n def fib(n: int) -> int:\n if n == 1:\n return 0\n "
},
{
"path": "chapter_01/listing_1_6.py",
"chars": 711,
"preview": "import threading\nimport time\n\n\ndef print_fib(number: int) -> None:\n def fib(n: int) -> int:\n if n == 1:\n "
},
{
"path": "chapter_01/listing_1_7.py",
"chars": 302,
"preview": "import time\nimport requests\n\n\ndef read_example() -> None:\n response = requests.get('https://www.example.com')\n pri"
},
{
"path": "chapter_01/listing_1_8.py",
"chars": 493,
"preview": "import time\nimport threading\nimport requests\n\n\ndef read_example() -> None:\n response = requests.get('https://www.exam"
},
{
"path": "chapter_02/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_02/listing_2_1.py",
"chars": 60,
"preview": "async def my_coroutine() -> None:\n print('Hello world!')\n"
},
{
"path": "chapter_02/listing_2_10.py",
"chars": 399,
"preview": "import asyncio\nfrom util import delay\n\n\nasync def hello_every_second():\n for i in range(2):\n await asyncio.sle"
},
{
"path": "chapter_02/listing_2_11.py",
"chars": 525,
"preview": "import asyncio\nfrom asyncio import CancelledError\nfrom util import delay\n\n\nasync def main():\n long_task = asyncio.cre"
},
{
"path": "chapter_02/listing_2_12.py",
"chars": 364,
"preview": "import asyncio\nfrom util import delay\n\n\nasync def main():\n delay_task = asyncio.create_task(delay(2))\n try:\n "
},
{
"path": "chapter_02/listing_2_13.py",
"chars": 355,
"preview": "import asyncio\nfrom util import delay\n\n\nasync def main():\n task = asyncio.create_task(delay(10))\n\n try:\n re"
},
{
"path": "chapter_02/listing_2_14.py",
"chars": 237,
"preview": "from asyncio import Future\n\nmy_future = Future()\n\nprint(f'Is my_future done? {my_future.done()}')\n\nmy_future.set_result("
},
{
"path": "chapter_02/listing_2_15.py",
"chars": 483,
"preview": "from asyncio import Future\nimport asyncio\n\n\ndef make_request() -> Future:\n future = Future()\n asyncio.create_task("
},
{
"path": "chapter_02/listing_2_16.py",
"chars": 576,
"preview": "import functools\nimport time\nfrom typing import Callable, Any\n\n\ndef async_timed():\n def wrapper(func: Callable) -> Ca"
},
{
"path": "chapter_02/listing_2_17.py",
"chars": 470,
"preview": "import asyncio\nfrom util import async_timed\n\n\n@async_timed()\nasync def delay(delay_seconds: int) -> int:\n print(f'sle"
},
{
"path": "chapter_02/listing_2_18.py",
"chars": 393,
"preview": "import asyncio\nfrom util import async_timed\n\n\n@async_timed()\nasync def cpu_bound_work() -> int:\n counter = 0\n for "
},
{
"path": "chapter_02/listing_2_19.py",
"chars": 468,
"preview": "import asyncio\nfrom util import async_timed, delay\n\n\n@async_timed()\nasync def cpu_bound_work() -> int:\n counter = 0\n "
},
{
"path": "chapter_02/listing_2_2.py",
"chars": 377,
"preview": "async def coroutine_add_one(number: int) -> int:\n return number + 1\n\n\ndef add_one(number: int) -> int:\n return num"
},
{
"path": "chapter_02/listing_2_20.py",
"chars": 451,
"preview": "import asyncio\nimport requests\nfrom util import async_timed\n\n\n@async_timed()\nasync def get_example_status() -> int:\n "
},
{
"path": "chapter_02/listing_2_21.py",
"chars": 164,
"preview": "import asyncio\n\n\nasync def main():\n await asyncio.sleep(1)\n\n\nloop = asyncio.new_event_loop()\n\ntry:\n loop.run_until"
},
{
"path": "chapter_02/listing_2_22.py",
"chars": 233,
"preview": "import asyncio\nfrom util import delay\n\n\ndef call_later():\n print(\"I'm being called in the future!\")\n\n\nasync def main("
},
{
"path": "chapter_02/listing_2_23.py",
"chars": 325,
"preview": "import asyncio\nfrom util import async_timed\n\n\n@async_timed()\nasync def cpu_bound_work() -> int:\n counter = 0\n for "
},
{
"path": "chapter_02/listing_2_24.py",
"chars": 146,
"preview": "import asyncio\n\n\nasync def main():\n loop = asyncio.get_running_loop()\n loop.slow_callback_duration = .250\n\n\nasynci"
},
{
"path": "chapter_02/listing_2_3.py",
"chars": 148,
"preview": "import asyncio\n\n\nasync def coroutine_add_one(number: int) -> int:\n return number + 1\n\n\nresult = asyncio.run(coroutine"
},
{
"path": "chapter_02/listing_2_4.py",
"chars": 248,
"preview": "import asyncio\n\n\nasync def add_one(number: int) -> int:\n return number + 1\n\n\nasync def main() -> None:\n one_plus_o"
},
{
"path": "chapter_02/listing_2_5.py",
"chars": 221,
"preview": "import asyncio\n\n\nasync def hello_world_message() -> str:\n await asyncio.sleep(1)\n return \"Hello World!\"\n\n\nasync de"
},
{
"path": "chapter_02/listing_2_6.py",
"chars": 240,
"preview": "import asyncio\n\n\nasync def delay(delay_seconds: int) -> int:\n print(f'sleeping for {delay_seconds} second(s)')\n aw"
},
{
"path": "chapter_02/listing_2_7.py",
"chars": 359,
"preview": "import asyncio\nfrom util import delay\n\n\nasync def add_one(number: int) -> int:\n return number + 1\n\n\nasync def hello_w"
},
{
"path": "chapter_02/listing_2_8.py",
"chars": 217,
"preview": "import asyncio\nfrom util import delay\n\n\nasync def main():\n sleep_for_three = asyncio.create_task(delay(3))\n print("
},
{
"path": "chapter_02/listing_2_9.py",
"chars": 307,
"preview": "import asyncio\nfrom util import delay\n\n\nasync def main():\n sleep_for_three = asyncio.create_task(delay(3))\n sleep_"
},
{
"path": "chapter_03/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_03/listing_3_1.py",
"chars": 372,
"preview": "import socket\n\nserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nserver_socket.setsockopt(socket.SOL_SOC"
},
{
"path": "chapter_03/listing_3_10.py",
"chars": 1900,
"preview": "import asyncio\nfrom asyncio import AbstractEventLoop\nimport socket\nimport logging\nimport signal\nfrom typing import List\n"
},
{
"path": "chapter_03/listing_3_2.py",
"chars": 656,
"preview": "import socket\n\nserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nserver_socket.setsockopt(socket.SOL_SOC"
},
{
"path": "chapter_03/listing_3_3.py",
"chars": 885,
"preview": "import socket\n\nserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nserver_socket.setsockopt(socket.SOL_SOC"
},
{
"path": "chapter_03/listing_3_4.py",
"chars": 177,
"preview": "import socket\n\nserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nserver_socket.bind(('127.0.0.1', 8000))"
},
{
"path": "chapter_03/listing_3_5.py",
"chars": 963,
"preview": "import socket\n\nserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nserver_socket.setsockopt(socket.SOL_SOC"
},
{
"path": "chapter_03/listing_3_6.py",
"chars": 1148,
"preview": "import socket\n\nserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nserver_socket.setsockopt(socket.SOL_SOC"
},
{
"path": "chapter_03/listing_3_7.py",
"chars": 1065,
"preview": "import selectors\nimport socket\nfrom selectors import SelectorKey\nfrom typing import List, Tuple\n\nselector = selectors.De"
},
{
"path": "chapter_03/listing_3_8.py",
"chars": 1002,
"preview": "import asyncio\nimport socket\nfrom asyncio import AbstractEventLoop\n\n\nasync def echo(connection: socket,\n l"
},
{
"path": "chapter_03/listing_3_9.py",
"chars": 476,
"preview": "import asyncio\nfrom asyncio import AbstractEventLoop\nimport signal\nfrom typing import Set\nfrom util import delay\n\n\ndef c"
},
{
"path": "chapter_04/__init__.py",
"chars": 326,
"preview": "import asyncio\nfrom aiohttp import ClientSession\nfrom util import async_timed\n\n\n@async_timed()\nasync def fetch_status(se"
},
{
"path": "chapter_04/listing_4_1.py",
"chars": 1358,
"preview": "import asyncio\nimport socket\nfrom types import TracebackType\nfrom typing import Optional, Type\n\n\nclass ConnectedSocket:\n"
},
{
"path": "chapter_04/listing_4_10.py",
"chars": 629,
"preview": "import asyncio\nimport aiohttp\nfrom util import async_timed\nfrom chapter_04 import fetch_status\n\n\n@async_timed()\nasync de"
},
{
"path": "chapter_04/listing_4_11.py",
"chars": 936,
"preview": "import asyncio\nimport aiohttp\nimport logging\nfrom util import async_timed\nfrom chapter_04 import fetch_status\n\n\n@async_t"
},
{
"path": "chapter_04/listing_4_12.py",
"chars": 1022,
"preview": "import aiohttp\nimport asyncio\nimport logging\nfrom chapter_04 import fetch_status\nfrom util import async_timed\n\n\n@async_t"
},
{
"path": "chapter_04/listing_4_13.py",
"chars": 709,
"preview": "import asyncio\nimport aiohttp\nfrom util import async_timed\nfrom chapter_04 import fetch_status\n\n\n@async_timed()\nasync de"
},
{
"path": "chapter_04/listing_4_14.py",
"chars": 746,
"preview": "import asyncio\nimport aiohttp\nfrom chapter_04 import fetch_status\nfrom util import async_timed\n\n\n@async_timed()\nasync de"
},
{
"path": "chapter_04/listing_4_15.py",
"chars": 716,
"preview": "import asyncio\nimport aiohttp\nfrom chapter_04 import fetch_status\nfrom util import async_timed\n\n\n@async_timed()\nasync de"
},
{
"path": "chapter_04/listing_4_16.py",
"chars": 510,
"preview": "import asyncio\nimport aiohttp\nfrom chapter_04 import fetch_status\n\n\nasync def main():\n async with aiohttp.ClientSessi"
},
{
"path": "chapter_04/listing_4_2.py",
"chars": 493,
"preview": "import asyncio\nimport aiohttp\nfrom aiohttp import ClientSession\nfrom util import async_timed\n\n\n@async_timed()\nasync def "
},
{
"path": "chapter_04/listing_4_3.py",
"chars": 537,
"preview": "import asyncio\nimport aiohttp\nfrom aiohttp import ClientSession\n\n\nasync def fetch_status(session: ClientSession,\n "
},
{
"path": "chapter_04/listing_4_4.py",
"chars": 218,
"preview": "import asyncio\nfrom util import async_timed, delay\n\n\n@async_timed()\nasync def main() -> None:\n delay_times = [3, 3, 3"
},
{
"path": "chapter_04/listing_4_5.py",
"chars": 255,
"preview": "import asyncio\nfrom util import async_timed, delay\n\n\n@async_timed()\nasync def main() -> None:\n delay_times = [3, 3, 3"
},
{
"path": "chapter_04/listing_4_6.py",
"chars": 410,
"preview": "import asyncio\nimport aiohttp\nfrom chapter_04 import fetch_status\nfrom util import async_timed\n\n\n@async_timed()\nasync de"
},
{
"path": "chapter_04/listing_4_7.py",
"chars": 153,
"preview": "import asyncio\nfrom util import delay\n\n\nasync def main():\n results = await asyncio.gather(delay(3), delay(1))\n pri"
},
{
"path": "chapter_04/listing_4_8.py",
"chars": 524,
"preview": "import asyncio\nimport aiohttp\nfrom util import async_timed\nfrom chapter_04 import fetch_status\n\n\n@async_timed()\nasync de"
},
{
"path": "chapter_04/listing_4_9.py",
"chars": 731,
"preview": "import asyncio\nimport aiohttp\nfrom util import async_timed\nfrom chapter_04 import fetch_status\n\n\n@async_timed()\nasync de"
},
{
"path": "chapter_05/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_05/common_words.txt",
"chars": 5839,
"preview": "the\nof\nto\nand\na\nin\nis\nit\nyou\nthat\nhe\nwas\nfor\non\nare\nwith\nas\nI\nhis\nthey\nbe\nat\none\nhave\nthis\nfrom\nor\nhad\nby\nnot\nword\nbut\nw"
},
{
"path": "chapter_05/listing_5_1.py",
"chars": 485,
"preview": "import asyncpg\nimport asyncio\n\n\nasync def main():\n connection = await asyncpg.connect(host='127.0.0.1',\n "
},
{
"path": "chapter_05/listing_5_10.py",
"chars": 938,
"preview": "import asyncio\nimport logging\nimport asyncpg\n\n\nasync def main():\n connection = await asyncpg.connect(host='127.0.0.1'"
},
{
"path": "chapter_05/listing_5_11.py",
"chars": 794,
"preview": "import asyncio\nimport asyncpg\nimport logging\n\n\nasync def main():\n connection = await asyncpg.connect(host='127.0.0.1'"
},
{
"path": "chapter_05/listing_5_12.py",
"chars": 1145,
"preview": "import asyncio\nimport asyncpg\nfrom asyncpg.transaction import Transaction\n\n\nasync def main():\n connection = await asy"
},
{
"path": "chapter_05/listing_5_13.py",
"chars": 196,
"preview": "def positive_integers(until: int):\n for integer in range(until):\n yield integer\n\n\npositive_iterator = positive"
},
{
"path": "chapter_05/listing_5_14.py",
"chars": 405,
"preview": "import asyncio\nfrom util import delay, async_timed\n\n\nasync def positive_integers_async(until: int):\n for integer in r"
},
{
"path": "chapter_05/listing_5_15.py",
"chars": 568,
"preview": "import asyncio\nimport asyncpg\n\n\nasync def main():\n connection = await asyncpg.connect(host='127.0.0.1',\n "
},
{
"path": "chapter_05/listing_5_16.py",
"chars": 683,
"preview": "import asyncpg\nimport asyncio\n\n\nasync def main():\n connection = await asyncpg.connect(host='127.0.0.1',\n "
},
{
"path": "chapter_05/listing_5_17.py",
"chars": 880,
"preview": "import asyncpg\nimport asyncio\n\n\nasync def take(generator, to_take: int):\n item_count = 0\n async for item in genera"
},
{
"path": "chapter_05/listing_5_2.py",
"chars": 1539,
"preview": "CREATE_BRAND_TABLE = \\\n \"\"\"\n CREATE TABLE IF NOT EXISTS brand(\n brand_id SERIAL PRIMARY KEY,\n brand_"
},
{
"path": "chapter_05/listing_5_3.py",
"chars": 897,
"preview": "import asyncpg\nimport asyncio\nfrom chapter_05.listing_5_2 import *\n\n\nasync def main():\n connection = await asyncpg.co"
},
{
"path": "chapter_05/listing_5_4.py",
"chars": 808,
"preview": "import asyncpg\nimport asyncio\nfrom asyncpg import Record\nfrom typing import List\n\n\nasync def main():\n connection = aw"
},
{
"path": "chapter_05/listing_5_5.py",
"chars": 1011,
"preview": "import asyncpg\nimport asyncio\nfrom typing import List, Tuple, Union\nfrom random import sample\n\n\ndef load_common_words() "
},
{
"path": "chapter_05/listing_5_6.py",
"chars": 1997,
"preview": "import asyncio\nimport asyncpg\nfrom random import randint, sample\nfrom typing import List, Tuple\nfrom chapter_05.listing_"
},
{
"path": "chapter_05/listing_5_7.py",
"chars": 1039,
"preview": "import asyncio\nimport asyncpg\n\nproduct_query = \\\n \"\"\"\nSELECT\np.product_id,\np.product_name,\np.brand_id,\ns.sku_id,\npc.p"
},
{
"path": "chapter_05/listing_5_8.py",
"chars": 1374,
"preview": "import asyncio\nimport asyncpg\nfrom util import async_timed\n\nproduct_query = \\\n \"\"\"\nSELECT\np.product_id,\np.product_nam"
},
{
"path": "chapter_05/listing_5_9.py",
"chars": 827,
"preview": "import asyncio\nimport asyncpg\n\n\nasync def main():\n connection = await asyncpg.connect(host='127.0.0.1',\n "
},
{
"path": "chapter_06/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_06/listing_6_1.py",
"chars": 701,
"preview": "import time\nfrom multiprocessing import Process\n\n\ndef count(count_to: int) -> int:\n start = time.time()\n counter ="
},
{
"path": "chapter_06/listing_6_10.py",
"chars": 618,
"preview": "from multiprocessing import Process, Value, Array\n\n\ndef increment_value(shared_int: Value):\n shared_int.value = share"
},
{
"path": "chapter_06/listing_6_11.py",
"chars": 519,
"preview": "from multiprocessing import Process, Value, cpu_count\n\n\ndef increment_value(shared_int: Value):\n shared_int.value = s"
},
{
"path": "chapter_06/listing_6_12.py",
"chars": 556,
"preview": "from multiprocessing import Process, Value\n\n\ndef increment_value(shared_int: Value):\n shared_int.get_lock().acquire()"
},
{
"path": "chapter_06/listing_6_13.py",
"chars": 605,
"preview": "from concurrent.futures import ProcessPoolExecutor\nimport asyncio\nfrom multiprocessing import Value\n\nshared_counter: Val"
},
{
"path": "chapter_06/listing_6_14.py",
"chars": 1903,
"preview": "from concurrent.futures import ProcessPoolExecutor\nimport functools\nimport asyncio\nfrom multiprocessing import Value\nfro"
},
{
"path": "chapter_06/listing_6_15.py",
"chars": 1886,
"preview": "import asyncio\nimport asyncpg\nfrom util import async_timed\nfrom typing import List, Dict\nfrom concurrent.futures.process"
},
{
"path": "chapter_06/listing_6_2.py",
"chars": 345,
"preview": "from multiprocessing import Pool\n\n\ndef say_hello(name: str) -> str:\n return f'Hi there, {name}'\n\n\nif __name__ == \"__m"
},
{
"path": "chapter_06/listing_6_3.py",
"chars": 359,
"preview": "from multiprocessing import Pool\n\n\ndef say_hello(name: str) -> str:\n return f'Hi there, {name}'\n\n\nif __name__ == \"__m"
},
{
"path": "chapter_06/listing_6_4.py",
"chars": 504,
"preview": "import time\nfrom concurrent.futures import ProcessPoolExecutor\n\n\ndef count(count_to: int) -> int:\n start = time.time("
},
{
"path": "chapter_06/listing_6_5.py",
"chars": 838,
"preview": "import asyncio\nfrom asyncio.events import AbstractEventLoop\nfrom concurrent.futures import ProcessPoolExecutor\nfrom func"
},
{
"path": "chapter_06/listing_6_6.py",
"chars": 919,
"preview": "import functools\nfrom typing import Dict\n\n\ndef map_frequency(text: str) -> Dict[str, int]:\n words = text.split(' ')\n "
},
{
"path": "chapter_06/listing_6_7.py",
"chars": 429,
"preview": "import time\n\nfreqs = {}\n\nwith open('googlebooks-eng-all-1gram-20120701-a', encoding='utf-8') as f:\n lines = f.readlin"
},
{
"path": "chapter_06/listing_6_8.py",
"chars": 1720,
"preview": "import asyncio\nimport concurrent.futures\nimport functools\nimport time\nfrom typing import Dict, List\n\n\ndef partition(data"
},
{
"path": "chapter_06/listing_6_9.py",
"chars": 1591,
"preview": "import asyncio\nimport concurrent.futures\nimport functools\nimport time\nfrom typing import Dict, List\nfrom chapter_06.list"
},
{
"path": "chapter_07/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_07/listing_7_1.py",
"chars": 534,
"preview": "from threading import Thread\nimport socket\n\n\ndef echo(client: socket):\n while True:\n data = client.recv(2048)\n"
},
{
"path": "chapter_07/listing_7_10.py",
"chars": 791,
"preview": "from threading import Lock\nfrom typing import List\n\n\nclass IntListThreadsafe:\n\n def __init__(self, wrapped_list: List"
},
{
"path": "chapter_07/listing_7_11.py",
"chars": 547,
"preview": "from threading import Lock, Thread\nimport time\n\nlock_a = Lock()\nlock_b = Lock()\n\n\ndef a():\n with lock_a: #A\n p"
},
{
"path": "chapter_07/listing_7_12.py",
"chars": 278,
"preview": "import tkinter\nfrom tkinter import ttk\n\nwindow = tkinter.Tk()\nwindow.title('Hello world app')\nwindow.geometry('200x100')"
},
{
"path": "chapter_07/listing_7_13.py",
"chars": 1592,
"preview": "import asyncio\nfrom concurrent.futures import Future\nfrom asyncio import AbstractEventLoop\nfrom typing import Callable, "
},
{
"path": "chapter_07/listing_7_14.py",
"chars": 2530,
"preview": "from queue import Queue\nfrom tkinter import Tk\nfrom tkinter import Label\nfrom tkinter import Entry\nfrom tkinter import t"
},
{
"path": "chapter_07/listing_7_15.py",
"chars": 493,
"preview": "import asyncio\nfrom asyncio import AbstractEventLoop\nfrom threading import Thread\nfrom chapter_07.listing_7_14 import Lo"
},
{
"path": "chapter_07/listing_7_16.py",
"chars": 543,
"preview": "import hashlib\nimport os\nimport string\nimport time\nimport random\n\n\ndef random_password(length: int) -> bytes:\n ascii_"
},
{
"path": "chapter_07/listing_7_17.py",
"chars": 849,
"preview": "import asyncio\nimport functools\nimport hashlib\nimport os\nfrom concurrent.futures.thread import ThreadPoolExecutor\nimport"
},
{
"path": "chapter_07/listing_7_18.py",
"chars": 235,
"preview": "import numpy as np\nimport time\n\ndata_points = 4000000000\nrows = 50\ncolumns = int(data_points / rows)\n\nmatrix = np.arange"
},
{
"path": "chapter_07/listing_7_19.py",
"chars": 669,
"preview": "import functools\nfrom concurrent.futures.thread import ThreadPoolExecutor\nimport numpy as np\nimport asyncio\nfrom util im"
},
{
"path": "chapter_07/listing_7_2.py",
"chars": 1287,
"preview": "from threading import Thread\nimport socket\n\n\nclass ClientEchoThread(Thread):\n\n def __init__(self, client):\n su"
},
{
"path": "chapter_07/listing_7_3.py",
"chars": 211,
"preview": "import requests\n\n\ndef get_status_code(url: str) -> int:\n response = requests.get(url)\n return response.status_code"
},
{
"path": "chapter_07/listing_7_4.py",
"chars": 491,
"preview": "import time\nimport requests\nfrom concurrent.futures import ThreadPoolExecutor\n\n\ndef get_status_code(url: str) -> int:\n "
},
{
"path": "chapter_07/listing_7_5.py",
"chars": 602,
"preview": "import functools\nimport requests\nimport asyncio\nfrom concurrent.futures import ThreadPoolExecutor\nfrom util import async"
},
{
"path": "chapter_07/listing_7_6.py",
"chars": 496,
"preview": "import functools\nimport requests\nimport asyncio\nfrom util import async_timed\n\n\ndef get_status_code(url: str) -> int:\n "
},
{
"path": "chapter_07/listing_7_7.py",
"chars": 413,
"preview": "import requests\nimport asyncio\nfrom util import async_timed\n\n\ndef get_status_code(url: str) -> int:\n response = reque"
},
{
"path": "chapter_07/listing_7_8.py",
"chars": 1046,
"preview": "import functools\nimport requests\nimport asyncio\nfrom concurrent.futures import ThreadPoolExecutor\nfrom threading import "
},
{
"path": "chapter_07/listing_7_9.py",
"chars": 525,
"preview": "from threading import Lock, Thread\nfrom typing import List\n\nlist_lock = Lock()\n\n\ndef sum_list(int_list: List[int]) -> in"
},
{
"path": "chapter_08/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_08/listing_8_1.py",
"chars": 1359,
"preview": "import asyncio\nfrom asyncio import Transport, Future, AbstractEventLoop\nfrom typing import Optional\n\n\nclass HTTPGetClien"
},
{
"path": "chapter_08/listing_8_10.py",
"chars": 1066,
"preview": "import asyncio\nimport os\nimport tty\nfrom collections import deque\nfrom chapter_08.listing_8_5 import create_stdin_reader"
},
{
"path": "chapter_08/listing_8_11.py",
"chars": 1622,
"preview": "import asyncio\nimport asyncpg\nimport os\nimport tty\nfrom collections import deque\nfrom asyncpg.pool import Pool\nfrom chap"
},
{
"path": "chapter_08/listing_8_12.py",
"chars": 1810,
"preview": "import asyncio\nimport logging\nfrom asyncio import StreamReader, StreamWriter\n\n\nclass ServerState:\n\n def __init__(self"
},
{
"path": "chapter_08/listing_8_13.py",
"chars": 2914,
"preview": "import asyncio\nimport logging\nfrom asyncio import StreamReader, StreamWriter\n\n\nclass ChatServer:\n\n def __init__(self)"
},
{
"path": "chapter_08/listing_8_14.py",
"chars": 2029,
"preview": "import asyncio\nimport os\nimport logging\nimport tty\nfrom asyncio import StreamReader, StreamWriter\nfrom collections impor"
},
{
"path": "chapter_08/listing_8_2.py",
"chars": 556,
"preview": "import asyncio\nfrom asyncio import AbstractEventLoop\nfrom chapter_08.listing_8_1 import HTTPGetClientProtocol\n\n\nasync de"
},
{
"path": "chapter_08/listing_8_3.py",
"chars": 863,
"preview": "import asyncio\nfrom asyncio import StreamReader\nfrom typing import AsyncGenerator\n\n\nasync def read_until_empty(stream_re"
},
{
"path": "chapter_08/listing_8_4.py",
"chars": 201,
"preview": "import asyncio\nfrom util import delay\n\n\nasync def main():\n while True:\n delay_time = input('Enter a time to sl"
},
{
"path": "chapter_08/listing_8_5.py",
"chars": 337,
"preview": "import asyncio\nimport sys\nfrom asyncio import StreamReader\n\n\nasync def create_stdin_reader() -> StreamReader:\n stream"
},
{
"path": "chapter_08/listing_8_6.py",
"chars": 300,
"preview": "import asyncio\nfrom chapter_08.listing_8_5 import create_stdin_reader\nfrom util import delay\n\n\nasync def main():\n std"
},
{
"path": "chapter_08/listing_8_7.py",
"chars": 566,
"preview": "import sys\nimport shutil\n\n\ndef save_cursor_position():\n sys.stdout.write('\\0337')\n\n\ndef restore_cursor_position():\n "
},
{
"path": "chapter_08/listing_8_8.py",
"chars": 809,
"preview": "import sys\nfrom asyncio import StreamReader\nfrom collections import deque\nfrom chapter_08.listing_8_7 import move_back_o"
},
{
"path": "chapter_08/listing_8_9.py",
"chars": 372,
"preview": "from collections import deque\nfrom typing import Callable, Deque, Awaitable\n\n\nclass MessageStore:\n def __init__(self,"
},
{
"path": "chapter_09/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_09/async_views/async_api/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_09/async_views/async_api/admin.py",
"chars": 63,
"preview": "from django.contrib import admin\n\n# Register your models here.\n"
},
{
"path": "chapter_09/async_views/async_api/apps.py",
"chars": 92,
"preview": "from django.apps import AppConfig\n\n\nclass AsyncApiConfig(AppConfig):\n name = 'async_api'\n"
},
{
"path": "chapter_09/async_views/async_api/migrations/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_09/async_views/async_api/models.py",
"chars": 108,
"preview": "from django.db import models\n\n\nclass Url(models.Model):\n question_text = models.CharField(max_length=200)"
},
{
"path": "chapter_09/async_views/async_api/templates/async_api/requests.html",
"chars": 661,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Request Summary</title>\n</head>\n<body>\n<h1"
},
{
"path": "chapter_09/async_views/async_api/tests.py",
"chars": 60,
"preview": "from django.test import TestCase\n\n# Create your tests here.\n"
},
{
"path": "chapter_09/async_views/async_api/urls.py",
"chars": 249,
"preview": "from django.urls import path\nfrom . import views\n\napp_name = 'async_api'\n\nurlpatterns = [\n path('', views.requests_vi"
},
{
"path": "chapter_09/async_views/async_api/views.py",
"chars": 2138,
"preview": "import asyncio\nfrom datetime import datetime\nfrom aiohttp import ClientSession\nfrom django.shortcuts import render\nimpor"
},
{
"path": "chapter_09/async_views/async_views/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_09/async_views/async_views/asgi.py",
"chars": 399,
"preview": "\"\"\"\nASGI config for async_views project.\n\nIt exposes the ASGI callable as a module-level variable named ``application``."
},
{
"path": "chapter_09/async_views/async_views/settings.py",
"chars": 3093,
"preview": "\"\"\"\nDjango settings for async_views project.\n\nGenerated by 'django-admin startproject' using Django 3.1.3.\n\nFor more inf"
},
{
"path": "chapter_09/async_views/async_views/urls.py",
"chars": 811,
"preview": "\"\"\"async_views URL Configuration\n\nThe `urlpatterns` list routes URLs to views. For more information please see:\n http"
},
{
"path": "chapter_09/async_views/async_views/wsgi.py",
"chars": 399,
"preview": "\"\"\"\nWSGI config for async_views project.\n\nIt exposes the WSGI callable as a module-level variable named ``application``."
},
{
"path": "chapter_09/async_views/manage.py",
"chars": 667,
"preview": "#!/usr/bin/env python\n\"\"\"Django's command-line utility for administrative tasks.\"\"\"\nimport os\nimport sys\n\n\ndef main():\n "
},
{
"path": "chapter_09/listing_9_1.py",
"chars": 495,
"preview": "from aiohttp import web\nfrom datetime import datetime\nfrom aiohttp.web_request import Request\nfrom aiohttp.web_response "
},
{
"path": "chapter_09/listing_9_10.html",
"chars": 523,
"preview": "<!DOCTYPE html>\n<html lang=\"\">\n<head>\n <title>Starlette Web Sockets</title>\n <script>\n document.addEventLis"
},
{
"path": "chapter_09/listing_9_2.py",
"chars": 1487,
"preview": "import asyncpg\nfrom aiohttp import web\nfrom aiohttp.web_app import Application\nfrom aiohttp.web_request import Request\nf"
},
{
"path": "chapter_09/listing_9_3.py",
"chars": 1781,
"preview": "import asyncpg\nfrom aiohttp import web\nfrom aiohttp.web_app import Application\nfrom aiohttp.web_request import Request\nf"
},
{
"path": "chapter_09/listing_9_4.py",
"chars": 1156,
"preview": "from aiohttp import web\nfrom aiohttp.web_request import Request\nfrom aiohttp.web_response import Response\nfrom chapter_0"
},
{
"path": "chapter_09/listing_9_5.py",
"chars": 424,
"preview": "from flask import Flask, jsonify\nimport psycopg2\n\napp = Flask(__name__)\n\nconn_info = \"dbname=products user=postgres pass"
},
{
"path": "chapter_09/listing_9_6.py",
"chars": 127,
"preview": "def application(env, start_response):\n start_response('200 OK', [('Content-Type','text/html')])\n return [b\"WSGI he"
},
{
"path": "chapter_09/listing_9_7.py",
"chars": 255,
"preview": "async def application(scope, receive, send):\n await send({\n 'type': 'http.response.start',\n 'status': 2"
},
{
"path": "chapter_09/listing_9_8.py",
"chars": 1316,
"preview": "import asyncpg\nfrom asyncpg import Record\nfrom asyncpg.pool import Pool\nfrom starlette.applications import Starlette\nfro"
},
{
"path": "chapter_09/listing_9_9.py",
"chars": 1279,
"preview": "import asyncio\nfrom starlette.applications import Starlette\nfrom starlette.endpoints import WebSocketEndpoint\nfrom starl"
},
{
"path": "chapter_10/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_10/listing_10_1.py",
"chars": 515,
"preview": "import asyncio\nimport random\nfrom aiohttp import web\nfrom aiohttp.web_request import Request\nfrom aiohttp.web_response i"
},
{
"path": "chapter_10/listing_10_10.py",
"chars": 685,
"preview": "import asyncio\nfrom chapter_10.listing_10_9 import retry, TooManyRetries\n\n\nasync def main():\n async def always_fail()"
},
{
"path": "chapter_10/listing_10_11.py",
"chars": 2001,
"preview": "import asyncio\nfrom datetime import datetime, timedelta\n\n\nclass CircuitOpenException(Exception):\n pass\n\n\nclass Circui"
},
{
"path": "chapter_10/listing_10_12.py",
"chars": 686,
"preview": "import asyncio\nfrom chapter_10.listing_10_11 import CircuitBreaker\n\n\nasync def main():\n async def slow_callback():\n "
},
{
"path": "chapter_10/listing_10_2.sql",
"chars": 306,
"preview": "CREATE TABLE user_cart(\n user_id INT NOT NULL,\n product_id INT NOT NULL\n);\n\nINSERT INTO user_cart VALUES (1, 1)"
},
{
"path": "chapter_10/listing_10_3.sql",
"chars": 335,
"preview": "CREATE TABLE user_favorite\n(\n user_id INT NOT NULL,\n product_id INT NOT NULL\n);\n\nINSERT INTO user_favorite VALU"
},
{
"path": "chapter_10/listing_10_4.py",
"chars": 900,
"preview": "import asyncpg\nfrom aiohttp.web_app import Application\nfrom asyncpg.pool import Pool\n\nDB_KEY = 'database'\n\n\nasync def cr"
},
{
"path": "chapter_10/listing_10_5.py",
"chars": 1274,
"preview": "import functools\nfrom aiohttp import web\nfrom aiohttp.web_request import Request\nfrom aiohttp.web_response import Respon"
},
{
"path": "chapter_10/listing_10_6.py",
"chars": 1255,
"preview": "import functools\nfrom aiohttp import web\nfrom aiohttp.web_request import Request\nfrom aiohttp.web_response import Respon"
},
{
"path": "chapter_10/listing_10_7.py",
"chars": 997,
"preview": "import functools\nfrom aiohttp import web\nfrom aiohttp.web_request import Request\nfrom aiohttp.web_response import Respon"
},
{
"path": "chapter_10/listing_10_8.py",
"chars": 4699,
"preview": "import asyncio\nfrom asyncio import Task\nimport aiohttp\nfrom aiohttp import web, ClientSession\nfrom aiohttp.web_request i"
},
{
"path": "chapter_10/listing_10_9.py",
"chars": 605,
"preview": "import asyncio\nimport logging\nfrom typing import Callable, Awaitable\n\n\nclass TooManyRetries(Exception):\n pass\n\n\nasync"
},
{
"path": "chapter_11/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_11/listing_11_1.py",
"chars": 417,
"preview": "import asyncio\n\ncounter: int = 0\n\n\nasync def increment():\n global counter\n await asyncio.sleep(0.01)\n counter ="
},
{
"path": "chapter_11/listing_11_10.py",
"chars": 558,
"preview": "import asyncio\nimport functools\nfrom asyncio import Event\n\n\ndef trigger_event(event: Event):\n event.set()\n\n\nasync def"
},
{
"path": "chapter_11/listing_11_11.py",
"chars": 810,
"preview": "import asyncio\nfrom asyncio import StreamReader, StreamWriter\n\n\nclass FileUpload:\n def __init__(self,\n "
},
{
"path": "chapter_11/listing_11_12.py",
"chars": 1013,
"preview": "import asyncio\nfrom asyncio import StreamReader, StreamWriter\nfrom chapter_11.listing_11_11 import FileUpload\n\n\nclass Fi"
},
{
"path": "chapter_11/listing_11_13.py",
"chars": 744,
"preview": "import asyncio\nfrom asyncio import Event\nfrom contextlib import suppress\n\n\nasync def trigger_event_periodically(event: E"
},
{
"path": "chapter_11/listing_11_14.py",
"chars": 971,
"preview": "import asyncio\nfrom asyncio import Condition\n\n\nasync def do_work(condition: Condition):\n while True:\n print('W"
},
{
"path": "chapter_11/listing_11_15.py",
"chars": 1802,
"preview": "import asyncio\nfrom enum import Enum\n\n\nclass ConnectionState(Enum):\n WAIT_INIT = 0\n INITIALIZING = 1\n INITIALIZ"
},
{
"path": "chapter_11/listing_11_2.py",
"chars": 481,
"preview": "import asyncio\n\ncounter: int = 0\n\n\nasync def increment():\n global counter\n temp_counter = counter\n temp_counter"
},
{
"path": "chapter_11/listing_11_3.py",
"chars": 1051,
"preview": "import asyncio\n\n\nclass MockSocket:\n def __init__(self):\n self.socket_closed = False\n\n async def send(self, "
},
{
"path": "chapter_11/listing_11_4.py",
"chars": 612,
"preview": "import asyncio\nfrom asyncio import Lock\nfrom util import delay\n\n\nasync def a(lock: Lock):\n print('Coroutine a waiting"
},
{
"path": "chapter_11/listing_11_5.py",
"chars": 1312,
"preview": "import asyncio\nfrom asyncio import Lock\n\n\nclass MockSocket:\n def __init__(self):\n self.socket_closed = False\n\n"
},
{
"path": "chapter_11/listing_11_6.py",
"chars": 400,
"preview": "import asyncio\nfrom asyncio import Semaphore\n\n\nasync def operation(semaphore: Semaphore):\n print('Waiting to acquire "
},
{
"path": "chapter_11/listing_11_7.py",
"chars": 687,
"preview": "import asyncio\nfrom asyncio import Semaphore\nfrom aiohttp import ClientSession\n\n\nasync def get_url(url: str,\n "
},
{
"path": "chapter_11/listing_11_8.py",
"chars": 802,
"preview": "import asyncio\nfrom asyncio import Semaphore\n\n\nasync def acquire(semaphore: Semaphore):\n print('Waiting to acquire')\n"
},
{
"path": "chapter_11/listing_11_9.py",
"chars": 209,
"preview": "import asyncio\nfrom asyncio import BoundedSemaphore\n\n\nasync def main():\n semaphore = BoundedSemaphore(1)\n\n await s"
},
{
"path": "chapter_12/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "chapter_12/listing_12_1.py",
"chars": 1690,
"preview": "import asyncio\nfrom asyncio import Queue\nfrom random import randrange\nfrom typing import List\n\n\nclass Product:\n def _"
},
{
"path": "chapter_12/listing_12_10.py",
"chars": 935,
"preview": "import asyncio\nfrom asyncio import Queue, LifoQueue\nfrom dataclasses import dataclass, field\n\n\n@dataclass(order=True)\ncl"
},
{
"path": "chapter_12/listing_12_2.py",
"chars": 2184,
"preview": "import asyncio\nfrom asyncio import Queue\nfrom random import randrange\n\n\nclass Product:\n def __init__(self, name: str,"
},
{
"path": "chapter_12/listing_12_3.py",
"chars": 1700,
"preview": "import asyncio\nfrom asyncio import Queue, Task\nfrom typing import List\nfrom random import randrange\nfrom aiohttp import "
},
{
"path": "chapter_12/listing_12_4.py",
"chars": 1813,
"preview": "import asyncio\nimport aiohttp\nimport logging\nfrom asyncio import Queue\nfrom aiohttp import ClientSession\nfrom bs4 import"
},
{
"path": "chapter_12/listing_12_5.py",
"chars": 674,
"preview": "import asyncio\nfrom asyncio import Queue, PriorityQueue\nfrom typing import Tuple\n\n\nasync def worker(queue: Queue):\n w"
},
{
"path": "chapter_12/listing_12_6.py",
"chars": 803,
"preview": "import asyncio\nfrom asyncio import Queue, PriorityQueue\nfrom dataclasses import dataclass, field\n\n\n@dataclass(order=True"
},
{
"path": "chapter_12/listing_12_7.py",
"chars": 2098,
"preview": "import asyncio\nfrom asyncio import Queue, Task\nfrom dataclasses import field, dataclass\nfrom enum import IntEnum\nfrom ty"
},
{
"path": "chapter_12/listing_12_8.py",
"chars": 916,
"preview": "import asyncio\nfrom asyncio import Queue, PriorityQueue\nfrom dataclasses import dataclass, field\n\n\n@dataclass(order=True"
},
{
"path": "chapter_12/listing_12_9.py",
"chars": 946,
"preview": "import asyncio\nfrom asyncio import Queue, PriorityQueue\nfrom dataclasses import dataclass, field\n\n\n@dataclass(order=True"
},
{
"path": "chapter_13/__init__.py",
"chars": 0,
"preview": ""
}
]
// ... and 32 more files (download for full content)
About this extraction
This page contains the full source code of the concurrency-in-python-with-asyncio/concurrency-in-python-with-asyncio GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 232 files (168.4 KB), approximately 45.4k tokens, and a symbol index with 451 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.