Skip to main content

AIOFile

Github Actions Latest Version https://img.shields.io/pypi/wheel/aiofile.svg https://img.shields.io/pypi/pyversions/aiofile.svg https://img.shields.io/pypi/l/aiofile.svg

Real asynchronous file operations with asyncio support.

Status

Development - Stable

Features

  • Since version 2.0.0 using caio, is contain linux libaio and two thread-based implementations (c-based and pure-python).

  • AIOFile has no internal pointer. You should pass offset and chunk_size for each operation or use helpers (Reader or Writer). The simples way is use async_open for create object with file-like interface.

  • For Linux using implementation based on libaio.

  • For POSIX (MacOS X and optional Linux) using implementation using on threadpool.

  • Otherwise using pure-python thread-based implementation.

  • Implementation chooses automatically depending on system compatibility.

Code examples

All code examples requires python 3.6+.

High-level API

async_open helper

The async_open helper creates file like object with file-like methods:

import asyncio
from aiofile import async_open


async def main():
    async with async_open("/tmp/hello.txt", 'w+') as afp:
        await afp.write("Hello ")
        await afp.write("world")
        afp.seek(0)

        print(await afp.read())

        await afp.write("Hello from\nasync world")
        print(await afp.readline())
        print(await afp.readline())

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Suboptimal for small lines because doesn’t reuse read buffer. When you want to read file by lines please avoid to use async_open use LineReader instead.

Supported methods:

  • async def read(length = -1) - reading chunk from file, when length is -1 will be read file to the end.

  • async def write(data) - write chunk to file

  • def seek(offset) - set file pointer position

  • def tell() - returns current file pointer position

  • async def readline(size=-1, newline="\n") - read chunks until newline or EOF.

Reader and Writer

When you want to read or write file linearly following example might be helpful.

import asyncio
from aiofile import AIOFile, Reader, Writer


async def main():
    async with AIOFile("/tmp/hello.txt", 'w+') as afp:
        writer = Writer(afp)
        reader = Reader(afp, chunk_size=8)

        await writer("Hello")
        await writer(" ")
        await writer("World")
        await afp.fsync()

        async for chunk in reader:
            print(chunk)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

LineReader - read file line by line

LineReader is a helper that is very effective when you want to read a file linearly and line by line.

It contains a buffer and will read the fragments of the file chunk by chunk into the buffer, where it will try to find lines.

The default chunk size is 4KB.

import asyncio
from aiofile import AIOFile, LineReader, Writer


async def main():
    async with AIOFile("/tmp/hello.txt", 'w+') as afp:
        writer = Writer(afp)

        await writer("Hello")
        await writer(" ")
        await writer("World")
        await writer("\n")
        await writer("\n")
        await writer("From async world")
        await afp.fsync()

        async for line in LineReader(afp):
            print(line)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

When you want to read file by lines please avoid to use async_open use LineReader instead.

Low-level API

Following API is just little bit sugared caio API.

Write and Read

import asyncio
from aiofile import AIOFile


async def main():
    async with AIOFile("/tmp/hello.txt", 'w+') as afp:
        await afp.write("Hello ")
        await afp.write("world", offset=7)
        await afp.fsync()

        print(await afp.read())


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Read file line by line

import asyncio
from aiofile import AIOFile, LineReader, Writer


async def main():
    async with AIOFile("/tmp/hello.txt", 'w') as afp:
        writer = Writer(afp)

        for i in range(10):
            await writer("%d Hello World\n" % i)

        await writer("Tail-less string")


    async with AIOFile("/tmp/hello.txt", 'r') as afp:
        async for line in LineReader(afp):
            print(line[:-1])


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

More examples

Useful examples with aiofile

Async CSV Dict Reader

import asyncio
import io
from csv import DictReader

from aiofile import AIOFile, LineReader


class AsyncDictReader:
    def __init__(self, afp, **kwargs):
        self.buffer = io.BytesIO()
        self.file_reader = LineReader(
            afp, line_sep=kwargs.pop('line_sep', '\n'),
            chunk_size=kwargs.pop('chunk_size', 4096),
            offset=kwargs.pop('offset', 0),
        )
        self.reader = DictReader(
            io.TextIOWrapper(
                self.buffer,
                encoding=kwargs.pop('encoding', 'utf-8'),
                errors=kwargs.pop('errors', 'replace'),
            ), **kwargs,
        )
        self.line_num = 0

    def __aiter__(self):
        return self

    async def __anext__(self):
        if self.line_num == 0:
            header = await self.file_reader.readline()
            self.buffer.write(header)

        line = await self.file_reader.readline()

        if not line:
            raise StopAsyncIteration

        self.buffer.write(line)
        self.buffer.seek(0)

        try:
            result = next(self.reader)
        except StopIteration as e:
            raise StopAsyncIteration from e

        self.buffer.seek(0)
        self.buffer.truncate(0)
        self.line_num = self.reader.line_num

        return result


async def main():
    async with AIOFile('sample.csv', 'rb') as afp:
        async for item in AsyncDictReader(afp, line_sep='\r'):
            print(item)


loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)


try:
    loop.run_until_complete(main())
finally:
    # Shutting down and closing file descriptors after interrupt
    loop.run_until_complete(loop.shutdown_asyncgens())
    loop.close()

Metadata

Release files for aiofile 3.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aiofile 3.3.1
File Size Uploaded
aiofile-3.3.1.tar.gz 11.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aiofile 3.3.1
File Interpreter ABI Platform
aiofile-3.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 28.3 kB

Release files / aiofile-3.3.1.tar.gz

Download URL aiofile-3.3.1.tar.gz
Size 11.3 kB
Tags Source
SHA-256 checksum
How to use checksums
67990f7b7afc31d588ae3a56e1f90df23c9dc18e7e9a46552598f43378ce647a
BLAKE2b-256 checksum
How to use checksums
ca26674613f4cd115f38f3cab155b435306400f147d47c8fc796516cab4595cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.45.0 CPython/3.8.3

Release files / aiofile-3.3.1-py3-none-any.whl

Download URL aiofile-3.3.1-py3-none-any.whl
Size 17.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2d1e05ee752fd46971df7dcb32cca37c2053c666149b104500770c514dcdf6ee
BLAKE2b-256 checksum
How to use checksums
e927ea5d84f7712ae3cb14b9a0864a0f8229e9029f4ec379eb066f5e5a861117
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.45.0 CPython/3.8.3

Release history Release notifications | RSS feed

3.11.1

2 release files

3.11.0

2 release files

3.10.2

2 release files

3.10.1

2 release files

3.10.0

2 release files

3.9.0

2 release files

3.8.8

2 release files

3.8.7

2 release files

3.8.6

2 release files

3.8.5

2 release files

3.8.4

2 release files

3.8.3

2 release files

3.8.2

1 release file

3.8.1

1 release file

3.8.0

1 release file

3.7.4

2 release files

3.7.3

2 release files

3.7.2

2 release files

3.7.1

2 release files

3.7.0

2 release files

3.6.0

2 release files

3.5.1

1 release file

3.5.0

2 release files

3.4.0

2 release files

3.3.3

2 release files

This release

3.3.1 This release

2 release files

3.3.0

2 release files

3.2.1

2 release files

3.2.0

2 release files

3.1.1

2 release files

3.1.0

2 release files

3.0.0

2 release files

2.0.4

2 release files

2.0.3

2 release files

2.0.2

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.5.2

7 release files

1.5.1

8 release files

1.4.3

8 release files

1.4.2

7 release files

1.4.0

8 release files

1.3.0

7 release files

1.2.6

7 release files

1.2.5

7 release files

1.2.2

7 release files

1.2.1

7 release files

1.2.0

7 release files

0.5.3

7 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page