Skip to content

client.artifacts

View as Markdown

client.artifacts — the artifacts operations.

On AsyncKindgi every method is the same, awaited.

list(
*,
limit: int | None = None,
cursor: str | None = None,
owner_run_id: str | UUID | None = None,
content_type: str | None = None,
project_id: str | UUID | None = None,
timeout: float | None = None,
) -> ArtifactCollectionPage
Signature

List artifact metadata. GET /v1/artifacts

Cursor-paginated. Metadata rows only (no bytes). Filters: ?ownerRunId=, ?projectId=, ?contentType=, ?tag.<key>=<value> (repeatable — every provided tag must match as AND). Sort order is binding-defined (typically createdAt desc, blobId desc). With authorization on, only artifacts in projects the caller can read are listed.

upload(
files: Mapping[str, Any],
/,
*,
idempotency_key: str | None = None,
data: Mapping[str, Any] | None = None,
timeout: float | None = None,
) -> BlobMeta
Signature

Upload an artifact. POST /v1/artifacts

Multipart upload. file part carries the bytes; other form fields carry metadata (name, contentType, tags (JSON), ownerRunId, projectId, expectedHash). Framework computes sha256 and returns it in BlobMeta.hash. If expectedHash was supplied and diverges, response is 400 blob-hash-mismatch. Content-type sniffing is NOT performed server-side — the framework trusts the caller. The artifact belongs to its owner run's project, else projectId, else the project the caller's API key is limited to, else the tenant's default project; uploading needs write there, and a key limited to a project uploads into that project only. An upload over the runtime's cap (default 100 MiB) is 413 artifact-too-large.

download(blob_id: str | UUID, /, *, timeout: float | None = None) -> bytes
Signature

Download an artifact (stream). GET /v1/artifacts/{blobId}

Streams raw bytes. Response headers: Content-Type (as declared at upload), Content-Length, X-Kindgi-Blob-Hash (sha256 hex), X-Kindgi-Blob-Name (URI-encoded caller name).

delete(
blob_id: str | UUID,
/,
*,
idempotency_key: str | None = None,
timeout: float | None = None,
) -> DeleteArtifactResult
Signature

Delete an artifact. DELETE /v1/artifacts/{blobId}

Idempotent: first call returns { deleted: true }, subsequent calls return { deleted: false } (already gone). The route responds 200 either way — 404 only when the id was never known (structurally impossible after list returned it).