Skip to main content

AxisDB

AxisDB is a tiny embedded document database for Python, designed for simple, reliable storage of JSON documents addressed by N-dimensional coordinate keys.

It is library-first, requires no server and stores all data in a single JSON file with atomic, crash-safe commits.

AxisDB

See also:
USE_CASES.md: a concise overview of practical applications and patterns enabled by this multidimensional JSON storage model.
ARCHITECTURE.md: the engine, the storage format and the locking model.
TECH_DEBT.md: what is still open, what is deliberately left and what only looks like debt.

MIT licensed. AxisDB is free and open source under the MIT licence, so it can be imported into closed-source and commercial code with no further agreement. Releases up to and including 1.0.6 were published under GPL-3.0 and stay under it.


Key properties

  • Library-first design (usable without any server)
  • Single-file JSON storage
  • Atomic, crash-safe commits via temp-file replace
  • Safe multi-process access (single writer, multiple readers) via file locks
  • Minimal but useful query + indexing support (correctness-first)

Features

  • Embedded JSON document database
  • N-dimensional coordinate keys
  • Atomic commit and recovery
  • Key listing (list) and multidimensional slicing (slice)
  • Basic querying (find) with optional persisted field indexes
  • Optional FastAPI wrapper with Swagger (/docs) and ReDoc (/redoc)

Installation

Core library

pip install axisdb

Optional server components

pip install "axisdb[server]"

Basic library usage

Create a database, write a value and commit:

from axisdb import AxisDB

db = AxisDB.create("./mydb.json", dimensions=2)
db.set(("user1", "orders"), {"count": 3})
db.commit()

ro = AxisDB.open("./mydb.json", mode="r")
print(ro.get(("user1", "orders")))

Notes:

  • Dimensions are fixed at database creation time; all keys must be a tuple[str, ...] of that length.
  • Values must be JSON-serializable (validated by default on set).
  • mode="rw" writes are staged in-memory until commit(); rollback() discards uncommitted changes.
  • mode="r" reloads from disk on each operation to reflect the latest committed state.

Query and indexing (MVP)

AxisDB is optimized for correctness and predictable behavior over complex query planning.

  • Indexes are materialized and persisted in the DB file.
  • Indexes are rebuilt on each commit (correctness-first MVP).
  • find() can use indexes only when there are no pending writes in the current session.

Index types

  • Prefix index: always maintained; used by find(prefix=...) to reduce scan work (note: list(prefix=...) currently filters materialized keys directly).
  • Field indexes: optional, user-defined; can accelerate simple equality predicates of the form Field(("path", "to", "field"), "==", literal).

Define a field index:

from axisdb import AxisDB

db = AxisDB.create("./mydb.json", dimensions=2)
db.define_field_index("by_customer_id", ("customer_id",))

Query with an expression:

from axisdb import AxisDB
from axisdb.query.ast import Field

db = AxisDB.open("./mydb.json", mode="r")
rows = db.find(prefix=("orders",), where=Field(("customer_id",), "==", "c2"))

Running the FastAPI wrapper (optional)

After installing the server extras:

pip install "axisdb[server]"

Run the server:

python -m uvicorn axisdb.server.app:app --reload

The server will start at:

http://localhost:8000

API documentation

FastAPI automatically exposes interactive documentation:

  • Swagger UI: http://localhost:8000/docs
  • ReDoc: http://localhost:8000/redoc

REST endpoints (thin wrapper)

The server is intentionally a minimal translation layer over the library:

  • GET /info?path=...
  • POST /init?path=...&dimensions=...&overwrite=false
  • POST /item?path=... (body: { "coords": [...], "value": ... })
  • GET /item?path=...&coords=...&coords=...
  • DELETE /item?path=... (body: { "coords": [...] })
  • GET /list?path=...&prefix=...&depth=...
  • GET /find?path=...&prefix=...&field=...&op===&value=...&limit=...

The wrapper does not bypass durability or locking: it opens the database in mode="r" or mode="rw" as needed and uses the same commit semantics.


Concurrency model (locking)

By default (lock=True), AxisDB uses two lock files next to the database file:

  • *.writer.lock: exclusive lock held for the lifetime of a writer session (mode="rw")
  • *.rw.lock: shared during reads; exclusive during commit()

This supports single-writer / multiple-reader access across processes.


Versioning and compatibility

This project follows semantic versioning.

Guaranteed stable within a major version:

  • Public AxisDB API: open, create, get, set, delete, exists, list, slice, find, commit, rollback
  • Public exception types in axisdb.errors
  • On-disk file format (format=axisdb, format_version=2)

May change in minor versions:

  • Internal module structure and private attributes
  • Index query planning details

Breaking changes will only occur in the next major version.


Development

Run tests:

python -m pytest -q

Supporting the project

AxisDB is free and stays free. There is no paid tier, no licence key and no feature held back behind a donation. If it has saved you time or simply been useful, a donation supports its maintenance and continued development.

Donate to AxisDB


Licence

MIT. See LICENSE.

AxisDB moved from GPL-3.0 to MIT after 1.0.6, a deliberate choice for adoption. A library is only useful to the teams that are allowed to import it; a GPL library is off limits to most commercial Python codebases. Its dependencies (portalocker, plus fastapi and uvicorn behind the server extra) are all under permissive licences, so nothing it pulls in contradicts the change. Releases up to and including 1.0.6 remain under GPL-3.0.

Metadata

Release files for axisdb 1.1.0

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

Source distribution (sdist)

Source distribution for axisdb 1.1.0
File Size Uploaded Provenance
axisdb-1.1.0.tar.gz 22.0 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 42.7 kB

Release files / axisdb-1.1.0.tar.gz

Download URL axisdb-1.1.0.tar.gz
Size 22.0 kB
Tags Source
SHA-256 checksum
How to use checksums
5be7e6aeea279326a0a6c99ac21783efb482a9e399bd7c2bd63f2d4ef20d308e
BLAKE2b-256 checksum
How to use checksums
85e8bc759b9050d5664f8680f67a90fecb23dc92caaeab1c3b928a27d632c86d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.11

Release files / axisdb-1.1.0-py3-none-any.whl

Download URL axisdb-1.1.0-py3-none-any.whl
Size 20.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f032577ced5367ff34706bf3e2d327f0f5924d303d813232d93b077c2cb663fa
BLAKE2b-256 checksum
How to use checksums
f97a9c56a7f82b1e106e52d064bc65b2b392846165cff06e3ebabfeac97f8387
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.11

Security for axisdb 1.1.0

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