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.
Metadata
Release files for terminusdb-pydantic 0.1.1
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.1.tar.gz | 6.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| terminusdb_pydantic-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.3 kB
Release files / terminusdb_pydantic-0.1.1.tar.gz
| Download URL | terminusdb_pydantic-0.1.1.tar.gz |
|---|---|
| Size | 6.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bfb6955b2eb2f68417022e55eecedd0d32267f0ee333ac6474b59b267068aa8d
|
|
BLAKE2b-256 checksum How to use checksums |
517352f787cbaddd8b25dcbd152de026d990a6487fd0997bb561ce8a9350bf35
|
| 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.1-py3-none-any.whl
| Download URL | terminusdb_pydantic-0.1.1-py3-none-any.whl |
|---|---|
| Size | 6.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d2a37b0b7a4d388befc103778e96298112a3308e691c5692199c65c7f814dd4f
|
|
BLAKE2b-256 checksum How to use checksums |
a2a4874846781f8dc19835f4b28309d932df0945eca777eb4ea95116d49a1fc9
|
| 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}
|