Client reference¶
Top-level¶
methodic.Chronicle ¶
Client for the Chronicle REST API.
Construct once with the server URL + API key, then call into namespaces:
chronicle = Chronicle(server_url="https://api.methodiclabs.ai", api_key="sk_...")
# Researcher
exp = chronicle.experiments.create(hypothesis_summary="...", config_yaml="...")
exp.commit().variations.create(config_yaml="...")
# Worker
run = chronicle.run(experiment_id, variation, run_idx)
run.start().heartbeat()
run.upload_asset(asset_type="research_report", content={"summary": "..."})
run.succeed()
Use as a context manager to guarantee the executor and HTTP session are closed.
Resource handles¶
methodic.Experiment ¶
Experiment(
chronicle: Chronicle,
experiment_id: str,
*,
_detail: ExperimentDetail | None = None,
_create_response: CreateExperimentResponse
| None = None,
)
Handle for one experiment.
Mutators (commit, conclude, retract) return self so callers can
chain (exp.commit().variations.create(...)). Cached detail is dropped
after each mutation; the next attribute access re-fetches transparently.
git_status ¶
Lightweight current git-integration state for this experiment.
mint_git_token ¶
Mint a 1-hour install token scoped to this experiment's repo.
set_report_settings ¶
Replace experiment.report_settings. Frozen at commit (server
returns 409 once committed). settings shape matches the
ReportSettings server type:
{
"hypothesis": {"mode": "freeform", "freeform_prompt": "..."},
"takeaways": {"mode": "template", "template_asset_id": "...", "per_variation": true},
"research": {...}
}
Returns self for chaining. Drops cached _detail so the next
access re-fetches the updated row.
wait_for_repo ¶
Poll until this experiment's repo is ready (or failed/timeout).
methodic.Variation ¶
Variation(
chronicle: Chronicle,
experiment_id: str,
variation: int,
*,
_data: Variation | None = None,
)
Handle for one variation. Holds (experiment_id, variation) and lazy-loaded data.
data
property
¶
Server-side variation record. Auto-fetched on first access; refetched after mutations.
methodic.Run ¶
Handle for a specific (experiment_id, variation, run) run.
Mutators return self so worker code can chain (run.start().heartbeat()).
Asset-upload helpers auto-populate output_of from the bound triple.
create_asset_presigned ¶
create_asset_presigned(
asset_type: str,
components: list[str],
name: str | None = None,
content_type: str = "application/octet-stream",
) -> AssetUploadInfo
Register a new asset for component upload via presigned URLs.
register_and_upload_async ¶
register_and_upload_async(
local_dir: Path,
asset_type: str,
upload_tracker: UploadTracker,
content_type: str = "application/octet-stream",
) -> str
Register every file in a directory, then upload + finalize on a background thread.
upload_asset ¶
upload_asset(
asset_type: str,
content: Any,
name: str | None = None,
content_type: str = "application/json",
asset_config: dict[str, Any] | None = None,
) -> dict[str, Any]
Upload a small inline asset (auto-finalized). Linked to this run as output.
upload_directory_async ¶
upload_directory_async(
local_dir: Path,
asset_type: str,
content_type: str = "application/octet-stream",
upload_tracker: UploadTracker | None = None,
) -> None
Upload every file in a directory on a background thread.
With upload_tracker, uses the register-then-upload flow for crash
recovery. Without, a thinner path that uploads and finalizes inline.
Namespaces¶
methodic.ExperimentsAPI ¶
Experiments namespace. Stateless; every method takes the experiment id explicitly.
create ¶
create(
*,
hypothesis_summary: str,
config_yaml: str,
rationale: str | None = None,
description: str | None = None,
accelerate_config_yaml: str | None = None,
launch_config: dict[str, Any] | None = None,
parent_experiment_ids: list[str] | None = None,
allow_retracted_parent: bool = False,
) -> Experiment
Create a new experiment. Returns a handle with the create-response cached.
git_status ¶
Current git-integration state for the experiment.
Returns lightweight status info — state (pending/ready/failed/archived),
repo_url (when ready), failure_reason (when failed). Cheap to poll;
UI calls this every couple seconds while state is pending.
iter ¶
iter(
*,
status: str | None = None,
created_by: str | None = None,
page_size: int | None = None,
) -> Iterator[ExperimentSummary]
Yield every experiment matching the filters, paging server-side as needed.
list ¶
list(
*,
status: str | None = None,
created_by: str | None = None,
page_size: int | None = None,
page_token: str | None = None,
) -> ExperimentListPage
One page of experiments matching the filters. Cursor-aware (when server supports it).
mint_git_token ¶
Mint a 1-hour install token scoped to this experiment's repo.
The returned token has Administration permission stripped — pushes
to agent/* branches will be rejected by branch protection. Use it
to clone the repo and push to user/... branches you create.
Raises ServerError(503) if the server has no GitHub App configured;
ConflictError(409) if the experiment's repo isn't ready yet.
wait_for_repo ¶
wait_for_repo(
experiment_id: str,
*,
timeout: float = 300.0,
poll_interval: float = 2.0,
) -> GitStatus
Poll git_status until the repo is ready or failed, or timeout.
methodic.VariationsAPI ¶
Variations namespace. Keys every operation on (experiment_id, variation).
create ¶
create(
experiment_id: str,
*,
config_yaml: str,
accelerate_config_yaml: str | None = None,
launch_config: dict[str, Any] | None = None,
description: str | None = None,
input_asset_ids: list[str] | None = None,
git_ref: str | None = None,
) -> Variation
Create a new variation under experiment_id. Returns a Variation handle.
git_ref optionally associates the variation with a branch on the
experiment's GitHub repo. Server captures the branch name now;
SHA resolution + the branch-rename-to-agent/... flow happens at
variation commit (Phase 3). Pre-Phase-3, registering with git_ref
is informational only.
methodic.RunsAPI ¶
Run-lifecycle namespace. Stateless across calls; takes the run triple as args.
fail ¶
Mark a run failed. reason is crash (worker error) or abandoned (cancel).
methodic.AssetsAPI ¶
Asset operations.
Output-of linking (which experiment/variation/run produced this asset) is
passed explicitly by callers — Run populates it from its bound context,
while researcher-level uploads pass it directly or omit it for shared assets.
create_inline ¶
create_inline(
*,
asset_type: str,
content: Any,
name: str | None = None,
content_type: str = "application/json",
output_of: dict[str, Any] | None = None,
asset_config: dict[str, Any] | None = None,
) -> dict[str, Any]
Upload a small inline asset. Chronicle auto-finalizes.
create_with_presigned ¶
create_with_presigned(
*,
asset_type: str,
components: list[str],
name: str | None = None,
content_type: str = "application/octet-stream",
output_of: dict[str, Any] | None = None,
) -> AssetUploadInfo
Register a new asset and get presigned PUT URLs for each component.
download ¶
Download all components of an asset to a local directory.
finalize ¶
Mark a presigned-upload asset as ready (immutable) once all components are up.
get ¶
Fetch asset metadata. With include_presigned=True, includes read URLs.
presign ¶
presign(
asset_id: str,
*,
operation: str = "read",
components: list[str] | None = None,
) -> dict[str, Any]
Request presigned URLs for an asset's components.
upload_component ¶
PUT one component to its presigned URL.
methodic.SearchAPI ¶
Vertex-backed search across research docs, experiment metadata, and arxiv assets.
iter ¶
iter(
query: str,
*,
filters: SearchFilters | dict[str, Any] | None = None,
experiment_context: list[str] | None = None,
page_size: int | None = None,
) -> Iterator[SearchResult]
Yield every search hit, paging server-side as needed.
query ¶
query(
query: str,
*,
filters: SearchFilters | dict[str, Any] | None = None,
experiment_context: list[str] | None = None,
page_size: int | None = None,
page_token: str | None = None,
) -> SearchResponse
Run a single search request. Returns one page; use iter to walk pages.
Response types¶
methodic.ExperimentData
dataclass
¶
ExperimentData(
id: str,
owner_subject: str,
hypothesis_summary: str,
created_at: str,
created_by: str,
state: str,
rationale: str | None = None,
description: str | None = None,
committed_at: str | None = None,
concluded_at: str | None = None,
retracted_at: str | None = None,
retraction_reason: str | None = None,
git_repo_state: str = "pending",
git_repo_url: str | None = None,
git_repo_failure_reason: str | None = None,
)
Mirror of the server's Experiment struct.
git_repo_state defaults to "pending" so older server payloads (which
may not include the field yet) deserialize cleanly.
methodic.ExperimentDetail
dataclass
¶
ExperimentDetail(
experiment: Experiment,
parent_ids: list[str],
variations: list[VariationSummary],
)
GET /experiments/{id} response: experiment + parents + variation summaries.
methodic.ExperimentSummary
dataclass
¶
ExperimentSummary(
id: str,
hypothesis_summary: str,
variation_count: int,
created_at: str,
created_by: str,
state: str,
status: str | None = None,
committed_at: str | None = None,
concluded_at: str | None = None,
retracted_at: str | None = None,
)
One row in the experiments list.
methodic.ExperimentListPage
dataclass
¶
One page of experiments.list results plus a cursor for the next page.
The current server returns a flat array; we normalize that into a
single-page response with next_page_token=None. When the server
grows pagination, the same dataclass keeps working.
methodic.VariationData
dataclass
¶
VariationData(
experiment_id: str,
variation: int,
config_json: dict[str, Any],
config_yaml: str,
created_at: str,
created_by: str,
state: str,
accelerate_config_json: dict[str, Any] | None = None,
accelerate_config_yaml: str | None = None,
launch_config: dict[str, Any] | None = None,
description: str | None = None,
committed_at: str | None = None,
retracted_at: str | None = None,
retraction_reason: str | None = None,
git_ref: str | None = None,
git_sha: str | None = None,
)
Mirror of the server's Variation struct.
config_json, accelerate_config_json, and launch_config arrive as
arbitrary JSON — kept as dict[str, Any] since the schema is open.
methodic.VariationSummary
dataclass
¶
VariationSummary(
variation: int,
created_at: str,
run_count: int,
state: str,
description: str | None = None,
latest_status: str | None = None,
committed_at: str | None = None,
retracted_at: str | None = None,
)
One variation as it appears in ExperimentDetail.variations.
methodic.LineageResponse
dataclass
¶
methodic.UpstreamRetraction
dataclass
¶
UpstreamRetraction(
experiment_id: str,
retracted_at: str,
reason: str,
depth: int,
variation: int | None = None,
document_asset_id: str | None = None,
chain: list[str] | None = None,
)
methodic.UpstreamRetractionsResponse
dataclass
¶
methodic.CreateExperimentResponse
dataclass
¶
POST /experiments response: the new experiment plus the always-created variation 0 / run 0.
methodic.SearchResult
dataclass
¶
SearchResult(
document_id: str,
source_type: str,
relevance_score: float,
lineage_boost: bool,
asset_type: str | None = None,
title: str | None = None,
snippet: str | None = None,
experiment_ids: list[str] = list(),
created_at: str | None = None,
)
One hit from the Vertex-backed search.
methodic.SearchResponse
dataclass
¶
methodic.SearchFilters
dataclass
¶
SearchFilters(
asset_types: list[str] | None = None,
organization_id: str | None = None,
team_id: str | None = None,
created_after: str | None = None,
created_before: str | None = None,
created_by: str | None = None,
source_type: str | None = None,
)
Filters layered on top of the RBAC + namespace filters the server adds.
methodic.AssetUploadInfo
dataclass
¶
Result of AssetsAPI.create_with_presigned: where to put each component.
Errors¶
methodic.ChronicleError ¶
Bases: Exception
Base class for every error raised by the methodic client.