Skip to content

Commit

Permalink
Merge branch 'master' into scrapy-mongodb
Browse files Browse the repository at this point in the history
  • Loading branch information
bzaczynski authored Aug 2, 2024
2 parents 152227a + ac31789 commit 68d8fc0
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 1 deletion.
2 changes: 1 addition & 1 deletion functional-programming-python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This folder contains the sample code used in the RealPython tutorial [Functional Programming in Python: When and How to Use It](https://realpython.com/python-functional-programming/).

## Run the Scrips
## Run the Scripts

You can run the individual files as Python scripts:

Expand Down
3 changes: 3 additions & 0 deletions python-async-iterators/README.md
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/).
17 changes: 17 additions & 0 deletions python-async-iterators/async_comp.py
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())
36 changes: 36 additions & 0 deletions python-async-iterators/async_csv.py
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())
27 changes: 27 additions & 0 deletions python-async-iterators/async_range_v1.py
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())
19 changes: 19 additions & 0 deletions python-async-iterators/async_range_v2.py
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())
15 changes: 15 additions & 0 deletions python-async-iterators/async_range_v3.py
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())
22 changes: 22 additions & 0 deletions python-async-iterators/compress.py
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))
39 changes: 39 additions & 0 deletions python-async-iterators/counter.py
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())
5 changes: 5 additions & 0 deletions python-async-iterators/data.csv
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
22 changes: 22 additions & 0 deletions python-async-iterators/inf_integers.py
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))
27 changes: 27 additions & 0 deletions python-async-iterators/large_file_iterable.py
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())
32 changes: 32 additions & 0 deletions python-async-iterators/large_file_iterator.py
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())

0 comments on commit 68d8fc0

Please sign in to comment.