-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into scrapy-mongodb
- Loading branch information
Showing
13 changed files
with
265 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Asynchronous Iterators and Iterables in Python | ||
|
||
This folder provides the code examples for the Real Python tutorial [Asynchronous Iterators and Iterables in Python](https://realpython.com/python-async-iterators/). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import asyncio | ||
|
||
|
||
async def async_range(start, end): | ||
for i in range(start, end): | ||
await asyncio.sleep(0.2) | ||
yield i | ||
|
||
|
||
async def main(): | ||
number_list = [i async for i in async_range(0, 5)] | ||
number_dict = {i: str(i) async for i in async_range(0, 5)} | ||
print(number_list) | ||
print(number_dict) | ||
|
||
|
||
asyncio.run(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import asyncio | ||
import csv | ||
|
||
import aiofiles | ||
|
||
|
||
class AsyncCSVIterator: | ||
def __init__(self, path): | ||
self.path = path | ||
self.file_was_read = False | ||
|
||
def __aiter__(self): | ||
return self | ||
|
||
async def __anext__(self): | ||
if not self.file_was_read: | ||
async with aiofiles.open(self.path, mode="r") as file: | ||
lines = await file.readlines() | ||
self.reader = csv.reader(lines) | ||
self.file_was_read = True | ||
try: | ||
return next(self.reader) | ||
except StopIteration: | ||
raise StopAsyncIteration | ||
|
||
|
||
async def main(): | ||
csv_iter = AsyncCSVIterator("data.csv") | ||
# Skip the headers | ||
await anext(csv_iter) | ||
# Process the rest of the rows | ||
async for row in csv_iter: | ||
print(row) | ||
|
||
|
||
asyncio.run(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import asyncio | ||
|
||
|
||
class AsyncRange: | ||
def __init__(self, start, end): | ||
self.start = start | ||
self.end = end | ||
|
||
def __aiter__(self): | ||
return self | ||
|
||
async def __anext__(self): | ||
if self.start < self.end: | ||
await asyncio.sleep(0.5) | ||
value = self.start | ||
self.start += 1 | ||
return value | ||
else: | ||
raise StopAsyncIteration | ||
|
||
|
||
async def main(): | ||
async for i in AsyncRange(0, 5): | ||
print(i) | ||
|
||
|
||
asyncio.run(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import asyncio | ||
|
||
|
||
class AsyncRange: | ||
def __init__(self, start, end): | ||
self.data = range(start, end) | ||
|
||
async def __aiter__(self): | ||
for i in self.data: | ||
await asyncio.sleep(0.5) | ||
yield i | ||
|
||
|
||
async def main(): | ||
async for i in AsyncRange(0, 5): | ||
print(i) | ||
|
||
|
||
asyncio.run(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import asyncio | ||
|
||
|
||
async def async_range(start, end): | ||
for i in range(start, end): | ||
await asyncio.sleep(0.5) | ||
yield i | ||
|
||
|
||
async def main(): | ||
async for i in async_range(0, 5): | ||
print(i) | ||
|
||
|
||
asyncio.run(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import asyncio | ||
from pathlib import Path | ||
|
||
import aiofiles | ||
from zipstream import AioZipStream | ||
|
||
|
||
async def stream_generator(files): | ||
async_zipstream = AioZipStream(files) | ||
async for chunk in async_zipstream.stream(): | ||
yield chunk | ||
|
||
|
||
async def main(directory, zip_name="output.zip"): | ||
files = [{"file": path} for path in directory.iterdir() if path.is_file()] | ||
async with aiofiles.open(zip_name, mode="wb") as archive: | ||
async for chunk in stream_generator(files): | ||
await archive.write(chunk) | ||
|
||
|
||
directory = Path() | ||
asyncio.run(main(directory)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import asyncio | ||
from random import randint | ||
|
||
|
||
class AsyncCounterIterator: | ||
def __init__(self, name="", end=5): | ||
self.counter = 0 | ||
self.name = name | ||
self.end = end | ||
|
||
def __aiter__(self): | ||
return self | ||
|
||
async def __anext__(self): | ||
if self.counter >= self.end: | ||
raise StopAsyncIteration | ||
self.counter += 1 | ||
await asyncio.sleep(randint(1, 3) / 10) | ||
return self.counter | ||
|
||
|
||
async def task(iterator): | ||
async for item in iterator: | ||
print(item, f"from iterator {iterator.name}") | ||
|
||
|
||
async def main(): | ||
# This code runs sequentially: | ||
# await task(AsyncCounterIterator("#1")) | ||
# await task(AsyncCounterIterator("#2")) | ||
|
||
# This is concurrent: | ||
await asyncio.gather( | ||
task(AsyncCounterIterator("#1")), | ||
task(AsyncCounterIterator("#2")), | ||
) | ||
|
||
|
||
asyncio.run(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Name,Age,Job | ||
John Doe,30,Software Engineer | ||
Jane Smith,25,Data Scientist | ||
Jim Brown,45,Project Manager | ||
Jessica Jones,40,UX Designer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import asyncio | ||
|
||
|
||
async def async_inf_integers(start=0): | ||
current = start | ||
while True: | ||
yield current | ||
current += 1 | ||
await asyncio.sleep(0.5) | ||
|
||
|
||
async def main(stop=5): | ||
generator = async_inf_integers() | ||
while True: | ||
number = await anext(generator) | ||
# Process the number here... | ||
print(number) | ||
if number == stop - 1: | ||
break | ||
|
||
|
||
asyncio.run(main(20)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import asyncio | ||
|
||
import aiofiles | ||
|
||
|
||
class AsyncFileIterable: | ||
def __init__(self, path, chunk_size=1024): | ||
self.path = path | ||
self.chunk_size = chunk_size | ||
|
||
async def __aiter__(self): | ||
async with aiofiles.open(self.path, mode="rb") as file: | ||
while True: | ||
chunk = await file.read(self.chunk_size) | ||
if not chunk: | ||
break | ||
yield chunk | ||
|
||
|
||
async def main(): | ||
async for chunk in AsyncFileIterable("large-file.md"): | ||
# Process the file chunk here... | ||
await asyncio.sleep(0.2) | ||
print(chunk.decode("utf-8")) | ||
|
||
|
||
asyncio.run(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import asyncio | ||
|
||
import aiofiles | ||
|
||
|
||
class AsyncFileIterator: | ||
def __init__(self, path, chunk_size=1024): | ||
self.path = path | ||
self.chunk_size = chunk_size | ||
self.file = None | ||
|
||
def __aiter__(self): | ||
return self | ||
|
||
async def __anext__(self): | ||
if self.file is None: | ||
self.file = await aiofiles.open(self.path, mode="rb") | ||
chunk = await self.file.read(self.chunk_size) | ||
if not chunk: | ||
await self.file.close() | ||
raise StopAsyncIteration | ||
return chunk | ||
|
||
|
||
async def main(): | ||
async for chunk in AsyncFileIterator("large-file.md"): | ||
# Process the file chunk here... | ||
await asyncio.sleep(0.2) | ||
print(chunk.decode("utf-8")) | ||
|
||
|
||
asyncio.run(main()) |