Mesh Storage
Upload Files
Upload MCAP recordings and metadata sidecars from Python
Use alloy.storage when you already have files on disk and want them to land directly in Mesh Storage.
from alloy import storage
with storage.connect() as store:
store.upload_folder("local/run-001", path="flights/run-001")Folder uploads
upload_folder(local_folder, path=...) walks the folder recursively and preserves relative paths below that folder. Every file in the folder must be a supported type. One unsupported file stops the whole upload with AlloyStorageTransferError before any file uploads.
local/run-001/
├── metadata.json
├── drone-a/
│ └── flight.mcap
└── drone-b/
└── flight.mcapfrom alloy import storage
with storage.connect() as store:
result = store.upload_folder(
"local/run-001",
path="flights/run-001",
overwrite=False,
)
print(result.prefix)
# uploads/sdk-uploads/flights/run-001/The resulting Mesh keys are:
uploads/sdk-uploads/flights/run-001/metadata.json
uploads/sdk-uploads/flights/run-001/drone-a/flight.mcap
uploads/sdk-uploads/flights/run-001/drone-b/flight.mcapSingle-file uploads
upload_file(local_path, path=...) treats path as a folder and uploads the local file into that folder using the local basename.
from alloy import storage
with storage.connect() as store:
result = store.upload_file(
"local/run-001/flight.mcap",
path="flights/run-001",
overwrite=False,
)
print(result.files[0].key)
# uploads/sdk-uploads/flights/run-001/flight.mcapPath rules
path is a Mesh folder below the SDK upload root:
uploads/sdk-uploads/<path>/Pass this:
flights/run-001Do not pass:
uploads/sdk-uploads/flights/run-001
uploads/flights/run-001
s3://bucket/flights/run-001
flights/run-001/If you omit path, Alloy generates a dated folder such as:
2026-06-24/4c9033de-6e7d-4d9a-8c34-9b4ab10e6bb7The upload result includes the concrete generated path and prefix.
Supported files
The high-level upload helpers support:
| File type | Extension |
|---|---|
| MCAP recordings | .mcap |
| JSON sidecars | .json |
| YAML sidecars | .yml, .yaml |
Metadata sidecars upload before MCAP files. This makes sidecar metadata available to the ingestion path before the recording is processed.
Alloy reads a .json, .yml, or .yaml file as sidecar metadata only when its file name contains metadata, for example metadata.json or run_metadata.yaml. The sidecar must be in the MCAP's folder or a parent folder. Alloy uses the closest match.
Overwrite behaviour
overwrite=False is the supported high-level SDK upload mode.
from alloy import storage
with storage.connect() as store:
store.upload_folder("local/run-001", path="flights/run-001", overwrite=False)Before uploading, the SDK checks every target key. If any key already exists, it raises AlloyStorageConflictError before uploading the new batch.
from alloy import storage
try:
storage.upload_file("flight.mcap", path="flights/run-001", overwrite=False)
except storage.AlloyStorageConflictError as exc:
print(exc)overwrite=True raises immediately. Delete or replace files through the Mesh deletion workflow before uploading a replacement.
What happens after upload
Uploaded files appear in Mesh Storage under uploads/sdk-uploads/. Each MCAP goes through the normal lifecycle:
- Queued - the file has landed and is waiting for processing
- Ingesting - Alloy is parsing the MCAP and building queryable tables
- Ingested - SQL and external query paths can read the processed data
- Ingest failed - processing failed; hover the status for details
Replay and Inspect work as soon as the MCAP lands. SQL requires the file to show Ingested.
One-shot helpers
For short scripts, use module-level helpers. They open and close a client for one operation.
from alloy import storage
storage.upload_folder("local/run-001", path="flights/run-001")
storage.upload_file("local/run-001/flight.mcap", path="flights/run-001")Async one-shots are available too:
from alloy import storage
await storage.async_upload_folder("local/run-001", path="flights/run-001")
await storage.async_upload_file("local/run-001/flight.mcap", path="flights/run-001")Use a long-lived client when you are doing more than one operation.