API Reference¶
Everything below is generated from the source at build time with mkdocstrings + Griffe. It reflects the exact installed version — there is no hand-maintained copy to fall out of date.
Ledger¶
The one object you'll use most. Every method is tool-shaped — usable directly, over REST, or as an MCP tool.
The main entry point for model-ledger.
Every public method is designed to work as an agent tool call: clear inputs, JSON-serializable outputs, no side effects beyond the ledger.
Source code in src/model_ledger/sdk/ledger.py
from_sqlite
classmethod
¶
from_sqlite(db_path: str) -> Ledger
Create a Ledger backed by a SQLite database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
db_path
|
str
|
Path to the SQLite database file. Created if it doesn't exist. |
required |
Example
ledger = Ledger.from_sqlite("./inventory.db")
Source code in src/model_ledger/sdk/ledger.py
from_snowflake
classmethod
¶
from_snowflake(
connection: Any, schema: str = "MODEL_LEDGER"
) -> Ledger
Create a Ledger backed by Snowflake.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
connection
|
Any
|
A Snowflake connection (snowflake.connector connection object). |
required |
schema
|
str
|
Fully qualified schema name (e.g., "MY_DB.MODEL_LEDGER"). |
'MODEL_LEDGER'
|
Example
ledger = Ledger.from_snowflake(conn, schema="ANALYTICS.MODEL_LEDGER")
Source code in src/model_ledger/sdk/ledger.py
dependencies
¶
dependencies(
model: ModelRef | str,
direction: str = "both",
*,
snapshots: list[Snapshot] | None = None,
) -> list[dict[str, Any]]
Direct dependency edges for a model.
Resolves every edge's target model in ONE batched lookup instead of a
per-edge round trip. Pass snapshots (the model's full history) to
reuse an already-fetched list and skip the list_snapshots call —
the graph traversal and investigate use this to avoid refetching.
Source code in src/model_ledger/sdk/ledger.py
add
¶
Register DataNodes. Each becomes a ModelRef + discovered Snapshot.
Skips writing if the discovered payload is identical to the last snapshot (content-hash dedup). Preloads existing models in bulk to avoid per-node queries.
Recognized node.metadata keys map onto the model row: owner,
model_type/node_type/type, tier, purpose,
model_origin, and status. A discovered status (any
ModelStatus value, case-insensitive) is propagated to the model —
including already-registered models — so lifecycle changes detected at
the source (e.g. deprecated for an entity deleted upstream) reach
the model row on the next sync. An absent or unrecognized status leaves
the stored status unchanged.
Source code in src/model_ledger/sdk/ledger.py
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 | |
connect
¶
Match output ports to input ports. Write only new dependency links.
Uses cached nodes from add() if available (avoids re-reading from backend). Preloads existing edges to skip duplicates.
Source code in src/model_ledger/sdk/ledger.py
trace
¶
Topological path from sources to this node.
Source code in src/model_ledger/sdk/ledger.py
upstream
¶
downstream
¶
All models that depend on this one (transitive).
Source code in src/model_ledger/sdk/ledger.py
register_group
¶
register_group(
*,
name: str,
owner: str,
model_type: str,
tier: str,
purpose: str,
members: list[str],
actor: str,
metadata: dict[str, Any] | None = None,
) -> ModelRef
Register a governed model group and link its members.
A group is a business-level entity that aggregates technical components. Members are linked via relationship="member_of".
Example
group = ledger.register_group( ... name="Credit Scorecard", owner="risk-team", ... model_type="ml_model", tier="high", ... purpose="Credit risk scoring pipeline", ... members=["feature_pipeline", "scoring_model", "alert_queue"], ... actor="system", ... )
Source code in src/model_ledger/sdk/ledger.py
members
¶
Return current members of this group.
Replays member_added/member_removed snapshots to determine current membership. Falls back to dependency links if no membership events exist (backward compatible with register_group).
Mixed case: groups seeded via register_group() that later have add_member()/remove_member() called use dependency links as the baseline and overlay the event log on top.
All member_added targets are resolved in a single batched lookup
instead of one round trip per event. Pass snapshots (the group's
full history) to reuse an already-fetched list.
Source code in src/model_ledger/sdk/ledger.py
groups
¶
Return groups this model currently belongs to.
Replays member_added/member_removed events on each candidate group
to exclude composites the model has been removed from. The candidate
composites' membership histories are fetched in a single bulk
list_all_snapshots scan when the backend supports it, so the cost
is one query for the whole fan-out rather than one per candidate.
Pass snapshots (this model's full history) to reuse an
already-fetched list for the downstream-edge discovery.
Source code in src/model_ledger/sdk/ledger.py
add_member
¶
add_member(
composite: ModelRef | str,
member: ModelRef | str,
*,
role: str | None = None,
actor: str,
) -> Snapshot
Add a member to a composite.
Records a member_added snapshot on the composite and creates a member_of dependency link.
Source code in src/model_ledger/sdk/ledger.py
remove_member
¶
remove_member(
composite: ModelRef | str,
member: ModelRef | str,
*,
reason: str | None = None,
actor: str,
) -> Snapshot
Remove a member from a composite.
Records a member_removed snapshot. The dependency link is NOT deleted (append-only event log). members() will exclude removed members by replaying member_added/member_removed events.
Source code in src/model_ledger/sdk/ledger.py
record_observation
¶
record_observation(
composite: ModelRef | str,
*,
observation_id: str,
observation: str,
status: str,
severity: str | None = None,
actor: str,
metadata: dict[str, Any] | None = None,
) -> Snapshot
Record an observation against a composite.
Source code in src/model_ledger/sdk/ledger.py
resolve_observation
¶
resolve_observation(
composite: ModelRef | str,
*,
observation_id: str,
resolution: str,
actor: str,
metadata: dict[str, Any] | None = None,
) -> Snapshot
Record the resolution of an observation.
Source code in src/model_ledger/sdk/ledger.py
record_validation
¶
record_validation(
composite: ModelRef | str,
*,
result: str,
actor: str,
metadata: dict[str, Any] | None = None,
) -> Snapshot
Record a validation result against a composite.
Source code in src/model_ledger/sdk/ledger.py
open_observation_count
staticmethod
¶
open_observation_count(snapshots: list[Snapshot]) -> int
Return the number of observations that have been issued but not resolved.
Accepts any iterable of Snapshots. Only observation_issued and
observation_resolved events that carry an observation_id payload key
are considered; all other snapshots are ignored.
Source code in src/model_ledger/sdk/ledger.py
composite_summary
¶
Flat inventory of all composites with derived fields.
By default, returns models whose model_type == "composite". Pass
model_types=["composite", "ml_model", "heuristic"] (or any subset)
to include other types the caller treats as composites.
Source code in src/model_ledger/sdk/ledger.py
Data models¶
The event-log primitives. A model is a ModelRef; every change is a Snapshot; a
Tag is a mutable pointer.
ModelRef
¶
Bases: BaseModel
Regulatory identity — the minimum a regulator needs.
Snapshot
¶
Bases: BaseModel
Immutable, content-addressed observation of a model.
Tag
¶
Bases: BaseModel
Mutable pointer from a name to a snapshot.
Graph¶
DataNode
dataclass
¶
DataNode(
name: str,
platform: str = "",
inputs: list[DataPort] = list(),
outputs: list[DataPort] = list(),
metadata: dict[str, Any] = dict(),
)
DataPort
¶
Connectors¶
Factory functions that emit DataNodes from external sources. See
Connectors & discovery for usage.
sql_connector
¶
sql_connector(
*,
name: str,
connection: Any,
query: str,
name_column: str,
name_prefix: str = "",
input_columns: list[str] | None = None,
output_columns: list[str] | None = None,
sql_column: str | None = None,
sql_preprocessor: Callable[[str], str]
| str
| None = "default",
shared_table_patterns: list[str] | None = None,
shared_table_fallback: dict[str, str] | None = None,
cron_column: str | None = None,
input_port: dict[str, str] | None = None,
output_port: dict[str, str] | None = None,
metadata_columns: dict[str, str] | None = None,
) -> _SQLConnector
Create a SourceConnector that discovers models from a SQL query.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Platform name for discovered DataNodes. |
required |
connection
|
Any
|
Database connection with execute() method. |
required |
query
|
str
|
SQL query to run. |
required |
name_column
|
str
|
Column containing the model name. |
required |
name_prefix
|
str
|
Optional prefix for model names (e.g., "queue:"). |
''
|
input_columns
|
list[str] | None
|
Columns containing input table/port identifiers. |
None
|
output_columns
|
list[str] | None
|
Columns containing output table/port identifiers. |
None
|
sql_column
|
str | None
|
Column containing SQL to parse for input/output tables. |
None
|
sql_preprocessor
|
Callable[[str], str] | str | None
|
Function to clean SQL before parsing (e.g., strip template variables). Default: strip_template_vars from model_ledger.adapters.sql. Pass None to disable preprocessing. |
'default'
|
shared_table_patterns
|
list[str] | None
|
When sql_column is set, table names matching any of these substrings will get model_name discriminators from the parsed SQL. Default: ["scores", "alert"]. |
None
|
shared_table_fallback
|
dict[str, str] | None
|
When a write table matches shared_table_patterns but no model_name is found in the SQL, derive model_name from a column value. Dict with keys: source_column (required), strip_prefix (optional regex). Example: {"source_column": "NAME", "strip_prefix": "etl_"} |
None
|
cron_column
|
str | None
|
Column containing a cron expression. When set, adds both the raw cron and an English translation to metadata. |
None
|
input_port
|
dict[str, str] | None
|
Config dict with keys: column, fallback (optional), kind (optional). |
None
|
output_port
|
dict[str, str] | None
|
Config dict with keys: column, fallback (optional), kind (optional). |
None
|
metadata_columns
|
dict[str, str] | None
|
Explicit {metadata_key: column_name} mapping. If omitted, all unmapped columns become metadata automatically. |
None
|
Returns:
| Type | Description |
|---|---|
_SQLConnector
|
A SourceConnector with a discover() method. |
Source code in src/model_ledger/connectors/sql.py
rest_connector
¶
rest_connector(
*,
name: str,
url: str,
items_path: str,
name_field: str,
headers: dict[str, str] | None = None,
input_fields: list[str] | None = None,
output_fields: list[str] | None = None,
metadata_fields: dict[str, str] | None = None,
pagination: dict[str, str] | None = None,
) -> _RESTConnector
Create a SourceConnector that discovers models from a REST API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Platform name for discovered DataNodes. |
required |
url
|
str
|
API endpoint URL. |
required |
items_path
|
str
|
Dot-path to the array of items in JSON response. |
required |
name_field
|
str
|
Field containing the model name. |
required |
headers
|
dict[str, str] | None
|
HTTP headers (auth goes here). |
None
|
input_fields
|
list[str] | None
|
Dot-paths to input identifiers. |
None
|
output_fields
|
list[str] | None
|
Dot-paths to output identifiers. |
None
|
metadata_fields
|
dict[str, str] | None
|
Explicit {metadata_key: field_path} mapping. If omitted, all unmapped fields become metadata automatically. |
None
|
pagination
|
dict[str, str] | None
|
Config dict with keys: type (token/offset), token_field, param. |
None
|
Returns:
| Type | Description |
|---|---|
_RESTConnector
|
A SourceConnector with a discover() method. |
Source code in src/model_ledger/connectors/rest.py
github_connector
¶
github_connector(
*,
name: str,
repos: list[str],
project_path: str,
config_file: str,
parser: Callable[[str, str], DataNode | None],
token: str | None = None,
) -> _GitHubConnector
Create a SourceConnector that discovers models from GitHub repos.
For each repo, lists subdirectories under project_path, reads config_file from each, and passes the content to parser to produce DataNodes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Platform name for discovered DataNodes. |
required |
repos
|
list[str]
|
List of GitHub repos (org/repo format). |
required |
project_path
|
str
|
Directory containing project subdirectories. |
required |
config_file
|
str
|
Filename to read in each project directory. |
required |
parser
|
Callable[[str, str], DataNode | None]
|
Function (project_name, file_content) -> DataNode | None. |
required |
token
|
str | None
|
GitHub personal access token (optional). |
None
|
Returns:
| Type | Description |
|---|---|
_GitHubConnector
|
A SourceConnector with a discover() method. |
Source code in src/model_ledger/connectors/github.py
Introspection¶
introspect
¶
Model introspection — plugin-based metadata extraction.
ComponentInfo
¶
Bases: BaseModel
Maps to a ComponentNode in the version's tree.
IntrospectionResult
¶
Bases: BaseModel
Typed contract returned by all introspectors.
Introspector
¶
Bases: Protocol
Extracts metadata from a model object or config.
get_registry
¶
Get or create the global introspector registry.
register_introspector
¶
register_introspector(introspector: Introspector) -> None
register_introspector
¶
register_introspector(introspector: Introspector) -> None
Register a custom introspector plugin.
Manually registered introspectors take priority over entry-point-discovered ones.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
introspector
|
Introspector
|
An object implementing the Introspector protocol (must have name, can_handle, and introspect attributes). |
required |
Example
from model_ledger import register_introspector register_introspector(MyCustomIntrospector())