Skip to main content

asyncblobdict

Tests codecov

asyncblobdict is a minimal async‑friendly key–value store for JSON and binary data, backed by either:

  • Local filesystem
  • Azure Blob Storage

It lets you store and retrieve Python data by key, with optional caching and optimistic concurrency via ETags, and swap backends without changing your application code.


Features

  • Backends: Local filesystem or Azure Blob Storage
  • Data types:
    • JSON‑serializable (dict, list, set, datetime, etc.)
    • Arbitrary binary (bytes, bytearray)
  • Caching modes:
    • NONE — always read/write directly to backend
    • WRITE_THROUGH — cache and immediately write to backend
    • WRITE_BACK — cache and sync later
  • Concurrency modes:
    • NONE — no concurrency control
    • ETAG — optimistic concurrency using ETags
  • Serializer views:
    • store.json — JSON serializer view
    • store.binary — binary serializer view
    • store.default_view — default serializer view (format chosen at init)

Installation

From PyPI:

pip install asyncblobdict

For development (editable install):

git clone https://github.com/ViLahte/asyncblobdict.git
cd asyncblobdict
pip install -e .

Quick Start

Local backend example

import asyncio
import pickle
from datetime import datetime
from asyncblobdict import AsyncBlobStore, CacheMode, ConcurrencyMode, LocalFileAdapter

async def main():
    adapter = LocalFileAdapter("./local_blob_storage")
    async with AsyncBlobStore(
        adapter,
        "demo_container",
        cache_mode=CacheMode.WRITE_THROUGH,
        concurrency_mode=ConcurrencyMode.ETAG,
        default_format="json",  # default view is JSON
    ) as store:
        # Store JSON (default view)
        await store.set("demo/config", {"learning_rate": 0.01, "created_at": datetime.utcnow()})

        # Retrieve JSON
        print(await store.get("demo/config"))

        # Store binary explicitly
        model_bytes = pickle.dumps({"weights": [0.1, 0.2, 0.3], "bias": 0.5})
        await store.binary.set("demo/model.bin", model_bytes)

        # Retrieve binary
        print(await store.binary.get("demo/model.bin"))

        # List keys
        print(await store.list_keys())

        # Delete a key
        await store.delete("demo/config")

if __name__ == "__main__":
    asyncio.run(main())

API Reference (Simplified)

All methods are async.

Default view (format chosen at init)

await store.set(key: str, value: Any)
await store.get(key: str) -> Any
await store.delete(key: str)

Format-specific views

await store.json.set(key, value)     # JSON serializer
await store.json.get(key)            # returns Python object
await store.binary.set(key, bytes)   # Binary serializer
await store.binary.get(key)          # returns bytes

Other methods

await store.list_keys(prefix: str = "") -> list[str]
await store.sync(etag_behavior="skip")  # flush WRITE_BACK cache

Adding Your Own Serializer

You can add new formats (e.g., YAML) by passing a serializers dict to AsyncBlobStore.

import yaml

from asyncblobdict import (
    AsyncBlobStore,
    BinarySerializer,
    JSONSerializer,
    LocalFileAdapter,
    Serializer,
)


class YAMLSerializer(Serializer):
    def serialize(self, value):
        return yaml.dump(value).encode("utf-8")

    def deserialize(self, raw: bytes):
        return yaml.safe_load(raw.decode("utf-8"))

    def name_strategy(self, key: str) -> str:
        return f"{key}.yaml"


LOCAL_BASE_PATH = "./local_blob_storage"
LOCAL_CONTAINER = "test_container"

serializers = {
    "json": JSONSerializer(),
    "binary": BinarySerializer(),
    "yaml": YAMLSerializer(),
}


adapter = LocalFileAdapter(LOCAL_BASE_PATH)
container_name = LOCAL_CONTAINER

store = AsyncBlobStore(
    adapter,
    container_name,
    serializers=serializers,
    default_format="json",
)

# Now you can use:
await store.yaml.set("config", {"a": 1})
print(await store.yaml.get("config"))

Syncing in WRITE_BACK mode

When using CacheMode.WRITE_BACK, changes are cached locally until you call:

await store.sync(etag_behavior="skip")  # options: "skip", "overwrite", "raise"

Testing

We use pytest:

pytest

Azure tests are skipped automatically if environment variables are not set.

Run only local tests:

pytest -m "not azure"

Run only Azure tests:

pytest -m azure

For code coverage HTML report:

pytest --cov=src --cov-report=html

License

MIT License

Metadata

Release files for asyncblobdict 0.1.133

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

Source distribution (sdist)

Source distribution for asyncblobdict 0.1.133
File Size Uploaded Provenance
asyncblobdict-0.1.133.tar.gz 13.4 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 27.6 kB

Release files / asyncblobdict-0.1.133.tar.gz

Download URL asyncblobdict-0.1.133.tar.gz
Size 13.4 kB
Tags Source
SHA-256 checksum
How to use checksums
b0da4fba19916638b1960243ab2a773d0a2af119f22c79adb71616ad41db1f23
BLAKE2b-256 checksum
How to use checksums
3ed772e0a695a2d1d72dc57fc096df54fc5e2ca29bc023034fd756b67ffdd49d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.0

Release files / asyncblobdict-0.1.133-py3-none-any.whl

Download URL asyncblobdict-0.1.133-py3-none-any.whl
Size 14.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b4bb23f1d2a57fc829260a5d5972d5807db21a9df9c6c2e95b9d33a2a76d10da
BLAKE2b-256 checksum
How to use checksums
15ae5b46f98e686cae59660a5a31f3b3c6ceb0d590ab891b243e87d28bc439a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.0

Security for asyncblobdict 0.1.133

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

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