terminusdb-pydantic
Pydantic v2 models for TerminusDB JSON-LD documents and TerminusDB schema generation.
The package lets application code keep ordinary Pydantic models as its Python data model while providing a small adapter layer for TerminusDB persistence:
Pydantic model
↕
TerminusDB JSON-LD document
↓
TerminusDB schema document
Status: early-stage / pre-1.0. The supported type mapping is intentionally small and explicit.
Project status: this is a community package and is not an official TerminusDB package.
Installation
With uv:
uv add terminusdb-pydantic
With pip:
python -m pip install terminusdb-pydantic
Python 3.11+ and Pydantic v2 are supported.
Quick start
Define a model:
from enum import Enum
from terminusdb_pydantic import LexicalKey, TerminusModel
class Level(str, Enum):
bachelor = "bachelor"
master = "master"
class Discipline(TerminusModel):
__terminus_key__ = LexicalKey("code")
code: str
name: str
description: str | None = None
level: Level
Serialize it to a TerminusDB JSON-LD document:
from terminusdb_pydantic import to_document
discipline = Discipline(
code="MATH-01",
name="Mathematical Analysis",
level=Level.bachelor,
)
document = to_document(
discipline,
document_id="Discipline/MATH-01",
)
assert document == {
"@type": "Discipline",
"@id": "Discipline/MATH-01",
"code": "MATH-01",
"name": "Mathematical Analysis",
"level": "bachelor",
}
Read a TerminusDB document back into Pydantic:
from terminusdb_pydantic import from_document
discipline = from_document(Discipline, document)
Pydantic validation is applied when the model is reconstructed.
Generate a TerminusDB schema
from terminusdb_pydantic import models_to_schema
schema_documents = models_to_schema([Discipline])
The returned value is ordinary Python data and can be inspected, versioned,
tested, or sent to TerminusDB using
terminusdb-async.
Key strategies
TerminusModel uses RandomKey() by default. The package also supports
lexical, hash, and value-hash keys:
from terminusdb_pydantic import HashKey, LexicalKey, ValueHashKey
__terminus_key__ = LexicalKey("code")
__terminus_key__ = LexicalKey("program_code", "discipline_code")
__terminus_key__ = HashKey("source", "target")
__terminus_key__ = ValueHashKey()
Supported type mapping
| Python / Pydantic annotation | TerminusDB schema |
|---|---|
str |
xsd:string |
int |
xsd:integer |
float |
xsd:double |
bool |
xsd:boolean |
| `T | None` |
list[T] / tuple[T, ...] |
List<T> |
set[T] |
Set<T> |
Enum |
TerminusDB Enum document |
| another Pydantic model | reference to that class |
Example:
class Course(TerminusModel):
title: str
tags: set[str]
prerequisites: list[str]
notes: str | None = None
Enums
Python enums are emitted once per generated schema:
from enum import Enum
class AssessmentType(str, Enum):
exam = "exam"
credit = "credit"
project = "project"
A field annotated with AssessmentType references the generated TerminusDB
enum.
JSON-LD conversion
to_document():
- uses Pydantic's JSON serialization mode;
- omits fields whose value is
None; - adds
@typefrom the model class name; - optionally adds
@id.
from_document():
- removes top-level JSON-LD metadata keys beginning with
@; - validates the remaining data with
model_validate().
This keeps persistence metadata separate from the application model.
Migration metadata
terminus_field() can attach TerminusDB-specific metadata to a Pydantic
field:
from terminusdb_pydantic import terminus_field
class Discipline(TerminusModel):
name: str = terminus_field(rename_from="title")
The rename_from value is stored in Pydantic field metadata for higher-level
migration tooling. It does not itself mutate a TerminusDB schema.
Current boundaries
The library is intentionally conservative in 0.1.x.
- It does not provide persistence or network access.
- It does not act as an ORM.
- It does not infer arbitrary Python types.
- Types outside the current mapping fall back to
xsd:string; inspect generated schemas before applying them to production databases. - Schema generation and data migration are separate concerns.
Use terminusdb-async for
network access and
terminusdb-migrations for
schema comparison and migration planning.
End-to-end example
from terminusdb_async import AsyncTerminusClient
from terminusdb_pydantic import (
LexicalKey,
TerminusModel,
models_to_schema,
to_document,
)
class Discipline(TerminusModel):
__terminus_key__ = LexicalKey("code")
code: str
name: str
async def save() -> None:
async with AsyncTerminusClient(
"http://localhost:6363",
organization="admin",
database="edtech",
username="admin",
password="root",
) as db:
await db.insert_schema_documents(
models_to_schema([Discipline]),
author="schema-bot",
message="Add Discipline schema",
)
value = Discipline(code="MATH-01", name="Mathematical Analysis")
await db.insert_documents(
to_document(value, document_id="Discipline/MATH-01"),
author="application",
message="Add Discipline",
)
Package family
| Package | Purpose |
|---|---|
terminusdb-async |
Async TerminusDB HTTP client |
terminusdb-pydantic |
Pydantic v2 ↔ JSON-LD and schema generation |
terminusdb-migrations |
Schema diff and migration planning |
Development
The project uses uv:
uv sync --group dev
uv run pytest -q
uv build --no-sources
CI tests Python 3.11, 3.12, and 3.13.
Development follows GitHub Flow on GitLab. Changes are made on short-lived
branches and merged into main through Merge Requests. See
CONTRIBUTING.md.
Versioning
The package is pre-1.0. A bounded dependency is recommended for consumers that want compatible updates:
terminusdb-pydantic = ">=0.1.1,<1.0.0"
Review release notes before upgrading across 0.x minor versions.
License
MIT License. See LICENSE for the full text.
Metadata
Release files for terminusdb-pydantic 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| terminusdb_pydantic-0.1.2.tar.gz | 6.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| terminusdb_pydantic-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.1 kB
Release files / terminusdb_pydantic-0.1.2.tar.gz
| Download URL | terminusdb_pydantic-0.1.2.tar.gz |
|---|---|
| Size | 6.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
958fd2dbfd1f0f2e4bcaf6e2bdb256e96cc4daa9fec7908296643e3ae6078107
|
|
BLAKE2b-256 checksum How to use checksums |
c5b616e4413ab3b909adefb138646d46b9fa0efd8918e38fc2c8e1377c331f0d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / terminusdb_pydantic-0.1.2-py3-none-any.whl
| Download URL | terminusdb_pydantic-0.1.2-py3-none-any.whl |
|---|---|
| Size | 7.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c0f869ec2964970246b38d7818ca7be506e0d315993eebe1b7a38d86a59a4841
|
|
BLAKE2b-256 checksum How to use checksums |
f1e8b352dbd4d9269f40879fe2668e92df615e5ba33419d252c06fbe9c3ff41a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|