Keep files with a run
This guide keeps a file in the runtime with the run it came from, then finds it, downloads it and deletes it.
A file kept in the runtime is an artifact, such as a report a run's output became, a document your app sent in, or an export. Each one belongs to a project, and can name the run it came from. Its name, type, size and sha256 are kept in the runtime's database. Its bytes are kept on disk, in a Google Cloud Storage bucket, or in an S3 bucket.
Before you start
Section titled “Before you start”- A runtime that keeps artifacts.
kindgi devkeeps them in the pack's.kindgi/dev/artifacts. Another runtime keeps them once you turn them on. - Kindgi 0.2's CLI, and a file to keep, such as
report.pdf. - A run's id, to keep the file with that run.
Upload one
Section titled “Upload one”Uploading the file keeps it with its run:
pnpm exec kindgi artifacts upload report.pdf --run=<run-id> --content-type=application/pdf --tag=kind=summaryreport.pdfis the file to upload.--run=<run-id>is the run it came from, where<run-id>is the run's id.--content-typeis its type,application/octet-streamunless you say.--tag=key=valuelabels it. You can give it more than once.
It prints the artifact's record, with its blobId.
- Its project: with
--run, it's the run's project. Without--run, it's--project's, or else the workspace's default project. A--projectthat isn't the run's is refused, and so is a run that doesn't exist, with404 run-not-found. With an API key limited to a project, an upload that names no project goes to the key's project. One whose project, named or its run's, is another is refused with403 key-project-mismatch. - Its name is the file's, unless
--namegives another. - Its size: the runtime refuses a bigger upload than its cap, 100 MiB by
default. It answers
413 artifact-too-large, with the cap indetails.maxBytes.
From your app, in TypeScript, artifacts.upload sends the file. download
streams it back, and head reads what's kept without the bytes.
Find and download them
Section titled “Find and download them”Listing a run's artifacts gives each one's id, which you read and download it by:
pnpm exec kindgi artifacts list --run=<run-id> --tablepnpm exec kindgi artifacts get <blob-id>pnpm exec kindgi artifacts download <blob-id> -o report.pdflistis newest first.--run,--projectand--content-typenarrow it, and--tableprints a table instead of JSON.<blob-id>is an artifact'sblobId, from the list.getgives an artifact's name, type, size and sha256, without its bytes.downloadwrites the file under its own name in this directory, unless-onames one. It keeps a file that's already there, unless you add--force.downloadfirst writes to a new file next to the one it saves, and moves it into place only once the whole file has arrived and its sha256 is the one the server sent. A download that fails leaves no file, and with--forcethe file already there stays as it was.- One Ctrl-C (or
SIGTERM) stopsdownload, whether it's still waiting for the server or part way through the file. As after a failure, it leaves no file, and a file already there stays as it was. It sayskindgi artifacts download stopped: no file was written.and exits with code 130. - Ended at once, by a second Ctrl-C or
kill -9,downloadcan leave that new file behind: the file's name, then 8 hex digits, then.partial, such asreport.pdf.1a2b3c4d.partial. You can delete it.
A download is checked against the sha256 and size kept for the artifact. If
its bytes were changed in their store outside the runtime, on disk or in the
bucket, the download stops part way: the runtime closes the connection
before the last of its Content-Length bytes. download then fails with
the download stopped part way (…): report.pdf wasn't written, and writes
no file. In TypeScript, reading download's body throws. The runtime logs
each one at ERROR, as
Artifact <blob-id>'s stored bytes aren't the ones put; the read was stopped,
with its workspace, where its bytes are kept, the sha256 and size kept for it,
and what was read. The log line never holds the file's content.
With authorization on, listing and
downloading need read on the artifact's project, and uploading and deleting
need write. An artifact you can't read answers 404, as if it weren't
there, and lists leave it out.
Delete one
Section titled “Delete one”pnpm exec kindgi artifacts delete <blob-id><blob-id> is the artifact's blobId. It's gone from lists and downloads
at once. Its record and bytes stay until a retention policy on artifact
purges them, as Keep and purge deleted data
describes.
Turn them on
Section titled “Turn them on”The runtime keeps artifacts once KINDGI_ARTIFACTS says where their bytes
go:
local:<absolute directory>: a directory on the runtime's machine.gcs:<bucket>[/<prefix>]: a Google Cloud Storage bucket, reached with the runtime's own Google identity, its Application Default Credentials. So there's no key to store.s3:<bucket>[/<prefix>](runtime 0.4.0 or later): an S3 bucket, on AWS with the runtime's own AWS identity, or in an S3-compatible store such as MinIO or Cloudflare R2.
Without it, the runtime serves no artifacts. kindgi dev keeps them in the
pack's .kindgi/dev/artifacts. KINDGI_ARTIFACT_MAX_BYTES sets the upload
cap. The startup output says where artifacts go, or that they're off.
Choose where the runtime keeps files
has each one's settings and permissions, and what the runtime checks at
startup.