Upload files
Files reach Labric through a signed storage URL: you ask the API for an upload URL, PUT the bytes to that URL, then confirm the upload. Only the two small JSON requests pass through the API; the bytes go straight to storage. The SDK does all three steps in one call, and the REST API exposes each step so any HTTP client can run them.
Every upload names its source. Pass job_execution_id to store the file as an artifact of a job execution, which also records provenance linking the file to that run, or instrument_id to attach the file to an instrument the Sync app cannot reach so its triggers and parsers pick it up. At least one of the two is required.
Prerequisites
- An API key with the write scope, created under Settings > API Keys on platform.labric.co and exported as
LABRIC_API_KEY - For the SDK, Python 3.9 or later with
pip install labric
Upload with the SDK
client.files.upload() takes an open file, bytes, or a (filename, content) tuple and returns the stored file’s record once its bytes are confirmed:
The platform records a filename, so pass a tuple when the content has no name of its own. The content type is guessed from the filename unless you supply one:
Inside a Labric job, job_execution_id defaults to the LABRIC_JOB_EXECUTION_ID environment variable, so a script running in the sandbox can omit it. Open files are streamed in 1 MiB chunks, so a large file never sits in memory.
client.files.create_upload_url() and client.files.confirm_upload() are also available for scripts that want to drive the steps themselves, for example to hand the PUT to another process.
Upload with the REST API
1. Create an upload URL
The response holds the file’s ID, the signed URL, the headers the PUT must carry, and when the URL expires:
2. PUT the bytes to the URL
Send the file as the request body with exactly the returned headers and no Authorization header. The URL is signed for those headers, so changing or omitting one makes storage reject the request.
3. Confirm the upload
Confirming records the stored file’s size and checksum, makes the file visible in listings, and notifies triggers and parsers. Until then the file does not appear anywhere. The response is the same record client.files.upload() returns.
Limits and retries
- An upload URL is valid for 15 minutes. If it expires or the PUT fails, request a new URL. For an unconfirmed upload at the same instrument path, the API returns a fresh URL for the same file ID instead of a conflict.
- The URL only creates an object; a second PUT to a used URL is refused by storage with a 412.
- Storage refuses bodies over 500 MB before they are stored. Files that turn out to be native executables are discarded at confirmation with a 400.
- An instrument can hold one file per name, so a name already confirmed for that instrument is a 409. Job artifacts have no such constraint.
Small files in one request
POST /api/v1/files accepts a single multipart/form-data request for files under 4.5 MB, which is the request body limit at the platform edge. It takes the same job_execution_id and instrument_id fields as form parts. Use it when a one-request upload is simpler than the signed flow and the file is small.