mushroomdb (Python)
Python bindings for mushroomdb — the embedded graph database where edges are declared, not inserted.
import mushroomdb
db = mushroomdb.GraphDb.open("./db")
db.insert_node("Org", "org-01", {"founded_year": 2010})
GraphDb.open creates the directory if it does not exist. The handle is also a
context manager, so with mushroomdb.GraphDb.open("./db") as db: closes on exit.
Writing nodes
db.insert_node("Person", "alice", {"team": "red"}) # raises if 'alice' exists
db.upsert_node("Person", "alice", {"team": "blue"}) # "inserted" or "updated"
db.set_prop("alice", "team", "green")
db.set_prop("alice", "team", None) # same as remove_prop
db.remove_prop("alice", "team") # False if already absent
report = db.delete_node("alice") # {"manual_edges", "derived_edges"}
upsert_node writes only the fields you pass whose value differs from the
stored one. Fields you omit are left alone, and unchanged fields produce no WAL
record, so rules do not re-fire needlessly. An existing key under a different
label raises ValueError — relabelling is not an upsert.
Querying
query and query_write both accept parameters as a dict, as a list of
(name, value) tuples, or not at all. Parameters are bound, never interpolated
into the Cypher string.
rows = db.query(
"MATCH (n:Person) WHERE n.age > $min RETURN key(n) AS id",
{"min": 18},
)
db.query_write(
"MATCH (n:Person) WHERE key(n) = $k SET n.age = 31 RETURN key(n)",
{"k": "alice"},
)
n.key / n.id read the node key (a stored property of the same name wins).
key(n) / id(n) always return the id-map key. node_info returns the key too.
Vector search
Scores are cosine similarity in [-1, 1] (score >= min). A distance of
1 - sim is the caller's conversion. Brute find_similar is exact GEMM; HNSW
is still the approximate path; exact=True (and any where=) force GEMM.
hits = db.find_similar("embedding", query_vec, k=10, min=0.0, exact=True)
hits = db.find_similar(
"embedding",
query_vec,
label="Document",
where={"field": "status", "eq": "published"},
)
pairs = db.pairwise_similar(["a", "b", "c"], "embedding", k=5)
# exact per-key top-k among `keys`; self excluded; no HNSW
Degree
Adjacency is a set; degree is unique-neighbour count ("both" is out+in
sum). Distinct from degree_centrality and from Degree views.
db.degree("alice", direction="both")
db.degrees(keys=["alice", "bob"], limit=10) # degree desc, key asc
Rules
db.create_rule({
"name": "same_team",
"src_label": "Person",
"dst_label": "Person",
"predicate": {"kind": "field_equal", "fields": ["team"]},
"edge_type": "SAME_TEAM",
"weight_prop": None,
})
The canonical predicate shape is snake_case — {"kind": ..., "fields": [...]}
plus whatever numeric knob the kind takes (min, tolerance, km, or parts
for all/any). This is exactly the shape explain emits, so an explanation
round-trips straight back into a new rule:
why = db.explain("alice", "bob")
clone = {**base, "name": "same_team_clone", "predicate": why[0]["predicate"]}
db.create_rule(clone)
| kind | extra keys |
|---|---|
key_match, field_equal |
— |
overlap, vector_similar |
min |
numeric_within |
tolerance |
geo_radius |
km |
all, any |
parts (a list of nested predicates) |
The Rust-native externally-tagged form is still accepted:
{"FieldEqual": {"field": "team"}}, {"Overlap": {"field": "skills", "min": 0.5}}.
create_rule returns True when it created the rule. Pass
if_not_exists=True to get False instead of an exception when a rule of that
name is already registered.
Concurrency
One writer at a time across processes; readers see commits after refresh().
The store carries an advisory write lock. A read-write handle holds it for as
long as it is open, so opening a second one anywhere on the machine raises
MushroomBusy rather than letting two writers corrupt the store:
from mushroomdb import GraphDb, MushroomBusy
try:
db = GraphDb.open("./db")
except MushroomBusy:
... # another process is writing; nothing was changed, retry later
A handle does not poll the store, so another process's commits stay invisible
until you ask for them. refresh() applies them in place and returns how many
arrived — no close() and reopen:
n = db.refresh() # rules fire and derived edges appear, as on a fresh open
Readers never take the lock. read_only=True opens immediately even while a
writer holds it, writes nothing to disk, raises RuntimeError on any mutation,
and can still refresh() to follow the writer:
reader = GraphDb.open("./db", read_only=True)
reader.refresh()
A commit another process is midway through writing is left alone and picked up
by the next refresh(); a partial write is never an error.
Within one process the handle is guarded by a mutex, so calls from multiple threads are serialized and safe. They are not isolated transactions: readers can observe intermediate states while a batch is being applied.
Type stubs
The wheel ships __init__.pyi and a py.typed marker, so mypy and Pyright
pick up signatures without extra configuration.
Full documentation, the rules tour, and benchmarks live in the main repository.
Metadata
Release files for mushroomdb 0.6.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mushroomdb-0.6.9-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| mushroomdb-0.6.9-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| mushroomdb-0.6.9-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 7.1 MB
Release files / mushroomdb-0.6.9-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | mushroomdb-0.6.9-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
62b0563b1ba61980107b7ba29a7d5d69f112260fc13c4035e0ec6ef9929e6047
|
|
BLAKE2b-256 checksum How to use checksums |
d9db8a9a5979578d089924e99e35969035ab96caa64e5e650b7283d8b57e7222
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.
Transparency logRelease files / mushroomdb-0.6.9-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | mushroomdb-0.6.9-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
6d2e29ce14b06a1f0d8c07a90427cf7b2d5e6d672d2d1944e0a493201366e1ba
|
|
BLAKE2b-256 checksum How to use checksums |
342bc7ab5ef11e9f9ca3f4639859e7376fd1603d613717a904eaf72e7d4a56ac
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.
Transparency logRelease files / mushroomdb-0.6.9-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | mushroomdb-0.6.9-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
d18440bfecfce5780e50675bf0d766e63fd8a481cda428faf73067451d45f614
|
|
BLAKE2b-256 checksum How to use checksums |
f72d7f5714ab6b0635ed08ff501d49b1bea33c76d86f452b50ef446ac183b889
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.
Transparency log