Snapshots Module
The storage and state-machine core behind Snapshot Testing. The pytest
toolscore_snapshot fixture and the toolscore record/approve/snapshots
CLI commands are built on this API.
- toolscore.snapshots.snapshot_check(name, actual, *, store=None, update=False, min_score=1.0, weights=None, strict=False)[source]
Record, approve and replay tool-call snapshots.
Extracts tool calls from actual (via
toolscore.integrations.auto_extract(), so raw provider responses are accepted) and runs the snapshot state machine:Snapshot missing. Locally: write an unapproved snapshot, emit a
UserWarningtelling the user to review and approve it, and returnNone. In CI (CIenv var set): raiseToolScoreAssertionErrorwithout writing the file — snapshots must be created and reviewed locally, never minted in CI.update=True. Overwrite the snapshot’s calls, mark it approved, emit a
UserWarning, and returnNone.Exists but unapproved. Locally: emit a
UserWarningand returnNone(an unapproved baseline is never evaluated against). In CI: raiseToolScoreAssertionError.Exists and approved. Evaluate actual against the approved baseline with
toolscore.evaluate(), enforce min_score, and return theEvaluationResult.
- Parameters:
name (
str) – Snapshot identifier (typically the pytest node id).actual (
Any) – A raw provider response or a list of tool-call dicts. Always run throughauto_extractbefore storage / comparison.store (
SnapshotStore|None) – Snapshot store to use;Noneuses a default-rooted store.update (
bool) – When True, overwrite and approve the snapshot (state 2).min_score (
float) – Minimum composite score required when replaying (state 4).weights (
dict[str,float] |None) – Optional custom weights for the composite score.strict (
bool) – When True, argument comparison uses pure equality.
- Return type:
- Returns:
An
EvaluationResultwhen an approved baseline was replayed (state 4); otherwiseNone.- Raises:
ToolScoreAssertionError – In CI when the snapshot is missing or unapproved, or when an approved replay scores below min_score.
- class toolscore.snapshots.Snapshot(name, calls=<factory>, approved=False, source='pytest', created_at='', updated_at='', schema_version=1, toolscore_version='')[source]
A recorded set of tool calls for a single test.
- Variables:
name – Logical identifier (typically a pytest node id).
calls – List of tool-call dicts (
{"tool": ..., "args": {...}}).approved – Whether a human has approved this baseline.
source – How the snapshot was produced —
"pytest","record"or"trace".created_at – ISO-8601 UTC timestamp; filled on creation if empty.
updated_at – ISO-8601 UTC timestamp; filled on creation if empty.
schema_version – On-disk schema version.
toolscore_version – Version of toolscore that wrote the snapshot; filled from the package version if empty.
- Parameters:
- __init__(name, calls=<factory>, approved=False, source='pytest', created_at='', updated_at='', schema_version=1, toolscore_version='')
- class toolscore.snapshots.SnapshotStore(root='.toolscore/snapshots')[source]
File-backed store for snapshots — one JSON file per snapshot.
The root directory is created lazily on the first
save(), so merely constructing a store (or listing an empty/absent root) never touches the filesystem in a way that creates directories.- Parameters:
root (str | Path)
- __init__(root='.toolscore/snapshots')[source]
Initialize the store rooted at root (no directory is created).
- path_for(name)[source]
Return the on-disk path for a snapshot named name.
The filename is
<sanitized-name>-<sha1(name)[:8]>.json. The sha1 of the full name guarantees uniqueness even when sanitization collapses distinct names, and keeps every snapshot insiderootregardless of path-traversal sequences in the name.
- load(name)[source]
Load the snapshot named name, or None if it does not exist.
- Raises:
ValueError – If the file exists but cannot be parsed as a valid snapshot (the path is included in the message).
- Return type:
- Parameters:
name (str)
- save(snapshot)[source]
Persist snapshot to disk, creating the root directory if needed.
The snapshot’s
updated_attimestamp is refreshed before writing.