Skip to content

Commit 226307e

Browse files
alambclaude
andauthored
Add doc example for multipart upload to MicrosoftAzure::create_multipart (#802)
Add a runnable (`no_run`) example on the `MultipartStore` impl for `MicrosoftAzure` showing the full low-level flow: `create_multipart`, `put_part` for each part, and `complete_multipart` to finalize. Also link to the example from `MultipartStore::create_multipart` so it is discoverable from the trait definition. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c7316d2 commit 226307e

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

src/azure/mod.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,59 @@ impl MultipartUpload for AzureMultiPartUpload {
304304

305305
#[async_trait]
306306
impl MultipartStore for MicrosoftAzure {
307+
/// Create a new multipart upload, returning its [`MultipartId`].
308+
///
309+
/// This is the low-level [`MultipartStore`] API, which gives direct control
310+
/// over individual parts. See [`ObjectStoreExt::put_multipart`] for a
311+
/// higher-level API that handles parts automatically.
312+
///
313+
/// # Example
314+
///
315+
/// Create a multipart upload, upload two parts, and finalize it by calling
316+
/// [`complete_multipart`]:
317+
///
318+
/// ```no_run
319+
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
320+
/// # use object_store::{azure::MicrosoftAzureBuilder, multipart::MultipartStore, path::Path, PutPayload};
321+
/// #
322+
/// let azure = MicrosoftAzureBuilder::new()
323+
/// .with_account("my-account")
324+
/// .with_container_name("my-container")
325+
/// .with_access_key("my-access-key")
326+
/// .build()?;
327+
///
328+
/// let path = Path::from("data/large_file");
329+
///
330+
/// // Start the upload, obtaining an id used to reference it in later calls
331+
/// let id = azure.create_multipart(&path).await?;
332+
///
333+
/// // Upload the individual parts. Azure stores each part as a block.
334+
/// let part0 = azure
335+
/// .put_part(&path, &id, 0, PutPayload::from("the first part"))
336+
/// .await?;
337+
/// let part1 = azure
338+
/// .put_part(&path, &id, 1, PutPayload::from("the final part"))
339+
/// .await?;
340+
///
341+
/// // Finalize the upload. The parts must be provided in `part_idx` order.
342+
/// azure.complete_multipart(&path, &id, vec![part0, part1]).await?;
343+
/// # Ok(())
344+
/// # }
345+
/// ```
346+
///
347+
/// Azure stores each part as a block, so a single blob may contain at most
348+
/// 50,000 parts, each up to 4,000 MiB. Parts may be uploaded concurrently and
349+
/// in any order, provided each is given the correct `part_idx`. See
350+
/// [Azure block blob limits] for the full set of size and count constraints.
351+
///
352+
/// Azure has no way to explicitly discard uploaded blocks, so
353+
/// [`abort_multipart`] is a no-op: any uncommitted blocks are automatically
354+
/// garbage collected roughly one week after the last write.
355+
///
356+
/// [`ObjectStoreExt::put_multipart`]: crate::ObjectStoreExt::put_multipart
357+
/// [`complete_multipart`]: MultipartStore::complete_multipart
358+
/// [`abort_multipart`]: MultipartStore::abort_multipart
359+
/// [Azure block blob limits]: https://learn.microsoft.com/en-us/rest/api/storageservices/put-block
307360
async fn create_multipart(&self, _: &Path) -> Result<MultipartId> {
308361
Ok(String::new())
309362
}

0 commit comments

Comments
 (0)