API reference¶
The public Python surface. The in-process client is what training scripts
use; MlParty is the core API every frontend (MCP, CLI, HTTP) is a thin
layer over; the models are the ontology.
Client (training scripts)¶
In-process client for training scripts — the second writer (§1.3).
The agent brackets the run over MCP (start → finalize); the training process attaches with mlparty.attach() (reading ML_PARTY_STORE / ML_PARTY_RUN set by the launcher) and streams telemetry to the per-run journal.
Split repro capture (three-machine world): the machine that runs the code is the only honest witness to its environment, so attaching patches the actual invocation and hardware onto the run and captures the runtime env lock from sys.executable (in the background — pip freeze is slow; finalize/fail joins it so a completed run always carries it). A heartbeat thread marks liveness so the UI and janitor can tell running from silently dead.
- mlparty.client.attach(run_id=None, store=None, **kwargs)[source]¶
Attach to a run the agent already started (env-var handshake).
- Parameters:
run_id (str | None)
store (Path | str | None)
kwargs (Any)
- Return type:
RunHandle
- mlparty.client.start_run(store, experiment, title, purpose, hypothesis, parameters, **kwargs)[source]¶
Start a run from inside the training process itself (agentless use).
- Parameters:
store (Path | str)
experiment (str)
title (str)
purpose (str)
hypothesis (str)
parameters (dict[str, Any])
kwargs (Any)
- Return type:
RunHandle
Core¶
- class mlparty.core.MlParty(store)[source]¶
- Parameters:
store (Store)
- project_ensure(name, description=None, created_by='unknown')[source]¶
- Parameters:
name (str)
description (str | None)
created_by (str)
- Return type:
dict
- experiment_ensure(project, name, description=None, created_by='unknown')[source]¶
- Parameters:
project (str)
name (str)
description (str | None)
created_by (str)
- Return type:
dict
- snapshot_preview(source_root, experiment=None)[source]¶
What a snapshot of source_root would capture, without writing it.
Pass experiment to also learn whether this exact tree is already stored — a re-run of unchanged code adds nothing, and saying so is more useful than re-listing the same files every time.
- Parameters:
source_root (Path | str)
experiment (str | None)
- Return type:
dict
- run_start(experiment, title, purpose, hypothesis, parameters, derives_from=None, data_refs=None, seed=None, tags=None, created_by='unknown', source_root=None, python_exe=None, planned_command=None, confirm_snapshot=False)[source]¶
- Parameters:
experiment (str)
title (str)
purpose (str)
hypothesis (str)
parameters (dict[str, Any])
derives_from (list[str] | None)
data_refs (list[dict] | None)
seed (int | None)
tags (list[str] | None)
created_by (str)
source_root (Path | str | None)
python_exe (str | None)
planned_command (str | None)
confirm_snapshot (bool)
- Return type:
dict
- run_log_metric(run, name, value, step=None)[source]¶
- Parameters:
run (str)
name (str)
value (float)
step (int | None)
- Return type:
dict
- run_log_artifact(run, path, media_type=None, note=None)[source]¶
- Parameters:
run (str)
path (Path | str)
media_type (str | None)
note (str | None)
- Return type:
dict
- experiment_log_artifact(experiment, path, media_type=None, note=None)[source]¶
Cross-run artifacts (experiment-level boards, summary reports).
- Parameters:
experiment (str)
path (Path | str)
media_type (str | None)
note (str | None)
- Return type:
dict
- run_finalize(run, method, result, reproduce, edges=None, tags=None, created_by='unknown')[source]¶
- Parameters:
run (str)
method (str)
result (dict)
reproduce (str)
edges (list[dict] | None)
tags (list[str] | None)
created_by (str)
- Return type:
dict
- run_fail(run, what_failed, failure_class=None, why=None, traceback=None)[source]¶
- Parameters:
run (str)
what_failed (str)
failure_class (str | None)
why (str | None)
traceback (str | None)
- Return type:
dict
- note_create(title, body, kind='insight', edges=None, tags=None, created_by='unknown')[source]¶
- Parameters:
title (str)
body (str)
kind (str)
edges (list[dict] | None)
tags (list[str] | None)
created_by (str)
- Return type:
dict
- node_get(ref, include_metrics=False)[source]¶
- Parameters:
ref (str)
include_metrics (bool)
- Return type:
dict
- node_annotate(ref, text, edges=None, created_by='unknown')[source]¶
- Parameters:
ref (str)
text (str)
edges (list[dict] | None)
created_by (str)
- Return type:
dict
- graph_query(query, mode='hybrid', type=None, experiment=None, status=None, tag=None, limit=10)[source]¶
- Parameters:
query (str)
mode (str)
type (str | None)
experiment (str | None)
status (str | None)
tag (str | None)
limit (int)
- Return type:
dict
- board_list(experiment=None)[source]¶
Boards (text/html artifacts) across the store, newest carrier first. With experiment: that experiment’s own boards + its runs’ boards.
- Parameters:
experiment (str | None)
- Return type:
list[dict]
- action_register(template, created_by='unknown')[source]¶
- Parameters:
template (dict)
created_by (str)
- Return type:
dict
Run control¶
Run-control plane: registered action templates, audited invocation.
ml-party never becomes a scheduler — orchestration stays in the user’s scripts/slurm/k8s. What this module adds is the uniform, audited interface agents use to drive them: users register action templates (shell commands with typed placeholders — the allowlist), agents invoke them with validated parameters (never free-form strings; every value is shell-quoted), and every invocation is recorded in the knowledge graph as an action node edged to the run it controls (who, what, when, outcome).
Trust model (v1, local): templates execute as the process user on the host where the invoking surface runs — registration is therefore a local-surface operation (CLI, MCP over stdio); the HTTP server only lists and invokes (write-gated). Remote runners are a later phase.
- class mlparty.actions.ActionParam(*, type='str', choices=None, default=None, required=True, help=None)[source]¶
- Parameters:
type (Literal['str', 'int', 'float', 'choice'])
choices (list[str] | None)
default (str | int | float | None)
required (bool)
help (str | None)
- type: Literal['str', 'int', 'float', 'choice']¶
- choices: list[str] | None¶
- default: str | int | float | None¶
- required: bool¶
- help: str | None¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.actions.ActionTemplate(*, name, command, description, cwd=None, env=<factory>, params=<factory>, experiment=None, created_by='unknown', created_at='')[source]¶
- Parameters:
name (str)
command (str)
description (str)
cwd (str | None)
env (dict[str, str])
params (dict[str, ActionParam])
experiment (str | None)
created_by (str)
created_at (str)
- name: str¶
- command: str¶
- description: str¶
- cwd: str | None¶
- env: dict[str, str]¶
- params: dict[str, ActionParam]¶
- experiment: str | None¶
- created_by: str¶
- created_at: str¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
Ontology models¶
Core ontology (DESIGN.md §3): fixed spine, extensible ribs.
Nodes serialize to JSON documents; the journal holds them as the source of truth and the SQLite index stores the same document for querying. Custom node types fall back to CustomNode and inherit every common field.
- class mlparty.models.Edge(*, src, dst, type, note=None, created_by='unknown', created_at=<factory>)[source]¶
- Parameters:
src (str)
dst (str)
type (str)
note (str | None)
created_by (str)
created_at (datetime)
- src: str¶
- dst: str¶
- type: str¶
- note: str | None¶
- created_by: str¶
- created_at: datetime¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.Abstract(*, purpose, hypothesis, method=None)[source]¶
- Parameters:
purpose (str)
hypothesis (str)
method (str | None)
- purpose: str¶
- hypothesis: str¶
- method: str | None¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.Result(*, summary, verdict, metrics=<factory>, metrics_note=None, surprises=None)[source]¶
- Parameters:
summary (str)
verdict (Literal['confirmed', 'refuted', 'inconclusive'])
metrics (dict[str, float])
metrics_note (str | None)
surprises (str | None)
- summary: str¶
- verdict: Literal['confirmed', 'refuted', 'inconclusive']¶
- metrics: dict[str, float]¶
- metrics_note: str | None¶
- surprises: str | None¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.Failure(*, what_failed, failure_class=None, why=None, traceback=None)[source]¶
- Parameters:
what_failed (str)
failure_class (str | None)
why (str | None)
traceback (str | None)
- what_failed: str¶
- failure_class: str | None¶
- why: str | None¶
- traceback: str | None¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.SnapshotReport(*, included_files=0, included_bytes=0, included=<factory>, source_mode=None, excluded=<factory>, skipped_for_size=<factory>, redacted_keys=<factory>, note=None)[source]¶
- Parameters:
included_files (int)
included_bytes (int)
included (list[str])
source_mode (str | None)
excluded (list[str])
skipped_for_size (list[str])
redacted_keys (list[str])
note (str | None)
- included_files: int¶
- included_bytes: int¶
- included: list[str]¶
- source_mode: str | None¶
- excluded: list[str]¶
- skipped_for_size: list[str]¶
- redacted_keys: list[str]¶
- note: str | None¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.Invocation(*, argv=<factory>, cwd=None, entrypoint=None, env=<factory>, captured_by=None)[source]¶
- Parameters:
argv (list[str])
cwd (str | None)
entrypoint (str | None)
env (dict[str, str])
captured_by (str | None)
- argv: list[str]¶
- cwd: str | None¶
- entrypoint: str | None¶
- env: dict[str, str]¶
- captured_by: str | None¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.DataRef(*, uri, fingerprint=None, role=None)[source]¶
- Parameters:
uri (str)
fingerprint (str | None)
role (str | None)
- uri: str¶
- fingerprint: str | None¶
- role: str | None¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.Hardware(*, host=None, platform=None, cpu=None, ram_gb=None, gpus=<factory>, captured_by=None)[source]¶
- Parameters:
host (str | None)
platform (str | None)
cpu (str | None)
ram_gb (float | None)
gpus (list[GpuInfo])
captured_by (str | None)
- host: str | None¶
- platform: str | None¶
- cpu: str | None¶
- ram_gb: float | None¶
- gpus: list[GpuInfo]¶
- captured_by: str | None¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.ArtifactRef(*, sha256, size_bytes, media_type=None, original_path, note=None)[source]¶
- Parameters:
sha256 (str)
size_bytes (int)
media_type (str | None)
original_path (str)
note (str | None)
- sha256: str¶
- size_bytes: int¶
- media_type: str | None¶
- original_path: str¶
- note: str | None¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.ProjectNode(*, id, type='project', title, slug='', tags=<factory>, annotations=<factory>, created_by='unknown', created_at=<factory>, updated_at=<factory>, schema_version=1, description=None)[source]¶
- Parameters:
id (str)
type (Literal['project'])
title (str)
slug (str)
tags (list[str])
annotations (list[Annotation])
created_by (str)
created_at (datetime)
updated_at (datetime)
schema_version (int)
description (str | None)
- type: Literal['project']¶
- description: str | None¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.ExperimentNode(*, id, type='experiment', title, slug='', tags=<factory>, annotations=<factory>, created_by='unknown', created_at=<factory>, updated_at=<factory>, schema_version=1, project_id, description=None, artifacts=<factory>)[source]¶
- Parameters:
id (str)
type (Literal['experiment'])
title (str)
slug (str)
tags (list[str])
annotations (list[Annotation])
created_by (str)
created_at (datetime)
updated_at (datetime)
schema_version (int)
project_id (str)
description (str | None)
artifacts (list[ArtifactRef])
- type: Literal['experiment']¶
- project_id: str¶
- description: str | None¶
- artifacts: list[ArtifactRef]¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.NoteNode(*, id, type='note', title, slug='', tags=<factory>, annotations=<factory>, created_by='unknown', created_at=<factory>, updated_at=<factory>, schema_version=1, kind='insight', body='')[source]¶
- Parameters:
id (str)
type (Literal['note'])
title (str)
slug (str)
tags (list[str])
annotations (list[Annotation])
created_by (str)
created_at (datetime)
updated_at (datetime)
schema_version (int)
kind (Literal['feedback', 'reference', 'insight'])
body (str)
- type: Literal['note']¶
- kind: Literal['feedback', 'reference', 'insight']¶
- body: str¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class mlparty.models.RunNode(*, id, type='run', title, slug='', tags=<factory>, annotations=<factory>, created_by='unknown', created_at=<factory>, updated_at=<factory>, schema_version=1, experiment_id, status='open', provenance='live', abstract, parameters=<factory>, params_hash='', result=None, reproduce=None, failure=None, code_ref=None, snapshot_report=None, project_git=None, invocation=None, env_lock_ref=None, env_lock_runtime=None, data_refs=<factory>, seed=None, hardware=None, started_at=<factory>, ended_at=None, metrics_summary=<factory>, artifacts=<factory>)[source]¶
- Parameters:
id (str)
type (Literal['run'])
title (str)
slug (str)
tags (list[str])
annotations (list[Annotation])
created_by (str)
created_at (datetime)
updated_at (datetime)
schema_version (int)
experiment_id (str)
status (Literal['open', 'finalized', 'failed', 'abandoned'])
provenance (Literal['live', 'retro'])
abstract (Abstract)
parameters (dict[str, Any])
params_hash (str)
result (Result | None)
reproduce (str | None)
failure (Failure | None)
code_ref (CommitRef | None)
snapshot_report (SnapshotReport | None)
project_git (ProjectGitRef | None)
invocation (Invocation | None)
env_lock_ref (str | None)
env_lock_runtime (ArtifactRef | None)
data_refs (list[DataRef])
seed (int | None)
hardware (Hardware | None)
started_at (datetime)
ended_at (datetime | None)
metrics_summary (dict[str, float])
artifacts (list[ArtifactRef])
- type: Literal['run']¶
- experiment_id: str¶
- status: Literal['open', 'finalized', 'failed', 'abandoned']¶
- provenance: Literal['live', 'retro']¶
- parameters: dict[str, Any]¶
- params_hash: str¶
- reproduce: str | None¶
- code_ref: CommitRef | None¶
- snapshot_report: SnapshotReport | None¶
- project_git: ProjectGitRef | None¶
- invocation: Invocation | None¶
- env_lock_ref: str | None¶
- env_lock_runtime: ArtifactRef | None¶
- seed: int | None¶
- started_at: datetime¶
- ended_at: datetime | None¶
- metrics_summary: dict[str, float]¶
- artifacts: list[ArtifactRef]¶
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].