Skip to main content

async_http_array_read/
async_http_array_read.rs

1#![allow(missing_docs)]
2
3use std::sync::Arc;
4
5use ndarray::ArrayD;
6use zarrs::array::{Array, ArraySubset};
7use zarrs::storage::AsyncReadableStorage;
8use zarrs::storage::storage_adapter::usage_log::UsageLogStorageAdapter;
9
10enum Backend {
11    // OpenDAL,
12    ObjectStore,
13}
14
15async fn http_array_read(backend: Backend) -> Result<(), Box<dyn std::error::Error>> {
16    const HTTP_URL: &str =
17        "https://raw.githubusercontent.com/zarrs/zarrs/main/zarrs/tests/data/array_write_read.zarr";
18    const ARRAY_PATH: &str = "/group/array";
19
20    // Create a HTTP store
21    let mut store: AsyncReadableStorage = match backend {
22        // Backend::OpenDAL => {
23        //     let builder = opendal::services::Http::default().endpoint(HTTP_URL);
24        //     let operator = opendal::Operator::new(builder)?.finish();
25        //     Arc::new(zarrs_opendal::AsyncOpendalStore::new(operator))
26        // }
27        Backend::ObjectStore => {
28            let options = object_store::ClientOptions::new().with_allow_http(true);
29            let store = object_store::http::HttpBuilder::new()
30                .with_url(HTTP_URL)
31                .with_client_options(options)
32                .build()?;
33            Arc::new(zarrs_object_store::AsyncObjectStore::new(store))
34        }
35    };
36    if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
37        && arg1 == "--usage-log"
38    {
39        let log_writer = Arc::new(std::sync::Mutex::new(
40            // std::io::BufWriter::new(
41            std::io::stdout(),
42            //    )
43        ));
44        store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
45            chrono::Utc::now().format("[%T%.3f] ").to_string()
46        }));
47    }
48
49    // Init the existing array, reading metadata
50    let array = Array::async_open(store, ARRAY_PATH).await?;
51
52    println!(
53        "The array metadata is:\n{}\n",
54        array.metadata().to_string_pretty()
55    );
56
57    // Read the whole array
58    let data_all: ArrayD<f32> = array
59        .async_retrieve_array_subset(&array.subset_all())
60        .await?;
61    println!("The whole array is:\n{data_all}\n");
62
63    // Read a chunk back from the store
64    let chunk_indices = vec![1, 0];
65    let data_chunk: ArrayD<f32> = array.async_retrieve_chunk(&chunk_indices).await?;
66    println!("Chunk [1,0] is:\n{data_chunk}\n");
67
68    // Read the central 4x2 subset of the array
69    let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
70    let data_4x2: ArrayD<f32> = array.async_retrieve_array_subset(&subset_4x2).await?;
71    println!("The middle 4x2 subset is:\n{data_4x2}\n");
72
73    Ok(())
74}
75
76#[tokio::main]
77async fn main() -> Result<(), Box<dyn std::error::Error>> {
78    println!("------------ object_store backend ------------");
79    http_array_read(Backend::ObjectStore).await?;
80    // println!("------------   opendal backend    ------------");
81    // http_array_read(Backend::OpenDAL).await?;
82    Ok(())
83}