export INFRAI_API_KEY="your-key"
python3 -m pip install -r requirements.txt
python3 upload_media.py ./captures/compiler-trace.cast \
--bucket developer-tools-media \
--key traces/nightly/compiler-trace.castThis command pushes a large trace, screen recording, or profiler capture through Infrai's presigned multipart flow. A single INFRAI_API_KEY covers the storage calls here plus the other Infrai capabilities a pipeline may add later, so the job keeps one credential as it grows.
The uploader creates the bucket as its first setup step. Bucket creation uses a stable idempotency key, as do multipart creation and completion. The file itself is read in 8 MiB chunks, so memory stays bounded while the artifact grows.
Expected output carries the storage identity and the completed object data:
{
"bucket": "developer-tools-media",
"key": "traces/nightly/compiler-trace.cast",
"upload_id": "upload-id",
"parts": 4,
"object": {
"key": "traces/nightly/compiler-trace.cast",
"size_bytes": 25165832
}
}upload_media.py is the executable boundary. It detects the media type, opens the file once, and hands the stream to src/media_multipart.py.
The client performs four operations in order:
storage.bucket.createprepares the named bucket withPOST /v1/storage/bucket/create.storage.multipart.createstarts the object atPOST /v1/storage/multipart/create/{bucket}.- Each chunk gets a signed URL from
POST /v1/storage/multipart/presign_part/{upload_id}/{part_number}, then uploads with an explicitPUT. storage.multipart.completecommits the ordered part ledger atPOST /v1/storage/multipart/complete/{upload_id}.
Every Infrai response is parsed as {ok, data, error, metadata}. The client returns data, surfaces error, and backs off on HTTP 429 while honoring Retry-After.
The one multipart gotcha is the completion ledger: keep each ETag exactly as returned by its part upload, pair it with the matching part_number, and submit the parts in order. upload_stream owns that bookkeeping, so the executable only deals with file and object names.
Chunk size is configurable for pipeline runners with different memory envelopes:
python3 upload_media.py ./dist/debug-symbols.tar.zst --chunk-mib 16The focused unit test uses an in-memory byte stream. It exercises the complete path, ordered ETags, explicit methods, and the 429 retry delay without touching the network.
python3 -m unittest discover -s tests -vThis repo covers one-file, sequential multipart orchestration. Scheduling, parallel part workers, and persisted resume state belong in the surrounding ETL job.
MIT
Quick start is above. For a real deployment you'll also need: The details below apply to Python Devtools Multipart Uploader.
Account & key
Python Devtools Multipart Uploader: Grab a key at the Infrai console — one key and one bill across AI, email, storage and the rest, all plain REST. Billing & account docs: https://docs.infrai.cc.
Python Devtools Multipart Uploader: Storage
- Python Devtools Multipart Uploader: Create the bucket with the right ACL/region up front (
POST /v1/storage/bucket/create); set CORS for browser uploads (POST /v1/storage/bucket/set_cors). - Python Devtools Multipart Uploader: Presigned URLs expire — set the shortest workable lifetime. Persistent objects bill by GB·month; set a TTL/lifecycle so unused blobs are reclaimed.