Skip to main content

azure_storage_blob/generated/clients/
blob_service_client.rs

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT License.
3//
4// Code generated by Microsoft (R) Rust Code Generator. DO NOT EDIT.
5
6use crate::generated::models::{
7    BlobServiceClientFindBlobsByTagsOptions, BlobServiceClientGetAccountInfoOptions,
8    BlobServiceClientGetAccountInfoResult, BlobServiceClientGetPropertiesOptions,
9    BlobServiceClientGetStatisticsOptions, BlobServiceClientGetUserDelegationKeyOptions,
10    BlobServiceClientListContainersOptions, BlobServiceClientSetPropertiesOptions,
11    BlobServiceProperties, FilteredBlobResponse, KeyInfo, ListContainersResponse,
12    StorageServiceStats,
13};
14use azure_core::{
15    error::CheckSuccessOptions,
16    fmt::SafeDebug,
17    http::{
18        pager::{PagerContinuation, PagerResult, PagerState},
19        ClientOptions, Method, NoFormat, Pager, Pipeline, PipelineSendOptions, RawResponse,
20        Request, RequestContent, Response, Url, UrlExt, XmlFormat,
21    },
22    tracing, xml, Result,
23};
24use azure_storage_common::models::UserDelegationKey;
25
26#[tracing::client]
27pub struct BlobServiceClient {
28    pub(crate) endpoint: Url,
29    pub(crate) pipeline: Pipeline,
30    pub(crate) version: String,
31}
32
33/// Options used when creating a `BlobServiceClient`
34#[derive(Clone, SafeDebug)]
35pub struct BlobServiceClientOptions {
36    /// Allows customization of the client.
37    pub client_options: ClientOptions,
38    /// Specifies the version of the operation to use for this request.
39    pub version: String,
40}
41
42impl BlobServiceClient {
43    /// Lists blobs across all containers whose tags match a given search expression.
44    ///
45    /// # Arguments
46    ///
47    /// * `filter_expression` - Filters the results to return only blobs whose tags match the specified expression.
48    /// * `options` - Optional parameters for the request.
49    #[tracing::function("Storage.Blob.BlobServiceClient.findBlobsByTags")]
50    pub fn find_blobs_by_tags(
51        &self,
52        filter_expression: &str,
53        options: Option<BlobServiceClientFindBlobsByTagsOptions<'_>>,
54    ) -> Result<Pager<FilteredBlobResponse, XmlFormat>> {
55        let options = options.unwrap_or_default().into_owned();
56        let pipeline = self.pipeline.clone();
57        let mut first_url = self.endpoint.clone();
58        let mut query_builder = first_url.query_builder();
59        query_builder.append_pair("comp", "blobs");
60        if let Some(include) = options.include.as_ref() {
61            query_builder.set_pair(
62                "include",
63                include
64                    .iter()
65                    .map(|i| i.to_string())
66                    .collect::<Vec<String>>()
67                    .join(","),
68            );
69        }
70        if let Some(marker) = options.marker.as_ref() {
71            query_builder.set_pair("marker", marker);
72        }
73        if let Some(maxresults) = options.maxresults {
74            query_builder.set_pair("maxresults", maxresults.to_string());
75        }
76        if let Some(timeout) = options.timeout {
77            query_builder.set_pair("timeout", timeout.to_string());
78        }
79        query_builder.set_pair("where", filter_expression);
80        query_builder.build();
81        #[derive(serde::Deserialize)]
82        struct BlobServiceClientFindBlobsByTagsPage {
83            #[serde(rename = "NextMarker")]
84            next_marker: Option<String>,
85        }
86
87        let version = self.version.clone();
88        Ok(Pager::new(
89            move |marker: PagerState, pager_options| {
90                let mut url = first_url.clone();
91                if let PagerState::More(marker) = marker {
92                    let mut query_builder = url.query_builder();
93                    query_builder.set_pair("marker", marker.as_ref());
94                    query_builder.build();
95                }
96                let mut request = Request::new(url, Method::Get);
97                request.insert_header("accept", "application/xml");
98                request.insert_header("x-ms-version", &version);
99                let pipeline = pipeline.clone();
100                Box::pin(async move {
101                    let rsp = pipeline
102                        .send(
103                            &pager_options.context,
104                            &mut request,
105                            Some(PipelineSendOptions {
106                                check_success: CheckSuccessOptions {
107                                    success_codes: &[200],
108                                },
109                                ..Default::default()
110                            }),
111                        )
112                        .await?;
113                    let (status, headers, body) = rsp.deconstruct();
114                    let res: BlobServiceClientFindBlobsByTagsPage = xml::from_xml(&body)?;
115                    let rsp = RawResponse::from_bytes(status, headers, body).into();
116                    Ok(match res.next_marker {
117                        Some(next_marker) if !next_marker.is_empty() => PagerResult::More {
118                            response: rsp,
119                            continuation: PagerContinuation::Token(next_marker),
120                        },
121                        _ => PagerResult::Done { response: rsp },
122                    })
123                })
124            },
125            Some(options.method_options),
126        ))
127    }
128
129    /// Returns information about the storage account.
130    ///
131    /// # Arguments
132    ///
133    /// * `options` - Optional parameters for the request.
134    ///
135    /// ## Response Headers
136    ///
137    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobServiceClientGetAccountInfoResultHeaders`] trait, which provides
138    /// access to response headers. For example:
139    ///
140    /// ```no_run
141    /// use azure_core::{Result, http::{Response, NoFormat}};
142    /// use azure_storage_blob::models::{BlobServiceClientGetAccountInfoResult, BlobServiceClientGetAccountInfoResultHeaders};
143    /// async fn example() -> Result<()> {
144    ///     let response: Response<BlobServiceClientGetAccountInfoResult, NoFormat> = unimplemented!();
145    ///     // Access response headers
146    ///     if let Some(account_kind) = response.account_kind()? {
147    ///         println!("x-ms-account-kind: {:?}", account_kind);
148    ///     }
149    ///     if let Some(is_hierarchical_namespace_enabled) = response.is_hierarchical_namespace_enabled()? {
150    ///         println!("x-ms-is-hns-enabled: {:?}", is_hierarchical_namespace_enabled);
151    ///     }
152    ///     if let Some(sku_name) = response.sku_name()? {
153    ///         println!("x-ms-sku-name: {:?}", sku_name);
154    ///     }
155    ///     Ok(())
156    /// }
157    /// ```
158    ///
159    /// ### Available headers
160    /// * [`account_kind`()](crate::generated::models::BlobServiceClientGetAccountInfoResultHeaders::account_kind) - x-ms-account-kind
161    /// * [`is_hierarchical_namespace_enabled`()](crate::generated::models::BlobServiceClientGetAccountInfoResultHeaders::is_hierarchical_namespace_enabled) - x-ms-is-hns-enabled
162    /// * [`sku_name`()](crate::generated::models::BlobServiceClientGetAccountInfoResultHeaders::sku_name) - x-ms-sku-name
163    ///
164    /// [`BlobServiceClientGetAccountInfoResultHeaders`]: crate::generated::models::BlobServiceClientGetAccountInfoResultHeaders
165    #[tracing::function("Storage.Blob.BlobServiceClient.getAccountInfo")]
166    pub async fn get_account_info(
167        &self,
168        options: Option<BlobServiceClientGetAccountInfoOptions<'_>>,
169    ) -> Result<Response<BlobServiceClientGetAccountInfoResult, NoFormat>> {
170        let options = options.unwrap_or_default();
171        let ctx = options.method_options.context.to_borrowed();
172        let mut url = self.endpoint.clone();
173        let mut query_builder = url.query_builder();
174        query_builder
175            .append_pair("comp", "properties")
176            .append_pair("restype", "account");
177        if let Some(timeout) = options.timeout {
178            query_builder.set_pair("timeout", timeout.to_string());
179        }
180        query_builder.build();
181        let mut request = Request::new(url, Method::Get);
182        request.insert_header("x-ms-version", &self.version);
183        let rsp = self
184            .pipeline
185            .send(
186                &ctx,
187                &mut request,
188                Some(PipelineSendOptions {
189                    check_success: CheckSuccessOptions {
190                        success_codes: &[200],
191                    },
192                    ..Default::default()
193                }),
194            )
195            .await?;
196        Ok(rsp.into())
197    }
198
199    /// Retrieves properties of a storage account's Blob service, including properties for Storage Analytics and CORS (Cross-Origin
200    /// Resource Sharing) rules.
201    ///
202    /// # Arguments
203    ///
204    /// * `options` - Optional parameters for the request.
205    #[tracing::function("Storage.Blob.BlobServiceClient.getProperties")]
206    pub async fn get_properties(
207        &self,
208        options: Option<BlobServiceClientGetPropertiesOptions<'_>>,
209    ) -> Result<Response<BlobServiceProperties, XmlFormat>> {
210        let options = options.unwrap_or_default();
211        let ctx = options.method_options.context.to_borrowed();
212        let mut url = self.endpoint.clone();
213        let mut query_builder = url.query_builder();
214        query_builder
215            .append_pair("comp", "properties")
216            .append_pair("restype", "service");
217        if let Some(timeout) = options.timeout {
218            query_builder.set_pair("timeout", timeout.to_string());
219        }
220        query_builder.build();
221        let mut request = Request::new(url, Method::Get);
222        request.insert_header("accept", "application/xml");
223        request.insert_header("x-ms-version", &self.version);
224        let rsp = self
225            .pipeline
226            .send(
227                &ctx,
228                &mut request,
229                Some(PipelineSendOptions {
230                    check_success: CheckSuccessOptions {
231                        success_codes: &[200],
232                    },
233                    ..Default::default()
234                }),
235            )
236            .await?;
237        Ok(rsp.into())
238    }
239
240    /// Retrieves statistics related to replication for the Blob service. It is only available on the secondary location endpoint
241    /// when read-access geo-redundant replication is enabled for the storage account.
242    ///
243    /// # Arguments
244    ///
245    /// * `options` - Optional parameters for the request.
246    #[tracing::function("Storage.Blob.BlobServiceClient.getStatistics")]
247    pub async fn get_statistics(
248        &self,
249        options: Option<BlobServiceClientGetStatisticsOptions<'_>>,
250    ) -> Result<Response<StorageServiceStats, XmlFormat>> {
251        let options = options.unwrap_or_default();
252        let ctx = options.method_options.context.to_borrowed();
253        let mut url = self.endpoint.clone();
254        let mut query_builder = url.query_builder();
255        query_builder
256            .append_pair("comp", "stats")
257            .append_pair("restype", "service");
258        if let Some(timeout) = options.timeout {
259            query_builder.set_pair("timeout", timeout.to_string());
260        }
261        query_builder.build();
262        let mut request = Request::new(url, Method::Get);
263        request.insert_header("accept", "application/xml");
264        request.insert_header("x-ms-version", &self.version);
265        let rsp = self
266            .pipeline
267            .send(
268                &ctx,
269                &mut request,
270                Some(PipelineSendOptions {
271                    check_success: CheckSuccessOptions {
272                        success_codes: &[200],
273                    },
274                    ..Default::default()
275                }),
276            )
277            .await?;
278        Ok(rsp.into())
279    }
280
281    /// Retrieves a user delegation key for the Blob service. This is only a valid operation when using bearer token authentication.
282    ///
283    /// # Arguments
284    ///
285    /// * `key_info` - Key information provided in the request.
286    /// * `options` - Optional parameters for the request.
287    #[tracing::function("Storage.Blob.BlobServiceClient.getUserDelegationKey")]
288    pub async fn get_user_delegation_key(
289        &self,
290        key_info: RequestContent<KeyInfo, XmlFormat>,
291        options: Option<BlobServiceClientGetUserDelegationKeyOptions<'_>>,
292    ) -> Result<Response<UserDelegationKey, XmlFormat>> {
293        let options = options.unwrap_or_default();
294        let ctx = options.method_options.context.to_borrowed();
295        let mut url = self.endpoint.clone();
296        let mut query_builder = url.query_builder();
297        query_builder
298            .append_pair("comp", "userdelegationkey")
299            .append_pair("restype", "service");
300        if let Some(timeout) = options.timeout {
301            query_builder.set_pair("timeout", timeout.to_string());
302        }
303        query_builder.build();
304        let mut request = Request::new(url, Method::Post);
305        request.insert_header("accept", "application/xml");
306        request.insert_header("content-type", "application/xml");
307        request.insert_header("x-ms-version", &self.version);
308        request.set_body(key_info);
309        let rsp = self
310            .pipeline
311            .send(
312                &ctx,
313                &mut request,
314                Some(PipelineSendOptions {
315                    check_success: CheckSuccessOptions {
316                        success_codes: &[200],
317                    },
318                    ..Default::default()
319                }),
320            )
321            .await?;
322        Ok(rsp.into())
323    }
324
325    /// Returns a list of the containers in the specified account.
326    ///
327    /// # Arguments
328    ///
329    /// * `options` - Optional parameters for the request.
330    #[tracing::function("Storage.Blob.BlobServiceClient.listContainers")]
331    pub fn list_containers(
332        &self,
333        options: Option<BlobServiceClientListContainersOptions<'_>>,
334    ) -> Result<Pager<ListContainersResponse, XmlFormat>> {
335        let options = options.unwrap_or_default().into_owned();
336        let pipeline = self.pipeline.clone();
337        let mut first_url = self.endpoint.clone();
338        let mut query_builder = first_url.query_builder();
339        query_builder.append_pair("comp", "list");
340        if let Some(include) = options.include.as_ref() {
341            query_builder.set_pair(
342                "include",
343                include
344                    .iter()
345                    .map(|i| i.to_string())
346                    .collect::<Vec<String>>()
347                    .join(","),
348            );
349        }
350        if let Some(marker) = options.marker.as_ref() {
351            query_builder.set_pair("marker", marker);
352        }
353        if let Some(maxresults) = options.maxresults {
354            query_builder.set_pair("maxresults", maxresults.to_string());
355        }
356        if let Some(prefix) = options.prefix.as_ref() {
357            query_builder.set_pair("prefix", prefix);
358        }
359        if let Some(timeout) = options.timeout {
360            query_builder.set_pair("timeout", timeout.to_string());
361        }
362        query_builder.build();
363        #[derive(serde::Deserialize)]
364        struct BlobServiceClientListContainersPage {
365            #[serde(rename = "NextMarker")]
366            next_marker: Option<String>,
367        }
368
369        let version = self.version.clone();
370        Ok(Pager::new(
371            move |marker: PagerState, pager_options| {
372                let mut url = first_url.clone();
373                if let PagerState::More(marker) = marker {
374                    let mut query_builder = url.query_builder();
375                    query_builder.set_pair("marker", marker.as_ref());
376                    query_builder.build();
377                }
378                let mut request = Request::new(url, Method::Get);
379                request.insert_header("accept", "application/xml");
380                request.insert_header("x-ms-version", &version);
381                let pipeline = pipeline.clone();
382                Box::pin(async move {
383                    let rsp = pipeline
384                        .send(
385                            &pager_options.context,
386                            &mut request,
387                            Some(PipelineSendOptions {
388                                check_success: CheckSuccessOptions {
389                                    success_codes: &[200],
390                                },
391                                ..Default::default()
392                            }),
393                        )
394                        .await?;
395                    let (status, headers, body) = rsp.deconstruct();
396                    let res: BlobServiceClientListContainersPage = xml::from_xml(&body)?;
397                    let rsp = RawResponse::from_bytes(status, headers, body).into();
398                    Ok(match res.next_marker {
399                        Some(next_marker) if !next_marker.is_empty() => PagerResult::More {
400                            response: rsp,
401                            continuation: PagerContinuation::Token(next_marker),
402                        },
403                        _ => PagerResult::Done { response: rsp },
404                    })
405                })
406            },
407            Some(options.method_options),
408        ))
409    }
410
411    /// Sets properties for a storage account's Blob service endpoint, including properties for Storage Analytics and CORS (Cross-Origin
412    /// Resource Sharing) rules.
413    ///
414    /// # Arguments
415    ///
416    /// * `storage_service_properties` - The storage service properties to set.
417    /// * `options` - Optional parameters for the request.
418    #[tracing::function("Storage.Blob.BlobServiceClient.setProperties")]
419    pub async fn set_properties(
420        &self,
421        storage_service_properties: RequestContent<BlobServiceProperties, XmlFormat>,
422        options: Option<BlobServiceClientSetPropertiesOptions<'_>>,
423    ) -> Result<Response<(), NoFormat>> {
424        let options = options.unwrap_or_default();
425        let ctx = options.method_options.context.to_borrowed();
426        let mut url = self.endpoint.clone();
427        let mut query_builder = url.query_builder();
428        query_builder
429            .append_pair("comp", "properties")
430            .append_pair("restype", "service");
431        if let Some(timeout) = options.timeout {
432            query_builder.set_pair("timeout", timeout.to_string());
433        }
434        query_builder.build();
435        let mut request = Request::new(url, Method::Put);
436        request.insert_header("content-type", "application/xml");
437        request.insert_header("x-ms-version", &self.version);
438        request.set_body(storage_service_properties);
439        let rsp = self
440            .pipeline
441            .send(
442                &ctx,
443                &mut request,
444                Some(PipelineSendOptions {
445                    check_success: CheckSuccessOptions {
446                        success_codes: &[202],
447                    },
448                    ..Default::default()
449                }),
450            )
451            .await?;
452        Ok(rsp.into())
453    }
454}
455
456/// Default value for [`BlobServiceClientOptions::version`].
457pub(crate) const DEFAULT_VERSION: &str = "2026-04-06";
458
459impl Default for BlobServiceClientOptions {
460    fn default() -> Self {
461        Self {
462            client_options: ClientOptions::default(),
463            version: String::from(DEFAULT_VERSION),
464        }
465    }
466}