Skip to main content

A small, persistent, dictionary-like JSON store for Python.

Project description

fuckreplitdb

A small, persistent, dictionary-like JSON store for Python. FuckReplitDB is intended for projects that outgrow Replit DB but still need a simple local key-value API rather than a database server.

Data is kept in memory and written to disk after every mutation. Nested dictionaries and lists remain live, so changing a value deep inside the structure is persisted automatically.

Features

  • Familiar MutableMapping interface
  • Automatic persistence for top-level and nested mutations
  • Atomic file replacement to avoid partially written JSON files
  • Thread-safe access within one FuckReplitDB instance
  • Auto-vivifying nested dictionaries, matching common Replit DB usage
  • Batched writes for efficient multi-step updates
  • Fast JSON encoding and decoding with orjson

Installation

python -m pip install fuckreplitdb

Python 3.8 or newer is required.

Quick start

from fuckreplitdb import FuckReplitDB

db = FuckReplitDB("data.json")

db["name"] = "Alice"
db.set("visits", 1)

print(db["name"])
print(db.get("missing", "fallback"))
print("visits" in db)

del db["visits"]

Every successful mutation is persisted before the operation returns.

Nested data

Dictionaries and lists are recursively wrapped when assigned or loaded. Their mutations are written automatically:

db["users"] = {
    "alice": {
        "roles": ["admin"],
        "settings": {"theme": "dark"},
    }
}

db["users"]["alice"]["roles"].append("editor")
db["users"]["alice"]["settings"]["theme"] = "light"

Missing keys accessed with brackets are created as nested dictionaries. This makes incremental construction concise:

db["users"]["bob"]["profile"]["display_name"] = "Bob"

Use get() when a read should not create a missing key:

profile = db.get("profile")

Nested lists support normal mutable-sequence operations, including assignment, deletion, append, extend, insert, pop, remove, clear, reverse, and sort.

Batch multiple updates

A normal mutation performs an atomic disk write immediately. When making several related changes, use batch() to serialize and write only once:

with db.batch():
    db["users"]["alice"]["visits"] = 12
    db["users"]["alice"]["roles"].append("moderator")
    db["last_updated_by"] = "worker-1"

Nested batch contexts are supported. The outermost context writes pending changes when it exits, including when the body raises an exception.

Mapping API

FuckReplitDB implements collections.abc.MutableMapping, including:

db[key] = value
db[key]
del db[key]
key in db
len(db)
iter(db)

db.get(key, default)
db.set(key, value)
db.setdefault(key, default)
db.update(values)
db.pop(key, default)
db.popitem()
db.clear()
db.keys()
db.values()
db.items()

set() is a convenience method that stores and returns the assigned value.

Storage behavior

  • The default path is database.json.
  • Parent directories are created when needed.
  • Files are encoded as indented, key-sorted JSON.
  • Writes go to a temporary file, are flushed to disk, and then atomically replace the destination.
  • A missing file starts as an empty database.
  • Invalid JSON raises orjson.JSONDecodeError instead of silently replacing existing data.
  • The JSON root must be an object; another root type raises ValueError.

Values must be serializable by orjson. In practice, use JSON-compatible strings, numbers, booleans, None, dictionaries, and lists. Dictionary keys are stored as strings.

Concurrency and limitations

Operations and nested mutations are protected by a reentrant lock. This prevents threads sharing the same database instance from interleaving writes.

The library does not coordinate separate FuckReplitDB instances or separate processes that point to the same file. For multi-process access, transactions, queries, very large datasets, or high write throughput, use SQLite or another database designed for those workloads.

The full in-memory store is serialized on each write outside a batch() block, so batching is recommended for bulk changes.

License

MIT

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

fuckreplitdb-2.1.0.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

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

fuckreplitdb-2.1.0-py3-none-any.whl (6.2 kB view details)

Uploaded Python 3

File details

Details for the file fuckreplitdb-2.1.0.tar.gz.

File metadata

  • Download URL: fuckreplitdb-2.1.0.tar.gz
  • Upload date:
  • Size: 6.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for fuckreplitdb-2.1.0.tar.gz
Algorithm Hash digest
SHA256 4ec87368c7f47317f6d9ea343c9c3d3e9a7ca402927007342c1afa2a616e8e2e
MD5 951e37e1a3a4d180ad1da990b0311caa
BLAKE2b-256 d76819ca6cdd6b87e1382110f31809a872df31d8938770164b2088e4af49d8b0

See more details on using hashes here.

File details

Details for the file fuckreplitdb-2.1.0-py3-none-any.whl.

File metadata

  • Download URL: fuckreplitdb-2.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for fuckreplitdb-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 be8caca212395ee3c269e68f60ff152e605ae0495fe3313d16f4fb5b1d99d247
MD5 c06c6f5fad193eeb1cc60c3387e1c841
BLAKE2b-256 71a3e2e5f110b2569dcab485a0175436988d1b3ff500254103b9c8a0be8d85cf

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