Skip to main content

DataLoader implementation for Python asyncio

Project description

dloader

A Python implementation of the DataLoader pattern for data fetching with automatic batching.

Installation

uv add dloader
# or
pip install dloader

Quick Start

import asyncio
from dloader import DataLoader

# Define a batch loading function
async def batch_load_users(user_ids):
    # Fetch multiple users at once (e.g., from a database)
    users = await db_client.get_many(User, user_ids)
    return users

# Create a DataLoader instance
async with DataLoader(batch_load_users) as user_loader:
    # These calls are automatically batched
    user_1, user_2, other_users = await asyncio.gather(
        user_loader.load(1),
        user_loader.load(2),
        user_loader.load_many([3, 4, 5]),
    )

How It Works

When you call load() or load_many(), the DataLoader doesn't immediately execute the load function. Instead, it schedules a task for the next event loop iteration, collects keys, and returns a Future immediately. If other load calls are made while the task is pending, their keys are collected and batched together. This works best when load calls are made in parallel through asyncio.gather() or tasks.

API Reference

DataLoader

DataLoader[K, V](
    load_fn: LoadFunction[K, V],
    max_batch_size: int | None = None,
    cache: bool = True,
    loop: asyncio.AbstractEventLoop | None = None,
    cache_map: MutableMapping[K, V] | None = None,
)

Parameters

  • load_fn: Async callable that accepts a sequence of keys and returns results in the same order. Results can be values or Exception instances.
  • max_batch_size: Maximum number of keys per batch. Default is None (unlimited).
  • cache: Whether to cache successful results. Default is True.
  • loop: Event loop to use. Only needed when calling load() outside an async context.
  • cache_map: Custom cache storage to use. If not provided, a plain dict will be used.

Methods

load(key: K) -> Future[V]

Load a single value by its key. Returns a Future that resolves to the value.

load_many(keys: Iterable[K]) -> Future[list[V]]

Load multiple values. Returns a Future that resolves to a list of values.

clear(key: K) -> None

Remove a single key from the cache.

clear_many(keys: Iterable[K]) -> None

Remove multiple keys from the cache.

clear_all() -> None

Clear the entire cache.

prime(key: K, value: V) -> None

Pre-populate the cache with a key-value pair.

prime_many(data: Mapping[K, V]) -> None

Pre-populate the cache with multiple key-value pairs.

shutdown() -> ExceptionGroup | None

Clean up all pending operations. Called automatically when using as a context manager.

LoadFunction Protocol

The load function must follow this protocol:

class LoadFunction(Protocol, Generic[K, V]):
    async def __call__(self, keys: Sequence[K], /) -> Sequence[V | Exception]: ...

# This is equivalent to:
async def load_fn(keys: Sequence[K]) -> Sequence[V | Exception]:
    ...

This callable will receive a sequence of keys and has to return a sequence of results. The sequence of results has to be the same length as the keys and results have to be in the same order as keys, i.e., a result in the position X corresponds to a key in the position X. A result can also be an instance of Exception in which case it will be set as an exception on the respective future, which will raise that exception when the future is awaited on.

Best Practices

  • Use as context manager to guarantee all tasks and futures are correctly cleaned up. Alternatively, make sure to call shutdown() when you're done with the dataloader.
  • Use asyncio.gather() or other asyncio concurrency patterns, like strawberry's async GraphQL resolvers.

License

MIT License - see LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dloader-0.1.1.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dloader-0.1.1-py3-none-any.whl (6.7 kB view details)

Uploaded Python 3

File details

Details for the file dloader-0.1.1.tar.gz.

File metadata

  • Download URL: dloader-0.1.1.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.7.19

File hashes

Hashes for dloader-0.1.1.tar.gz
Algorithm Hash digest
SHA256 91886b8ae497c9569a129a4e3343ff4d97cd2b2a16f3dbb82c9a492530fb77b3
MD5 d0ad4730e6d6fdc0ccc8fa1a6611aebf
BLAKE2b-256 f0607eb24d7ea0ff43800371340faebfe27d7ce48df457661382b136f29510d0

See more details on using hashes here.

File details

Details for the file dloader-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: dloader-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 6.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.7.19

File hashes

Hashes for dloader-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ceecb3cca55765ab4136eecda8c43b52fbaf2af5e01141d9ff754051903adbc2
MD5 a7effd20dd753b07c71c3ac0ddc49d56
BLAKE2b-256 69ebbea717444c6f665f33f6d044d743281fb6523805cbec18467153dbe031ac

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page