Skip to main content
One workspace, many storage engines, one place to ask questions.

1. What a Workspace Owns

A HeavenBase workspace is the application boundary for a data application. It owns:
  • entity schemas you register
  • backend instances you connect
  • field-level storage placement
  • system rows for Catalog, MetaSchema, and other entities from the required system extension
  • CRUD, query, audit, repair, and MCP-facing access to the data inside the workspace
You usually create one workspace for one application, agent memory, demo, or tenant boundary. Inside that boundary, HeavenBase keeps one logical API even when fields live across different physical backends.
Think of the workspace as the place where “what the data means” and “where the data lives” meet.

2. Start with a Preset

For the first local run, use the debug preset. It needs no Docker services and gives you SQLite row storage plus in-memory vector and search backends.
import heavenbase as hb

ws = hb.HeavenBase("core-workspace", preset="debug")
print(ws.id)
Inspect the resolved preset from the CLI:
hb ws presets show debug
PresetBackendsWhen to use
debugSQLite main, in-memory vec, in-memory searchFirst-run demos, tests, and examples.
local-ltsPostgres main, LanceDB vec, Elasticsearch searchDurable local development with the repo service stack.
web-ltsManaged Postgres, pgvector, hosted searchShared or hosted deployments.
Start with preset="debug" until you need persistence or external services. The same entity and query code can move to a larger preset later.

3. Use Explicit Backends When Placement Matters

Presets are the shortest path, but explicit backend maps are useful when you want a custom test layout or you are documenting a deployment shape.
ws = hb.HeavenBase(
    "core-explicit-workspace",
    backends={
        "main": {"type": "inmem"},
        "vec": {"type": "inmem"},
    },
)

print(ws.backends.names())
Backend keys are workspace-local names. Backend type values choose the provider family, such as sqlite, postgres, inmem, lance, elasticsearch, json, or pickle.

4. Register, Write, and Read

Registration is explicit. Define an entity, register it in the workspace, then write rows through the workspace API.
class Note(hb.Entity):
    title = hb.field(hb.ShortText)
    body = hb.field(hb.LongText)


ws.register(Note)

note_id = ws.upsert(
    Note,
    {
        "name": "Routing note",
        "title": "Routing note",
        "body": "One logical row can move across backends.",
    },
)

row = ws.get(note_id, entity=Note)
print(row["title"])
Every row has one object_id. When you omit it and the row has a name, HeavenBase derives a stable ID from the entity schema and that name.

5. Inspect and Repair

Workspaces always register Catalog and MetaSchema system entities. Query them when an agent or developer needs to understand what is inside the workspace.
entity_rows = (
    ws.query(hb.MetaSchema)
    .where(hb.MetaSchema.kind == "entity")
    .select("subject_id", "name")
    .execute()
    .rows()
)

print([row["subject_id"] for row in entity_rows])
print(ws.audit()["catalog"]["ok"])
Use ws.audit() to check Catalog consistency. Use ws.repair() only when you intentionally want HeavenBase to rebuild missing or stale Catalog rows from authoritative entity rows.

Further Exploration

Related resources: