Skip to main content

artefaktum

Python client and CLI for Artefaktum: store, find and trust the artifacts that AI agents hand to each other.

Install

pip install artefaktum          # the client
pip install "artefaktum[cli]"   # plus the `artefaktum` command

Python 3.10+. The only dependency is httpx.

Quick start

Create an API key in the console and export it as ARTEFAKTUM_API_KEY.

from artefaktum import Artefaktum

client = Artefaktum()
artifact = client.artifacts.push("report.pdf", title="Q3 churn", tags=["churn"])
hits = client.artifacts.search("q3 churn")
client.artifacts.pull(hits.items[0].artifact.id, "out/")

Configuration

Explicit argument, then environment variable, then default.

Argument Environment variable Default
api_key ARTEFAKTUM_API_KEY required
base_url ARTEFAKTUM_BASE_URL https://api.artefaktum.dev
project ARTEFAKTUM_PROJECT default

project is a slug or a UUID. Project-scoped methods take a per-call project= override.

Uploading

client.artifacts.push("data/export.parquet", title="Export")  # a path, streamed
client.artifacts.push(payload, title="Export", filename="export.json")  # bytes
client.artifacts.create_version(artifact.id, "data/export-v2.parquet")

push hashes the source, uploads it straight to object storage (the API key is never sent there) and waits until the artifact is ready. wait=False returns as soon as the upload is accepted.

Compute once, reuse everywhere

r = client.artifacts.resolve(
    "openweather/vilnius/2026-09-21",
    filename="weather.json",
    content_type="application/json",
    size_bytes=len(body),
    title="Vilnius weather",
    max_age=3600,
)
if r.status == "hit":
    use(r.artifact)
elif r.status == "create":
    client.artifacts.fulfil(r, body)
else:
    ...  # "pending": another producer is already making it

Reuse or replace by key

from datetime import timedelta

# Reuse: an artifact under this key younger than an hour is returned, nothing is uploaded.
a = client.artifacts.push(
    body,
    filename="weather.json",
    title="Vilnius weather",
    external_key="openweather/vilnius",
    if_exists="reuse",
    max_age=timedelta(hours=1),
)
print(a.reused)  # True when an existing artifact came back (set by the SDK, not the API)

# Replace: add a version to the artifact holding the key, or create it when the key is new.
client.artifacts.push(
    body,
    filename="weather.json",
    title="Vilnius weather",
    external_key="openweather/vilnius",
    if_exists="version",
)

# Read it back by key; a `max_age` older artifact is NotFound.
client.artifacts.pull_by_key("openweather/vilnius", "out/", max_age=timedelta(hours=1))

if_exists is "error" (the default: an existing key is a Conflict), "version" or "reuse"; both need external_key, and max_age only applies to "reuse". With "reuse", a push that finds another producer already making the artifact waits up to timeout seconds, then raises ProcessingTimeout.

Downloading

client.artifacts.pull(artifact.id, "out/")  # into a directory, server-side filename
client.artifacts.pull(artifact.id, "out/report.pdf")  # to an exact path

pull verifies the sha256 digest and raises IntegrityError on a mismatch. A string ending in / is a directory, created if needed.

Finding

client.artifacts.search("emission factors", mode="hybrid", tags_all=["ghg"])
client.artifacts.get_by_external_key("reports/q3-churn")
for a in client.artifacts.iter_all(tag="churn"):
    print(a.title)

Search hides superseded artifacts by default; each hit says whether it is superseded or stale_upstream.

Everything else

client.artifacts: get, list, update, delete, versions, relations, add_relation, download_url, create_upload, complete_upload. client.runs: create, seal, artifacts. client.projects.list(). client.keys and client.usage (admin scope). client.whoami(), client.quota().

Async

AsyncArtefaktum mirrors every method as a coroutine; iter_all becomes an async generator.

import asyncio
from artefaktum import AsyncArtefaktum


async def main():
    async with AsyncArtefaktum() as client:
        await client.artifacts.push("report.pdf", title="Q3 churn")
        async for a in client.artifacts.iter_all(tag="churn"):
            print(a.id)


asyncio.run(main())

Command line

artefaktum login                          # prompts for the key, saves it with mode 0600
artefaktum push report.pdf --title "Q3 churn" --tag churn
artefaktum search "q3 churn"
artefaktum pull <artifact-id> out/
artefaktum get --key vendor-x/report/2026-09 --max-age 1h
artefaktum pull --key vendor-x/report/2026-09 out/
artefaktum push report.pdf --title "Q3 churn" --key q3-churn --if-exists reuse --max-age 1d

push --if-exists is error (default), version (add a version to the artifact holding --key) or reuse (return that artifact, uploading only if there is none or it is older than --max-age). Under reuse the output gains reused, and --wait SECONDS (default 60) is, with reuse, the seconds to wait on another writer and then again for the artifact to become ready (ignored otherwise; --timeout is ignored under reuse). pull --key K takes its destination as --dest.

afk is a shorter alias. Output is a table on a terminal and JSON when piped; --json / --table force either. The key comes from --api-key, then ARTEFAKTUM_API_KEY, then the saved config. Exit codes: 0 ok, 1 API error, 2 usage error, 3 not found, 4 push --if-exists reuse still pending after --wait, 130 interrupted.

Commands: push, pull, get, ls, search, relate, relations, versions, link, rm, projects, whoami, login, logout. artefaktum --help has the details.

Errors

Every failure is an ArtefaktumError with code, status and request_id (quote it when contacting support). Subclasses: NotFound, Unauthorized, Forbidden, QuotaExceeded, RequestTooLarge, Conflict, ValidationFailed, UploadError, ServiceUnavailable, StorageError, ProcessingFailed, ProcessingTimeout, IntegrityError. MissingApiKey is a ValueError raised before any request is made.

from artefaktum import NotFound

try:
    client.artifacts.get(artifact_id)
except NotFound as e:
    print(e.code, e.request_id)

QuotaExceeded means a plan limit is reached: 413 for storage or file size, 429 for the month's API calls. client.quota() reports the plan, its limits and current usage.

RequestTooLarge (413, code request_too_large) means the JSON request itself is over 256 KB, almost always because of oversized metadata. It has nothing to do with the size of your file. Field limits are listed at https://artefaktum.dev/docs/rest/#limits.

Reads are retried up to 3 attempts on 429, 502, 503, 504 and connection errors, honouring Retry-After. Writes and storage transfers are never retried.

Issues and contributions

Open an issue for bugs and questions. Pull requests are welcome; they are applied upstream and land here with the next release rather than being merged directly.

License

MIT

Metadata

Release files for artefaktum 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for artefaktum 0.3.0
File Size Uploaded Provenance
artefaktum-0.3.0.tar.gz 78.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for artefaktum 0.3.0
File Interpreter ABI Platform
artefaktum-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 126.4 kB

Release files / artefaktum-0.3.0.tar.gz

Download URL artefaktum-0.3.0.tar.gz
Size 78.7 kB
Tags Source
SHA-256 checksum
How to use checksums
c1a456d6a8b6f3e128dcfcaa20284ae48d81d3d469e7f1f5cc33dc37077c006e
BLAKE2b-256 checksum
How to use checksums
a17585e197ea4107c41b793fd4dba977fa6f3b9e3cd739d76d509f6e55ad3fe6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / artefaktum-0.3.0-py3-none-any.whl

Download URL artefaktum-0.3.0-py3-none-any.whl
Size 47.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7e73ec28bfff064f9aa405ffd9e11e640f45804ee3821114f3858f135180e12c
BLAKE2b-256 checksum
How to use checksums
4bdcce7ffcdf7d16a5e2fcbd133f48f475c0f0d536ce613452e96ec3bcf4420e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for artefaktum 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for artefaktum-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page