Skip to main content

One interface, multiple file formats — async nested storage with dot-path access and atomic writes

Project description

nestio

One interface, multiple file formats.

nestio gives you a single, consistent API for reading and writing nested data — regardless of file format. Switch between JSON, TOML, YAML, TOON, or MessagePack without changing any of your logic. Just swap the class.


Installation

pip install nestio

Supported formats

Format Class File ext Best for
JSON JSON .json General purpose, APIs, configs
TOML TOML .toml Configuration files
YAML YAML .yaml Human-friendly configs
TOON TOON .toon LLM input — compact, token-efficient
MessagePack MSGPACK .msgpack Binary, fast, compact serialization

The idea

Every class shares the exact same five methods. Your logic never changes — only the format does:

# Works identically for JSON, TOML, YAML, TOON, or MSGPACK
await storage.set("user.settings.theme", "dark")
await storage.get("user.settings.theme")
await storage.append("user.scores", 42)
await storage.update("user.settings", {"language": "en"})
await storage.delete("user.settings.theme")

Quickstart

JSON

import asyncio
from nestio.files import JSON

async def main():
    db = JSON("data/config.json")

    await db.set("user.name", "Alice")
    await db.set("user.settings.theme", "dark")
    await db.set("user.scores", [])

    name  = await db.get("user.name")            # "Alice"
    theme = await db.get("user.settings.theme")  # "dark"

    await db.append("user.scores", 42)
    await db.update("user.settings", {"language": "en"})
    await db.delete("user.settings.theme")

asyncio.run(main())

TOML

import asyncio
from nestio.files import TOML

async def main():
    cfg = TOML("data/config.toml")

    await cfg.set("server.host", "localhost")
    await cfg.set("server.port", 8080)
    await cfg.update("server", {"debug": True})

    host = await cfg.get("server.host")  # "localhost"

asyncio.run(main())

YAML

import asyncio
from nestio.files import YAML

async def main():
    cfg = YAML("data/config.yaml")

    await cfg.set("server.host", "localhost")
    await cfg.set("tags", ["web", "api"])
    await cfg.append("tags", "async")

    tags = await cfg.get("tags")  # ["web", "api", "async"]

asyncio.run(main())

TOON

TOON (Token-Oriented Object Notation) is a compact format designed for LLM input — YAML-style nesting, CSV-style rows for uniform arrays, up to 40% fewer tokens than JSON.

import asyncio
from nestio.files import TOON

async def main():
    store = TOON("data/context.toon")

    await store.set("context.task", "Our favorite hikes")
    await store.set("friends", ["ana", "luis", "sam"])
    await store.update("context", {"season": "spring_2025"})

    task = await store.get("context.task")  # "Our favorite hikes"

asyncio.run(main())

A .toon file produced by nestio looks like this:

context:
  task: Our favorite hikes
  season: spring_2025
friends[3]: ana,luis,sam
hikes[3]{id,name,distanceKm,wasSunny}:
  1,Blue Lake Trail,7.5,true
  2,Ridge Overlook,9.2,false
  3,Wildflower Loop,5.1,true

MessagePack

MessagePack is a binary format — smaller and faster to read/write than text-based formats, great for local caches and high-frequency storage.

import asyncio
from nestio.files import MSGPACK

async def main():
    cache = MSGPACK("data/cache.msgpack")

    await cache.set("session.user_id", 1234)
    await cache.set("session.token", "abc123")
    await cache.set("session.permissions", ["read", "write"])

    user_id = await cache.get("session.user_id")  # 1234

    await cache.append("session.permissions", "admin")
    await cache.delete("session.token")

asyncio.run(main())

API

All five methods work the same across every format. All are async and must be awaited.

Import from the submodule or top level — both work:

from nestio.files import JSON   # explicit
from nestio import JSON         # shortcut

get(path, default=None)

Returns the value at the dot-path, or default if it doesn't exist.

value = await db.get("server.host", default="localhost")

set(path, value)

Sets the value at the dot-path. Creates intermediate dicts as needed.

await db.set("server.port", 8080)

delete(path)

Removes the key at the dot-path. Does nothing if the key doesn't exist.

await db.delete("server.port")

append(path, value)

Appends a value to a list at the dot-path. Creates the list if it doesn't exist yet.

await db.append("logs", {"level": "info", "msg": "started"})

update(path, new_data)

Deep-merges a dict into the value at the dot-path. Existing keys not in new_data are preserved.

await db.update("config", {"retries": 3, "timeout": 30})

How it works

  • Dot-path access — keys like "a.b.c" resolve through nested dicts automatically.
  • Atomic writes — every save writes to a temp file first, then uses os.replace() to swap it in. Your file is never half-written.
  • Per-key locking — concurrent writes to the same path are serialized with asyncio.Lock, while independent paths write in parallel. Locks clean up automatically after a TTL.

Requirements


License

MIT © MrBaconHat

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

nestio-0.2.1.tar.gz (10.0 kB view details)

Uploaded Source

Built Distribution

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

nestio-0.2.1-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file nestio-0.2.1.tar.gz.

File metadata

  • Download URL: nestio-0.2.1.tar.gz
  • Upload date:
  • Size: 10.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for nestio-0.2.1.tar.gz
Algorithm Hash digest
SHA256 0578ee1fb315cb9cbe9d3bd5d142045e67ed6d344ad7a0a3cc4f0d388dfbda79
MD5 27f1ac82c1c2541ee3314df9ec476f8d
BLAKE2b-256 4c0db93b517afc9455dfa0dbf86fc125cffdf064dc274718eb2132bf3a03200c

See more details on using hashes here.

File details

Details for the file nestio-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: nestio-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 10.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for nestio-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1d37ee8a762c2f0bbc5a5a24d1335216ede9b4b0b1bb59acc62c7c742ac65fcb
MD5 f32c54d95a7e4622709006706d9e570f
BLAKE2b-256 56321f8b6d2285a62b1199010663b6b15f04ec8566c73876d10167163815f0ec

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