Large Attachment Upload
This page uses the beta V3 scratch file and attachment endpoints. Set early_access="true" on the
client or send the EARLY-ACCESS: true header on raw HTTP requests. See the
V3 Stability Guidelines.
V2 files larger than 10MB had to be split into parts and reassembled. The V3 API
has no multipart upload: a file goes to a scratch file’s presigned upload URL in a single PUT, and an
attachment is created from the scratch file. For a large file, the only care needed is to stream it from
disk instead of reading it into memory.
Store your attachment ID
Attachments are not searchable on their own. If you do not persist the ID before linking the attachment to a parent object, it is lost and the file has to be re-uploaded.
To link the attachment once it is uploaded, see Uploading an Attachment to Benchling. For an image read out of a spreadsheet, see Image File Upload.
V3 upload
Configuration
The V3 SDK,
httpx(installed with the SDK), the tenant URL, and an API key. Pass the tenant’s root URL; the SDK adds/api/v3itself.The key is inline here for demonstration only. Benchling credentials should not be stored in source code. See Authentication for the alternatives.
Choose the file
The file name and location are arbitrary examples; substitute your own.
Create a scratch file
The response carries the
upload_urlthe file goes to.Stream the file to the upload URL
Passing the open file as
contentmakeshttpxread it in chunks and send it with aContent-Lengthheader, so the whole file is never held in memory. Thex-amz-server-side-encryption: AES256header is required, and theContent-Typeheader becomes the attachment’s MIME type.- Timeout
httpxtimes out after five seconds by default, which a large upload can exceed.timeout=Noneturns the timeout off; set a limit that suits your file sizes instead if you prefer.
Mark the upload finished
Set the scratch file’s
upload_statustoSUCCEEDEDonce thePUThas returned.Create the attachment and keep its ID
Create the attachment from the scratch file, then store its ID for linking. This example prints it to the console.
V2 multipart upload
V3 has no multipart endpoints, so this flow uses the V2 blob endpoints. It splits the file into parts, uploads each one, and completes the upload so Benchling can reassemble it. Mixing the two API versions in one integration is supported, and both accept the same API key.
Configuration
A few built-in libraries, plus the tenant URL and API key.
The key is inline here for demonstration only. Benchling credentials should not be stored in source code. See Authentication for the alternatives.
Read the file in chunks
A generator that reads the file a chunk at a time. Every part except the last has to be at least 5MB and no more than 10MB.
- Choosing a chunk size
Both sizes are a byte or two over the round number so the chunk length is divisible by 3, which avoids base64 padding mid-file. Either works; pick what suits your implementation.
Encode and hash helpers
Two more helpers: one base64-encodes a chunk, the other takes its MD5 hash. Note that the hash is of the raw chunk, not of its base64 encoding.
Start the multipart upload
POST /api/v2/blobs:start-multipart-uploadreturns metadata about the upload, most importantly theid, which is theblob_idevery later call needs.Upload a single part
Each response from
POST /api/v2/blobs/{id}/partscarries the part’spartNumberand aneTagUUID. Both are required by the final step, so store them for every part.If an upload fails partway through, abort it with
POST /api/v2/blobs/{id}:abort-upload.Complete the multipart upload
Once every part is uploaded,
POST /api/v2/blobs/{id}:complete-uploadfinishes the job. Its body carries apartsarray of thepartNumberandeTagof each part. That serves two purposes: telling Benchling the upload is done, and giving Benchling a way to confirm it received every part it was expecting.Open the file
The file name and location are arbitrary examples; substitute your own.
Start the upload and keep the blob ID
Start the upload with the filename, then store the
blob_idfor the part uploads that follow.Number the parts
partNumbervalues do not have to be consecutive, but they must be unique and ascending.Upload each part
For every chunk, encode it, hash it, upload it as a blob part, and append the response to
part_data, which becomes thepartsarray in the final request.Complete the upload
One final request once all the chunks are up.
Log the result
This example prints to the console. Substitute your own logging or post-upload work.