Artifacts¶
Content-addressed artifacts: the specs that key them, the store that holds their files and the cache that serves them.
femforge.artifacts
¶
Content-addressed artifacts: a spec keys each one, a store holds its files, and the cache serves, pulls through or produces it.
Modules:
-
cache–The typed front door: key a spec, serve it from the local tier, then the remote tier, else produce it under a heartbeat claim and publish to both.
-
keys–Artifact identity: a typed content key, one canonical JSON serialization, one hash,
HashExclude()honoured at any depth. -
kind–An artifact kind: how its spec keys, what a complete artifact contains, and optionally how to make one; passed by reference, never looked up by name.
-
local–The directory-backed store: a staging dir plus one rename publishes atomically, and a sidecar written inside the staging dir is the commit marker.
-
lock–In-flight claims: a heartbeat-refreshed marker on one artifact key, held as a directory (
mkdiris atomic on NTFS, POSIX, and SMB). -
records–A kind whose artifact is one JSON file holding a typed result: the sweep-point memo, generalized.
-
sidecar–The sidecar that commits an artifact (
artifact.json: file list, hashes, spec, provenance) and the reference a consumer keeps. -
store–The store contract: a byte store addressed by
(kind, key)with a commit-marker sidecar and heartbeat claims, so any backend (a directory, S3) can implement it.
Classes:
-
ArtifactCache–Local tier always; an optional remote tier is pulled through on a hit and pushed to after a publish.
-
ArtifactClaim–A held claim: refreshed by
heartbeatwhile the holder works, dropped byrelease. -
ArtifactCorrupt–A stored artifact disagrees with its sidecar.
-
ArtifactError–An artifact-store failure.
-
ArtifactHandle–A served artifact: where its files are, where they came from, and the record behind them.
-
ArtifactKey–A content key (hex SHA-256), phantom-typed by the spec model it was hashed from;
nameis its readable directory form. -
ArtifactKind–One class of artifact; a module-level constant callers pass by reference.
-
ArtifactMissing–The requested artifact is in no tier and no producer was given.
-
ArtifactOrigin–Where a served artifact came from.
-
ArtifactRecord–The commit marker plus provenance of one stored artifact.
-
ArtifactRef–A consumer's pointer to a store artifact: enough to re-fetch it and to know which of its files are re-fetchable.
-
ArtifactStore–One storage tier: an artifact exists exactly when its sidecar can be read, and
putis first-wins and atomic. -
BuiltinKind–Store path segments of the built-in kinds; the only place these strings are spelled.
-
DirLock–A claim held as a directory with an owner file; stale (no heartbeat for
stale_after_s) claims are broken by the next claimant. -
FileEntry–One file of an artifact: its store-relative name, size, and content hash.
-
LocalArtifactStore–A directory store:
<root>/<kind>/<adjective-noun-hash8>/holds each committed artifact beside itsartifact.jsonsidecar. -
LockOwner–Who holds a claim, since when, and when it last beat.
-
Produced–What a producer reports: the files it wrote under its workdir (relative,
/-separated) and the tool versions it knows. -
Producer–The cache-miss callback: populate
workdirforspecand report the files written. -
RecordKind–Pairs an artifact kind with the result model its single JSON file holds.
-
RecordOutcome–A served record: the typed value, where it came from, and its key.
-
StoredArtifact–One committed artifact found on disk: its directory and the sidecar inside it.
-
ToolVersions–Provenance of the tools that produced an artifact; never part of its key.
Functions:
-
artifact_dir_of–The artifact directory
pathis or lies inside (the nearest ancestor holding a sidecar), or None. -
artifact_key–The content key of one artifact: the kind's own identity when it overrides one, else the hash of the kind name, its producer version and the spec payload.
-
json_record_kind–Declare a record kind:
namekeysspec_typeinstances to one JSONresult_type. -
keep_alive–Beat
claimeveryinterval_sfrom a daemon thread while the block runs, so a live holder never looks stale. -
sha256_json–Hex SHA-256 of
json.dumps(payload, sort_keys=True)— the one serialization every artifact key shares. -
spec_payload–spec.model_dump(mode="json")with everyHashExclude()field (any depth) plusexcluderemoved — the dict that is hashed and recorded. -
store_root_of–The store root two levels above the artifact directory
pathis or lies inside, or None.
Attributes:
-
ARTIFACT_FILE–The sidecar filename; an artifact exists in a store exactly when this file does, so it is always written last.
ARTIFACT_FILE
module-attribute
¶
The sidecar filename; an artifact exists in a store exactly when this file does, so it is always written last.
ArtifactCache
¶
ArtifactCache(local: LocalArtifactStore, remote: ArtifactStore | None = None, *, poll_s: float = 2.0, heartbeat_s: float = HEARTBEAT_S, verify: bool = False, push_required: bool = False)
Local tier always; an optional remote tier is pulled through on a hit and pushed to after a publish.
Parameters:
-
local(LocalArtifactStore) –The local tier, always consulted first and always published to.
-
remote(ArtifactStore | None, default:None) –The optional remote tier, pulled through on a hit and pushed to after a publish.
-
poll_s(float, default:2.0) –Seconds a producer waits between checks while another claim holds its key.
-
heartbeat_s(float, default:HEARTBEAT_S) –Seconds between refreshes of a held claim while producing.
-
verify(bool, default:False) –Verify file hashes when pulling from the remote tier.
-
push_required(bool, default:False) –Raise when a publish cannot reach the remote tier, instead of logging a warning.
Methods:
-
key–The content key of
specunderkind. -
lookup–The record of an existing artifact in any tier, without materializing it.
-
fetch–A hit-only request: the artifact from whichever tier holds it, else None.
-
get_or_produce–Serve
specfrom a tier, or produce it under an in-flight claim and publish it. -
publish–Commit files that already exist under
source(an in-place kind after the fact); first-wins like any publish. -
push–Copy a locally committed artifact to the remote tier; a failure warns unless
push_required. -
rehydrate–Materialize one referenced artifact into
intoagain; raisesArtifactMissingwhen no tier holds it.
Source code in src/femforge/artifacts/cache.py
key
¶
key(kind: ArtifactKind[S], spec: S) -> ArtifactKey[S]
lookup
¶
lookup(kind: ArtifactKind[S], spec: S) -> ArtifactRecord | None
The record of an existing artifact in any tier, without materializing it.
Source code in src/femforge/artifacts/cache.py
fetch
¶
fetch(kind: ArtifactKind[S], spec: S, into: Path | None) -> ArtifactHandle[S] | None
A hit-only request: the artifact from whichever tier holds it, else None.
Parameters:
-
kind(ArtifactKind[S]) –The artifact kind.
-
spec(S) –The spec that keys the artifact.
-
into(Path | None) –The directory to materialize the files into; None leaves them in the local store.
Source code in src/femforge/artifacts/cache.py
get_or_produce
¶
get_or_produce(kind: ArtifactKind[S], spec: S, into: Path | None, produce: Producer[S] | None = None) -> ArtifactHandle[S]
Serve spec from a tier, or produce it under an in-flight claim and publish it.
Parameters:
-
kind(ArtifactKind[S]) –The artifact kind.
-
spec(S) –The spec that keys the artifact.
-
into(Path | None) –The directory that receives the files, and where an
in_placekind produces; None keeps them in the local store only. -
produce(Producer[S] | None, default:None) –The producer to run on a miss; None uses the kind's own.
Source code in src/femforge/artifacts/cache.py
publish
¶
publish(kind: ArtifactKind[S], spec: S, source: Path, files: Sequence[str], tools: ToolVersions | None = None) -> ArtifactHandle[S]
Commit files that already exist under source (an in-place kind after the fact); first-wins like any publish.
Parameters:
-
kind(ArtifactKind[S]) –The artifact kind.
-
spec(S) –The spec that keys the artifact.
-
source(Path) –The directory holding the files.
-
files(Sequence[str]) –The files to commit, relative to
source. -
tools(ToolVersions | None, default:None) –The tool versions to record; None records only femforge's.
Source code in src/femforge/artifacts/cache.py
push
¶
push(kind: ArtifactKind[S], key: ArtifactKey[S]) -> None
Copy a locally committed artifact to the remote tier; a failure warns unless push_required.
Source code in src/femforge/artifacts/cache.py
rehydrate
¶
rehydrate(ref: ArtifactRef, into: Path, kind: ArtifactKind[S]) -> ArtifactHandle[S]
Materialize one referenced artifact into into again; raises ArtifactMissing when no tier holds it.
Parameters:
-
ref(ArtifactRef) –The reference a consumer recorded.
-
into(Path) –The directory to materialize the files into.
-
kind(ArtifactKind[S]) –The kind whose name the reference must carry.
Source code in src/femforge/artifacts/cache.py
ArtifactClaim
¶
ArtifactCorrupt
¶
Bases: ArtifactError
A stored artifact disagrees with its sidecar.
ArtifactError
¶
Bases: RuntimeError
An artifact-store failure.
ArtifactHandle
dataclass
¶
ArtifactHandle(kind: ArtifactKind[S], key: ArtifactKey[S], origin: ArtifactOrigin, path: Path, record: ArtifactRecord)
A served artifact: where its files are, where they came from, and the record behind them.
Attributes:
-
kind(ArtifactKind[S]) –The kind of artifact served.
-
key(ArtifactKey[S]) –The content key it is stored under.
-
origin(ArtifactOrigin) –Whether the local store held it, a remote tier sent it, or a producer just made it.
-
path(Path) –The local directory that holds its files.
-
record(ArtifactRecord) –The sidecar record that describes it.
-
files(tuple[str, ...]) –The artifact-relative names of its files.
-
ref(ArtifactRef) –The pointer a consumer records.
origin
instance-attribute
¶
origin: ArtifactOrigin
Whether the local store held it, a remote tier sent it, or a producer just made it.
ArtifactKey
¶
Bases: str
A content key (hex SHA-256), phantom-typed by the spec model it was hashed from; name is its readable directory form.
Attributes:
ArtifactKind
dataclass
¶
ArtifactKind(name: str, spec_type: type[S], producer_version: int = 1, required_files: tuple[str, ...] = (), produce: Producer[S] | None = None, key: Callable[[S], str] | None = None, in_place: bool = False)
One class of artifact; a module-level constant callers pass by reference.
Attributes:
-
name(str) –The store path segment (
[a-z0-9_]+; case-insensitive filesystems are in play). -
spec_type(type[S]) –The pydantic model whose instances key this kind.
-
producer_version(int) –Bump to invalidate every existing key of this kind when the producer's output semantics change.
-
required_files(tuple[str, ...]) –Files a complete artifact must contain; publish refuses a producer that left any out.
-
produce(Producer[S] | None) –The default cache-miss producer; None means the caller supplies one per request.
-
key(Callable[[S], str] | None) –An identity override (for a kind whose key must coincide with an existing hash); else the generic hash applies.
-
in_place(bool) –The producer works in the consumer's own directory and publish copies out of it (a run bundle), rather than in a staging dir.
name
instance-attribute
¶
name: str
The store path segment ([a-z0-9_]+; case-insensitive filesystems are in play).
producer_version
class-attribute
instance-attribute
¶
producer_version: int = 1
Bump to invalidate every existing key of this kind when the producer's output semantics change.
required_files
class-attribute
instance-attribute
¶
Files a complete artifact must contain; publish refuses a producer that left any out.
produce
class-attribute
instance-attribute
¶
produce: Producer[S] | None = None
The default cache-miss producer; None means the caller supplies one per request.
key
class-attribute
instance-attribute
¶
An identity override (for a kind whose key must coincide with an existing hash); else the generic hash applies.
ArtifactMissing
¶
Bases: ArtifactError
The requested artifact is in no tier and no producer was given.
ArtifactOrigin
¶
Bases: StrEnum
Where a served artifact came from.
Attributes:
ArtifactRecord
pydantic-model
¶
Bases: BaseModel
The commit marker plus provenance of one stored artifact.
Config:
use_attribute_docstrings:True
Fields:
-
kind(str) -
key(str) -
name(str) -
producer_version(int) -
spec_type(str) -
spec(dict[str, object]) -
files(list[FileEntry]) -
created_at(datetime) -
producer_host(str) -
producer_pid(int) -
tools(ToolVersions)
Validators:
-
_derive_name
name
pydantic-field
¶
name: str = ''
The <adjective>-<noun>-<hash8> store directory name; always derived from key, never read from input.
producer_version
pydantic-field
¶
producer_version: int
The kind's producer version at publish time.
spec_type
pydantic-field
¶
spec_type: str
module:QualName of the spec model, for humans reading the store.
build
classmethod
¶
build(*, kind: str, key: str, producer_version: int, spec_type: str, spec: dict[str, object], workdir: Path, files: Sequence[str], tools: ToolVersions | None = None) -> ArtifactRecord
Assemble the record for the files under workdir, sizing and hashing each.
Parameters:
-
kind(str) –The artifact kind name.
-
key(str) –The content key the artifact is stored under.
-
producer_version(int) –The kind's producer version.
-
spec_type(str) –module:QualNameof the spec model. -
spec(dict[str, object]) –The exact payload hashed into
key. -
workdir(Path) –The directory holding the artifact's files.
-
files(Sequence[str]) –The artifact-relative names of the files.
-
tools(ToolVersions | None, default:None) –The tool versions involved; None records the running femforge release only.
Source code in src/femforge/artifacts/sidecar.py
verify
¶
The names missing under directory or differing in size (and in content, when hashes).
Source code in src/femforge/artifacts/sidecar.py
ArtifactRef
pydantic-model
¶
Bases: BaseModel
A consumer's pointer to a store artifact: enough to re-fetch it and to know which of its files are re-fetchable.
Config:
use_attribute_docstrings:True
Fields:
Validators:
-
_derive_name
name
pydantic-field
¶
name: str = ''
The <adjective>-<noun>-<hash8> store directory name; always derived from key, never read from input.
origin
pydantic-field
¶
origin: ArtifactOrigin
Whether this consumer got a hit, pulled it through from the remote tier, or produced it.
ArtifactStore
¶
Bases: Protocol
One storage tier: an artifact exists exactly when its sidecar can be read, and put is first-wins and atomic.
Methods:
-
record–The committed sidecar of
key, or None when this tier lacks it. -
exists–Whether this tier holds
key. -
fetch–Materialize every file
keylists intointoand return its record. -
put–Commit the files
recordlists undersourceaskey; False when the key already exists. -
delete–Remove
keyfrom this tier. -
keys–Every committed key of
kindin this tier. -
try_claim–Claim
keyfor production so other producers wait; None when another live claim holds it.
record
¶
record(kind: ArtifactKind[S], key: ArtifactKey[S]) -> ArtifactRecord | None
exists
¶
exists(kind: ArtifactKind[S], key: ArtifactKey[S]) -> bool
fetch
¶
fetch(kind: ArtifactKind[S], key: ArtifactKey[S], into: Path, *, verify: bool = False) -> ArtifactRecord
Materialize every file key lists into into and return its record.
Parameters:
-
kind(ArtifactKind[S]) –The artifact kind.
-
key(ArtifactKey[S]) –The artifact's content key.
-
into(Path) –The directory to write the files into.
-
verify(bool, default:False) –Also check each file's sha256.
Source code in src/femforge/artifacts/store.py
put
¶
put(kind: ArtifactKind[S], key: ArtifactKey[S], source: Path, record: ArtifactRecord) -> bool
Commit the files record lists under source as key; False when the key already exists.
Parameters:
-
kind(ArtifactKind[S]) –The artifact kind.
-
key(ArtifactKey[S]) –The artifact's content key.
-
source(Path) –The directory holding the files.
-
record(ArtifactRecord) –The sidecar to commit, listing the files.
Source code in src/femforge/artifacts/store.py
delete
¶
delete(kind: ArtifactKind[S], key: ArtifactKey[S]) -> None
keys
¶
keys(kind: ArtifactKind[S]) -> Iterator[ArtifactKey[S]]
try_claim
¶
try_claim(kind: ArtifactKind[S], key: ArtifactKey[S]) -> ArtifactClaim | None
Claim key for production so other producers wait; None when another live claim holds it.
BuiltinKind
¶
Bases: StrEnum
Store path segments of the built-in kinds; the only place these strings are spelled.
Attributes:
-
STEP–The solve-frame STEP a geometry builds.
-
ELMER_MESH–The Elmer mesh files a config meshes into.
-
RUN_BUNDLE–A finished run bundle.
ELMER_MESH
class-attribute
instance-attribute
¶
The Elmer mesh files a config meshes into.
DirLock
¶
Bases: ArtifactClaim
A claim held as a directory with an owner file; stale (no heartbeat for stale_after_s) claims are broken by the next claimant.
Methods:
-
owner–The recorded owner, or None when the claim is not held or its owner file is unreadable.
-
is_stale–Whether a held claim has gone
stale_after_swithout a heartbeat (the directory mtime stands in for a missing owner file). -
try_acquire–Claim the key; False when another live claim holds it. A stale claim is broken and retried once.
-
heartbeat–Refresh the owner file's heartbeat; a no-op unless this object holds the claim.
-
release–Drop the claim directory: the holder letting go, or a reaper breaking a claim it has proven silent.
Attributes:
Source code in src/femforge/artifacts/lock.py
owner
¶
owner() -> LockOwner | None
The recorded owner, or None when the claim is not held or its owner file is unreadable.
Source code in src/femforge/artifacts/lock.py
is_stale
¶
is_stale() -> bool
Whether a held claim has gone stale_after_s without a heartbeat (the directory mtime stands in for a missing owner file).
Source code in src/femforge/artifacts/lock.py
try_acquire
¶
try_acquire() -> bool
Claim the key; False when another live claim holds it. A stale claim is broken and retried once.
Source code in src/femforge/artifacts/lock.py
heartbeat
¶
Refresh the owner file's heartbeat; a no-op unless this object holds the claim.
Source code in src/femforge/artifacts/lock.py
release
¶
Drop the claim directory: the holder letting go, or a reaper breaking a claim it has proven silent.
FileEntry
pydantic-model
¶
Bases: BaseModel
One file of an artifact: its store-relative name, size, and content hash.
Config:
use_attribute_docstrings:True
Fields:
LocalArtifactStore
¶
Bases: ArtifactStore
A directory store: <root>/<kind>/<adjective-noun-hash8>/ holds each committed artifact beside its artifact.json sidecar.
Parameters:
-
root(str | Path) –The store root, holding one directory per kind.
-
link(bool, default:False) –Hardlink files instead of copying them, where the volume allows.
-
claim_stale_s(float, default:STALE_AFTER_S) –Seconds a claim may go without a heartbeat before another producer breaks it.
Methods:
-
path–Where a committed artifact lives.
-
staging_dir–A fresh, unique workdir for producing
key;putrenames it into place. -
record–The committed sidecar, or None when absent, unreadable (then quarantined), or belonging to a different key that shares the name.
-
exists–Whether
keyis committed underkindwith a readable sidecar. -
fetch–Materialize every file
keylists intointoand return its record. -
materialize–Copy (or link) every listed file of a scanned artifact into
into; returns the paths written. -
put–Commit
sourceaskeyby renaming a staging dir into place; returns False, discarding the copy, when the key already exists. -
delete–Remove the artifact directory of
key; a missing one is not an error. -
committed–The artifact directories under one kind directory: no staging, claims, or quarantines.
-
keys–Every committed key of
kind, read from the sidecars. -
kinds–The kind directories present under the root.
-
read–The artifact committed in
directory, or None when it holds no readable sidecar. -
scan–Every committed artifact under the root (or under one kind), by kind then name.
-
locate–The committed artifacts a human reference names: an artifact directory, a full key, a key prefix of 8+ hex chars, or a
<adjective>-<noun>-<hash8>name. -
try_claim–Claim
keyfor production; None when another live claim holds it.
Source code in src/femforge/artifacts/local.py
path
¶
path(kind: ArtifactKind[S], key: ArtifactKey[S]) -> Path
staging_dir
¶
staging_dir(kind: ArtifactKind[S], key: ArtifactKey[S]) -> Path
A fresh, unique workdir for producing key; put renames it into place.
Source code in src/femforge/artifacts/local.py
record
¶
record(kind: ArtifactKind[S], key: ArtifactKey[S]) -> ArtifactRecord | None
The committed sidecar, or None when absent, unreadable (then quarantined), or belonging to a different key that shares the name.
Source code in src/femforge/artifacts/local.py
exists
¶
exists(kind: ArtifactKind[S], key: ArtifactKey[S]) -> bool
Whether key is committed under kind with a readable sidecar.
fetch
¶
fetch(kind: ArtifactKind[S], key: ArtifactKey[S], into: Path, *, verify: bool = False) -> ArtifactRecord
Materialize every file key lists into into and return its record.
Parameters:
-
kind(ArtifactKind[S]) –The artifact kind.
-
key(ArtifactKey[S]) –The artifact's content key.
-
into(Path) –The directory to write the files into.
-
verify(bool, default:False) –Also check each file's sha256; sizes are always checked.
Source code in src/femforge/artifacts/local.py
materialize
¶
materialize(artifact: StoredArtifact, into: Path, *, verify: bool = False) -> list[Path]
Copy (or link) every listed file of a scanned artifact into into; returns the paths written.
Parameters:
-
artifact(StoredArtifact) –The scanned artifact.
-
into(Path) –The directory to write the files into.
-
verify(bool, default:False) –Also check each file's sha256; sizes are always checked.
Source code in src/femforge/artifacts/local.py
put
¶
put(kind: ArtifactKind[S], key: ArtifactKey[S], source: Path, record: ArtifactRecord) -> bool
Commit source as key by renaming a staging dir into place; returns False, discarding the copy, when the key already exists.
Parameters:
-
kind(ArtifactKind[S]) –The artifact kind.
-
key(ArtifactKey[S]) –The artifact's content key.
-
source(Path) –A staging dir, pruned to the listed files, or any other directory whose listed files are first linked or copied into one.
-
record(ArtifactRecord) –The sidecar to commit, listing the files.
Source code in src/femforge/artifacts/local.py
delete
¶
delete(kind: ArtifactKind[S], key: ArtifactKey[S]) -> None
Remove the artifact directory of key; a missing one is not an error.
committed
¶
The artifact directories under one kind directory: no staging, claims, or quarantines.
Source code in src/femforge/artifacts/local.py
keys
¶
keys(kind: ArtifactKind[S]) -> Iterator[ArtifactKey[S]]
Every committed key of kind, read from the sidecars.
Source code in src/femforge/artifacts/local.py
kinds
¶
The kind directories present under the root.
read
¶
read(directory: Path) -> StoredArtifact | None
The artifact committed in directory, or None when it holds no readable sidecar.
Source code in src/femforge/artifacts/local.py
scan
¶
scan(kind: str | None = None) -> Iterator[StoredArtifact]
Every committed artifact under the root (or under one kind), by kind then name.
Source code in src/femforge/artifacts/local.py
locate
¶
locate(ref: str) -> list[StoredArtifact]
The committed artifacts a human reference names: an artifact directory, a full key, a key prefix of 8+ hex chars, or a <adjective>-<noun>-<hash8> name.
Source code in src/femforge/artifacts/local.py
try_claim
¶
try_claim(kind: ArtifactKind[S], key: ArtifactKey[S]) -> ArtifactClaim | None
Claim key for production; None when another live claim holds it.
Source code in src/femforge/artifacts/local.py
LockOwner
pydantic-model
¶
Bases: BaseModel
Who holds a claim, since when, and when it last beat.
Config:
use_attribute_docstrings:True
Fields:
-
host(str) -
pid(int) -
started_at(datetime) -
heartbeat_at(datetime)
Produced
dataclass
¶
Produced(files: tuple[str, ...], tools: ToolVersions | None = None)
What a producer reports: the files it wrote under its workdir (relative, /-separated) and the tool versions it knows.
Attributes:
-
files(tuple[str, ...]) –The files written, relative to the workdir and
/-separated. -
tools(ToolVersions | None) –The tool versions that made them; None when the producer knows none.
files
instance-attribute
¶
The files written, relative to the workdir and /-separated.
tools
class-attribute
instance-attribute
¶
tools: ToolVersions | None = None
The tool versions that made them; None when the producer knows none.
Producer
¶
RecordKind
dataclass
¶
RecordKind(kind: ArtifactKind[S], result_type: type[R])
Pairs an artifact kind with the result model its single JSON file holds.
Methods:
-
key–The content key of
specunder this kind. -
get_or_produce–The stored value for
spec, elseproduce(spec)written and published under a claim. -
load–The stored value for
spec, or None when no tier holds it. -
load_all–Every value of this kind in the local tier, with the record that identifies it.
Attributes:
-
kind(ArtifactKind[S]) –The artifact kind the records are stored as.
-
result_type(type[R]) –The model the record file is read back into.
key
¶
key(spec: S) -> ArtifactKey[S]
get_or_produce
¶
get_or_produce(cache: ArtifactCache, spec: S, produce: Callable[[S], R]) -> RecordOutcome[S, R]
The stored value for spec, else produce(spec) written and published under a claim.
Parameters:
-
cache(ArtifactCache) –The cache to serve from and publish to.
-
spec(S) –The spec that keys the record.
-
produce(Callable[[S], R]) –Computes the value on a miss.
Source code in src/femforge/artifacts/records.py
load
¶
load(cache: ArtifactCache, spec: S) -> R | None
The stored value for spec, or None when no tier holds it.
Source code in src/femforge/artifacts/records.py
load_all
¶
load_all(cache: ArtifactCache) -> Iterator[tuple[ArtifactRecord, R]]
Every value of this kind in the local tier, with the record that identifies it.
Source code in src/femforge/artifacts/records.py
RecordOutcome
dataclass
¶
RecordOutcome(value: R, origin: ArtifactOrigin, key: ArtifactKey[S])
A served record: the typed value, where it came from, and its key.
Attributes:
-
value(R) –The typed record.
-
origin(ArtifactOrigin) –Whether the local store held it, a remote tier sent it, or
producejust made it. -
key(ArtifactKey[S]) –The content key it is stored under.
origin
instance-attribute
¶
origin: ArtifactOrigin
Whether the local store held it, a remote tier sent it, or produce just made it.
StoredArtifact
dataclass
¶
StoredArtifact(path: Path, record: ArtifactRecord)
One committed artifact found on disk: its directory and the sidecar inside it.
Attributes:
-
path(Path) –The artifact's directory.
-
record(ArtifactRecord) –The sidecar inside it.
-
kind(str) –The artifact kind name.
-
key(str) –The content key the artifact is stored under.
-
name(str) –The artifact's store directory name.
ToolVersions
pydantic-model
¶
Bases: BaseModel
Provenance of the tools that produced an artifact; never part of its key.
Config:
use_attribute_docstrings:True
Fields:
artifact_dir_of
¶
The artifact directory path is or lies inside (the nearest ancestor holding a sidecar), or None.
Source code in src/femforge/artifacts/local.py
artifact_key
¶
artifact_key(kind: ArtifactKind[S], spec: S) -> ArtifactKey[S]
The content key of one artifact: the kind's own identity when it overrides one, else the hash of the kind name, its producer version and the spec payload.
Source code in src/femforge/artifacts/keys.py
json_record_kind
¶
json_record_kind(name: str, *, spec_type: type[S], result_type: type[R], producer_version: int = 1) -> RecordKind[S, R]
Declare a record kind: name keys spec_type instances to one JSON result_type.
Parameters:
-
name(str) –The kind name, which is also its store directory.
-
spec_type(type[S]) –The spec model that keys a record.
-
result_type(type[R]) –The model the record's JSON file holds.
-
producer_version(int, default:1) –Bump to invalidate every stored record of this kind.
Source code in src/femforge/artifacts/records.py
keep_alive
¶
keep_alive(claim: ArtifactClaim, interval_s: float = HEARTBEAT_S) -> Iterator[None]
Beat claim every interval_s from a daemon thread while the block runs, so a live holder never looks stale.
Source code in src/femforge/artifacts/lock.py
sha256_json
¶
Hex SHA-256 of json.dumps(payload, sort_keys=True) — the one serialization every artifact key shares.
spec_payload
¶
spec_payload(spec: BaseModel, *, exclude: Mapping[str | int, object] | None = None) -> dict[str, object]
spec.model_dump(mode="json") with every HashExclude() field (any depth) plus exclude removed — the dict that is hashed and recorded.
Source code in src/femforge/artifacts/keys.py
store_root_of
¶
The store root two levels above the artifact directory path is or lies inside, or None.