aiocsv
aiocsv is a Python library for asynchronous CSV reading and writing. It strives to be a drop-in replacement for Python's built-in `csv` module, providing `AsyncReader`, `AsyncDictReader`, `AsyncWriter`, and `AsyncDictWriter` classes. It supports Python 3.9+ and utilizes a C extension for improved performance. The library is actively maintained and currently at version 1.4.0.
Warnings
- gotcha When using `AsyncDictReader`, `fieldnames` can sometimes be `None`. Instead of accessing `AsyncDictReader.fieldnames` directly, use `await AsyncDictReader.get_fieldnames()` to reliably retrieve field names.
- gotcha `aiocsv` readers (`AsyncReader`, `AsyncDictReader`) expect file-like objects with an `async read(size: int)` coroutine, *not* an `AsyncIterable` over lines from a file. This differs from the standard `csv` module's behavior.
- gotcha Changes to `csv.field_size_limit` are not dynamically picked up by existing `AsyncReader` instances. The field size limit is cached during `Reader` instantiation.
- gotcha Files *must* be opened in text mode (`'r'` or `'w'`) and with `newline=""`. Additionally, ensure the file's line terminators match the dialect's `lineterminator`. `aiocsv` is less tolerant of mismatched newlines than the built-in `csv` module.
- gotcha The `AsyncWriter.writerows()` and `AsyncDictWriter.writerows()` methods temporarily store *all* provided rows in RAM before writing them to the file. Providing a generator for extremely large datasets can lead to high memory consumption.
Install
-
pip install aiocsv
Imports
- AsyncReader
from aiocsv import AsyncReader
- AsyncDictReader
from aiocsv import AsyncDictReader
- AsyncWriter
from aiocsv import AsyncWriter
- AsyncDictWriter
from aiocsv import AsyncDictWriter
Quickstart
import asyncio
import csv
import aiofiles
from aiocsv import AsyncReader, AsyncDictReader, AsyncWriter, AsyncDictWriter
async def main():
# Create a dummy CSV file for reading
async with aiofiles.open("example.csv", mode="w", encoding="utf-8", newline="") as afp:
writer = AsyncWriter(afp)
await writer.writerow(["name", "age"])
await writer.writerows([["John", 26], ["Sasha", 42]])
print("--- Reading simple CSV ---")
async with aiofiles.open("example.csv", mode="r", encoding="utf-8", newline="") as afp:
async for row in AsyncReader(afp):
print(row)
# Create a dummy TSV file for dict reading
async with aiofiles.open("example.tsv", mode="w", encoding="utf-8", newline="") as afp:
writer = AsyncDictWriter(afp, fieldnames=["name", "city"], delimiter="\t")
await writer.writeheader()
await writer.writerow({"name": "Alice", "city": "New York"})
await writer.writerow({"name": "Bob", "city": "London"})
print("\n--- Reading Dict CSV (TSV) ---")
async with aiofiles.open("example.tsv", mode="r", encoding="utf-8", newline="") as afp:
async for row in AsyncDictReader(afp, delimiter="\t"):
print(row)
# Writing new CSV file with AsyncWriter
print("\n--- Writing simple CSV ---")
async with aiofiles.open("output.csv", mode="w", encoding="utf-8", newline="") as afp:
writer = AsyncWriter(afp, dialect="unix")
await writer.writerow(["product", "price"])
await writer.writerows([["Laptop", 1200], ["Mouse", 25], ["Keyboard", 75]])
print("Written to output.csv")
# Writing new CSV file with AsyncDictWriter
print("\n--- Writing Dict CSV ---")
async with aiofiles.open("output_dict.csv", mode="w", encoding="utf-8", newline="") as afp:
writer = AsyncDictWriter(afp, ["item", "quantity", "status"], restval="N/A", quoting=csv.QUOTE_ALL)
await writer.writeheader()
await writer.writerow({"item": "Shirt", "quantity": 2, "status": "available"})
await writer.writerows([
{"item": "Pants", "quantity": 1},
{"item": "Socks", "quantity": 5, "status": "low stock"}
])
print("Written to output_dict.csv")
asyncio.run(main())