Skip to content

Commit 0f4c997

Browse files
committed
Expand scope of repo to include all H&N Asyncio tutorials.
1 parent ca7e35c commit 0f4c997

10 files changed

Lines changed: 107 additions & 37 deletions

File tree

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Asyncio Tutorial
1+
# Asyncio Tutorials
22

33
![Python](https://img.shields.io/badge/Python-v^3.9-blue.svg?logo=python&longCache=true&logoColor=white&colorB=5e81ac&style=flat-square&colorA=4c566a)
44
![Asyncio](https://img.shields.io/badge/Asyncio-v^3.4.3-blue.svg?longCache=true&logo=python&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a)
@@ -9,10 +9,20 @@
99
[![GitHub Stars](https://img.shields.io/github/stars/hackersandslackers/asyncio-tutorial.svg?style=flat-square&colorA=4c566a&logo=GitHub&colorB=ebcb8b)](https://github.com/hackersandslackers/flask-blueprint-tutorial/stargazers)
1010
[![GitHub Forks](https://img.shields.io/github/forks/hackersandslackers/asyncio-tutorial.svg?style=flat-square&colorA=4c566a&logo=GitHub&colorB=ebcb8b)](https://github.com/hackersandslackers/flask-blueprint-tutorial/network)
1111

12+
13+
Source code demonstrating asynchronous Python for the corresponding Hackersandslackers posts.
14+
15+
### Part I
16+
17+
Introduction to asynchronous Python with Asyncio.
18+
19+
https://hackersandslackers.com/python-concurrency-asyncio/
20+
21+
### Part II
22+
1223
Make asynchronous HTTP requests and write to disk using **asyncio**, **aiohttp**, & **aiofiles**.
1324

14-
* **Tutorial**: https://hackersandslackers.com/async-requests-with-aiohttp/
15-
* **Demo**: TBD
25+
https://hackersandslackers.com/async-requests-with-aiohttp/
1626

1727

1828
# Getting Started

asyncio_tutorial/__init__.py

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,12 @@
1-
"""Script initialization."""
1+
"""Demonstrate Parts 1 and 2 of Hackersandslackers Asyncio tutorial series"""
22
import asyncio
33

4-
from aiohttp import ClientSession
5-
64
from asyncio_tutorial.logger import LOGGER
7-
from asyncio_tutorial.tasks import create_tasks
8-
from config import EXPORT_DIR, HTML_HEADERS
9-
from data import parse_urls
10-
11-
from .logger import LOGGER
12-
13-
14-
async def init_script():
15-
"""Open async HTTP session & execute created tasks."""
16-
urls = parse_urls()
17-
async with ClientSession(headers=HTML_HEADERS) as session:
18-
tasks = await create_tasks(session, urls, EXPORT_DIR)
19-
await asyncio.gather(*tasks)
20-
await inspect_loop()
21-
LOGGER.success(
22-
f"Saved {len(urls)} files to `{EXPORT_DIR}`"
23-
)
24-
255

26-
async def inspect_loop() -> str:
27-
"""
28-
Get event loop info.
6+
from .part_I_asyncio_intro import intro_tutorial
7+
from .part_II_aiohttp_aiofiles import aiohttp_aiofiles_tutorial
298

30-
:param: List[Task] tasks
319

32-
:return: str
33-
"""
34-
loop = asyncio.get_event_loop()
35-
return LOGGER.info(f"Loop finished in {loop.time()} seconds.")
10+
def init_script():
11+
asyncio.run(intro_tutorial())
12+
asyncio.run(aiohttp_aiofiles_tutorial())
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""Script initialization."""
2+
import asyncio
3+
4+
from aiohttp import ClientSession
5+
6+
from asyncio_tutorial.logger import LOGGER
7+
from config import EXPORT_DIR, HTML_HEADERS
8+
from data import parse_urls
9+
10+
from .tasks import create_tasks
11+
12+
13+
async def aiohttp_aiofiles_tutorial():
14+
"""Open async HTTP session & execute created tasks."""
15+
LOGGER.info(f"Asyncio tutorial Part II: HTTP Requests with Aiohttp & Aiofiles.")
16+
urls = parse_urls()
17+
async with ClientSession(headers=HTML_HEADERS) as session:
18+
tasks = await create_tasks(session, urls, EXPORT_DIR)
19+
await asyncio.gather(*tasks)
20+
await inspect_loop()
21+
LOGGER.success(f"Saved {len(urls)} files to `{EXPORT_DIR}`")
22+
23+
24+
async def inspect_loop() -> str:
25+
"""
26+
Get event loop info.
27+
28+
:param: List[Task] tasks
29+
30+
:return: str
31+
"""
32+
loop = asyncio.get_event_loop()
33+
return LOGGER.info(f"Loop finished in {loop.time()} seconds.")

asyncio_tutorial/fetcher.py renamed to asyncio_tutorial/part_II_aiohttp_aiofiles/fetcher.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from aiohttp import ClientError, ClientSession, InvalidURL
33

44
from asyncio_tutorial.logger import LOGGER
5-
from asyncio_tutorial.writer import write_file
5+
6+
from .writer import write_file
67

78

89
async def fetch_and_save_url(

asyncio_tutorial/tasks.py renamed to asyncio_tutorial/part_II_aiohttp_aiofiles/tasks.py

File renamed without changes.

asyncio_tutorial/writer.py renamed to asyncio_tutorial/part_II_aiohttp_aiofiles/writer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Write to disk asynchronously."""
22
import aiofiles
33

4-
from .logger import LOGGER
4+
from asyncio_tutorial.logger import LOGGER
55

66

77
async def write_file(url: str, body: bytes, filetype: str, directory: str):
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""Simple script to create and execute tasks in a loop"""
2+
import asyncio
3+
4+
from asyncio_tutorial.logger import LOGGER
5+
6+
from .coroutines import simple_coroutine
7+
from .tasks import create_task
8+
9+
10+
async def intro_tutorial():
11+
"""Simple demonstration of a async script lifecycle"""
12+
LOGGER.info(f"Asyncio tutorial Part I: Intro to Asyncio.")
13+
tasks = []
14+
for i in range(3):
15+
task = await create_task(simple_coroutine(i, delay=1))
16+
tasks.append(task)
17+
LOGGER.info(type(task))
18+
await asyncio.gather(*tasks)
19+
LOGGER.info("-------------------------------------------")
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""Create a coroutine containing the business logic of our task."""
2+
import asyncio
3+
4+
from asyncio_tutorial.logger import LOGGER
5+
6+
7+
async def simple_coroutine(number: int, delay=1):
8+
"""
9+
Wait for a period of time before logging the coro number.
10+
11+
:param int number: Number to identify the current coroutine.
12+
:param int delay: Time delay to simulate a function which takes time to complete.
13+
"""
14+
await asyncio.sleep(delay)
15+
LOGGER.info(f"This is Coroutine {number} being executed.")
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Create task from provided coroutine."""
2+
import asyncio
3+
from asyncio import Task
4+
5+
from asyncio_tutorial.logger import LOGGER
6+
7+
8+
async def create_task(coroutine) -> Task:
9+
"""
10+
Create asyncio tasks to be executed.
11+
12+
:param coroutine: Coroutine to create async task from.
13+
14+
:returns: Task
15+
"""
16+
LOGGER.info(type(coroutine))
17+
return asyncio.create_task(coroutine)

main.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
"""Script entry point."""
2-
import asyncio
3-
42
from asyncio_tutorial import init_script
53

64
if __name__ == "__main__":
7-
asyncio.run(init_script())
5+
init_script()

0 commit comments

Comments
 (0)