Skip to main content

TapDB
Typed objects, immutable Meridian EUIDs, lineage, audit, and discoverable DAG surfaces for Python services.

CI PyPI Python versions

Operate · Embed · Discover · Model · Recover

Why TapDB

TapDB is a reusable persistence substrate for services that need typed, versioned objects with stable identifiers and authoritative relationships. It provides templates, generic instances, immutable EUIDs, lineage, audit history, transactional messaging records, and authenticated embeddable web surfaces.

TapDB is not an untyped graph database, workflow engine, or domain application. The owning service defines business meaning and access policy. Relationships belong in generic_instance_lineage; metadata may support display and search, but never becomes the relationship authority.

Install

TapDB 9.2 requires Python 3.12 or newer and PostgreSQL 17 for the supported release path.

python -m pip install "daylily-tapdb[cli,admin,gui]"

TapDB pins meridian-euid==0.4.8. Consumers must not replace that pin with an unverified range or synthesize strings that resemble Meridian EUIDs.

Quick start

From a source checkout:

source ./activate
tapdb --help
tapdb --config <path> ...
tapdb --config <path> bootstrap local --no-gui
tapdb --config <path> --json info

Every stateful command takes one explicit config path. There is no environment selector, ambient database discovery, or implicit fallback target. Config initialization records the client, logical database, physical database, schema, Meridian domain, prefix registry, and owner repository in one file.

Runnable examples live in the repository:

The public Meridian registry is maintained by lsmc-bio/meridian-registry. For example, validate domain Q with:

meridian-euid domain-check Q \
  --registry-index /abs/path/to/meridian-registry/registry/generated/domains.json

Domain registration does not grant a prefix claim. The explicit TapDB prefix ownership registry remains authoritative for prefixes.

Object model

TapDB stores four primary kinds of durable facts:

Fact Authority
Object shape and version generic_template
Persisted typed object generic_instance
Object-to-object relationship generic_instance_lineage
Actor-attributed change evidence audit_log

All runtime PostgreSQL access installs schema, config identity, domain, owner, tenant, actor, and global-row policy together inside the transaction. Row-level security is forced on protected tables. Runtime roles with SUPERUSER or BYPASSRLS are rejected; schema operators must opt into the distinct migration connection role.

Bundled templates

The core pack contains exactly nine substrate templates:

Category / type / subtype Purpose
actor/user/system Optional bundled GUI/auth user actor; not a universal business primitive
set/generic/generic Generic set
governance/validator/definition Validator definition
governance/terminology/set Terminology set
governance/relationship/constraint Lineage constraint
governance/position/scheme Position scheme
evidence/repair/record Explicit repair evidence
reference/external_identifier/tapdb_object Typed external object reference
message/webhook/event Transactional webhook event

Application-specific templates belong in the consuming repository and are loaded explicitly. Core and consumer packs cannot silently override one another.

The database operator materializes the exact installed core definitions inside each configured owner scope, allowing that owner's constrained runtime to use typed XRF/SYS/MSG objects without owning TapDB's reserved prefixes. A copied path or modified client-authored template cannot unlock reserved-prefix seeding.

Python API

Use the factory inside a caller-owned transaction. Natural identity claims are atomic and distinguish a new object from an idempotent replay:

from daylily_tapdb import InstanceFactory, TAPDBConnection, TemplateManager

manager = TemplateManager()
factory = InstanceFactory(manager, domain_code=domain_code)

with connection.session_scope(commit=True) as session:
    claim = factory.claim_instance_by_identity(
        session,
        template_code="message/webhook/event/1.0/",
        identity_key=event_identity_key,
        name="Webhook event",
        properties=event_properties,
        command_evidence={"source": "consumer"},
    )
    persisted_euid = claim.instance.euid

Any replay of the same identity key returns EXISTING and the stored winner; TapDB does not compare consumer payload fingerprints. A race-safe consumer such as Dewey first claims or reads the committed stored winner, then compares its client-owned fingerprint and returns its own divergent-payload 409 without creating a second receipt. The claim API requires an already-active transaction and never commits or rolls back its caller's transaction.

Discoverable DAG v2

Hosts mount the authenticated v2 contract atomically. A failed mount publishes no advertisement and registers no partial routes:

from fastapi import FastAPI

from daylily_tapdb.web import DagV2Limits, mount_tapdb_dag_surfaces

app = FastAPI()
result = mount_tapdb_dag_surfaces(
    app,
    config_path="/abs/path/to/tapdb-config.yaml",
    service_id="catalog-api",
    display_name="Catalog API",
    auth_dependency=require_service_or_user,
    limits=DagV2Limits(
        max_depth=6,
        max_nodes=500,
        max_search_page_size=100,
    ),
)
if not result.mounted:
    raise RuntimeError(f"DAG v2 unavailable: {result.reason}: {result.diagnostic}")

The mount exposes:

  • GET /api/dag/manifest
  • GET /api/dag/v2/object/{euid} for exact ownership lookup
  • GET /api/dag/v2/data for bounded native traversal
  • GET /api/dag/v2/search for bounded opaque-cursor discovery

Every route requires auth. The immutable service_id must exactly match fleet registration. Search results are discovery candidates, not ownership proof; consumers confirm ownership with exact lookup. Graph responses include a revision, snapshot time, presentation metadata, effective limits, and explicit truncation. DAG v2 projects only outbound typed references backed by a persisted external-reference object plus lineage, and it never fetches a remote v2 service on the caller's behalf.

See the runnable request flow, eligibility reasons, adoption checklist, and anti-patterns in the consumer discoverability guide.

Web and GUI embedding

create_tapdb_gui_app(...) mounts the host-authenticated HTML/JSON object surface at /tapdb. TapdbHostBridge supplies host identity, navigation, and styling without giving TapDB authority over application policy. The older v1 DAG router remains a separate, explicitly authenticated compatibility surface; its outbound proxy is disabled unless an operator supplies an exact HTTPS DNS allowlist, timeout, and response-size policy. It never forwards credentials. Mount it only by passing the host's callable authentication dependency:

legacy_router = create_tapdb_dag_router(
    config_path="/abs/path/to/tapdb-config.yaml",
    auth_dependency=require_service_or_user,
)
app.include_router(legacy_router)

The router rejects a missing or non-callable dependency at construction time; the dependency must reject anonymous requests with 401 or 403.

Development and release checks

python -m pytest tests/ -q
ruff check daylily_tapdb admin tests
ruff format --check daylily_tapdb admin tests
mypy
bandit -c pyproject.toml -r daylily_tapdb admin
python -m build

Release CI runs the complete suite against PostgreSQL 17, including local-doc examples, branch coverage, Ruff, mypy, Bandit, detect-secrets, wheel build, and installed-wheel smoke checks. It does not hide integration tests with deselects. The mypy file list in pyproject.toml covers every new 9.2 implementation module; older dynamically mapped ORM and Typer modules are not yet globally strict-clean.

Documentation

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

daylily_tapdb-9.2.0.tar.gz (1.1 MB view details)

Uploaded Source

Built Distribution

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

daylily_tapdb-9.2.0-py3-none-any.whl (574.4 kB view details)

Uploaded Python 3

File details

Details for the file daylily_tapdb-9.2.0.tar.gz.

File metadata

  • Download URL: daylily_tapdb-9.2.0.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for daylily_tapdb-9.2.0.tar.gz
Algorithm Hash digest
SHA256 1636bdad6ce86ff48dee42ca8f83335be1a42dd1c886c4aff07942ca978e4036
MD5 7fc635b5fe4cfa8dcbfb4b39ca80e32d
BLAKE2b-256 b56df3a1dbfb080f1f07659253d60e01897c73f60293633ea127a3256095ee94

See more details on using hashes here.

File details

Details for the file daylily_tapdb-9.2.0-py3-none-any.whl.

File metadata

  • Download URL: daylily_tapdb-9.2.0-py3-none-any.whl
  • Upload date:
  • Size: 574.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for daylily_tapdb-9.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 29c0b5f5f44d6bc2aaab403d64164c2d5132dea77c2168c502888c48884cd901
MD5 9dc821d6a37b8ead5e502a8739b8abc6
BLAKE2b-256 9016a5e0c7f034dcf699e019f506323564fd4977418ff4f408f51d514259ec77

See more details on using hashes here.

Release history Release notifications | RSS feed

10.1.5

2 files

10.1.4

2 files

10.1.3

2 files

10.1.2

2 files

10.1.1

2 files

10.1.0

2 files

10.0.0

2 files

9.2.2

2 files

9.2.1

2 files

This release

9.2.0 This release

2 files

9.0.10

2 files

9.0.9

2 files

9.0.0

2 files

8.0.6

2 files

8.0.5

2 files

8.0.2

2 files

8.0.1

2 files

8.0.0

2 files

7.0.12

2 files

7.0.11

2 files

7.0.9

2 files

7.0.8

2 files

7.0.7

2 files

7.0.5

2 files

7.0.4

2 files

7.0.3

2 files

7.0.2

2 files

7.0.1

2 files

7.0.0

2 files

6.0.13

2 files

6.0.12

2 files

6.0.11

2 files

6.0.9

2 files

6.0.8

2 files

6.0.7

2 files

6.0.5

2 files

6.0.4

2 files

6.0.3

2 files

6.0.2

2 files

6.0.1

2 files

6.0.0

2 files

5.1.0

2 files

5.0.4

2 files

5.0.3

2 files

5.0.2

2 files

5.0.0

2 files

4.1.4

2 files

4.1.3

2 files

4.1.2

2 files

4.1.1

2 files

4.1.0

2 files

4.0.11

2 files

4.0.10

2 files

4.0.9

2 files

4.0.7

2 files

4.0.6

2 files

4.0.5

2 files

4.0.4

2 files

4.0.3

2 files

4.0.2

2 files

4.0.0

2 files

3.2.5

2 files

3.2.4

2 files

3.2.3

2 files

3.2.2

2 files

3.2.1

2 files

3.2.0

2 files

3.1.0

2 files

3.0.12

2 files

3.0.11

2 files

3.0.10

2 files

3.0.9

2 files

3.0.8

2 files

3.0.7

2 files

3.0.6

2 files

3.0.5

2 files

3.0.4

2 files

3.0.3

2 files

3.0.2

2 files

3.0.1

2 files

0.2.7

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.1.39

2 files

0.1.38

2 files

0.1.37

2 files

0.1.35

2 files

0.1.33

2 files

0.1.32

2 files

0.1.30

2 files

0.1.29

2 files

0.1.28

2 files

0.1.27

2 files

0.1.26

2 files

0.1.25

2 files

0.1.24

2 files

0.1.23

2 files

0.1.22

2 files

0.1.21

2 files

0.1.19

2 files

0.1.17

2 files

0.1.16

2 files

0.1.15

2 files

0.1.13

2 files

0.1.12

2 files

0.1.11

2 files

0.1.9

2 files

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