s3-filesystem

Crates.ios3-filesystem
lib.rss3-filesystem
version0.0.1
sourcesrc
created_at2023-11-10 11:50:01.683136
updated_at2023-11-10 11:50:01.683136
descriptionA crate to sync files on AWS S3 to your local machine.
homepagehttps://github.com/AnBowell/s3-filesystem
repositoryhttps://github.com/AnBowell/s3-filesystem
max_upload_size
id1030979
size22,093
Andrew Bowell (AnBowell)

documentation

https://docs.rs/s3-filesystem/latest/s3-filesystem/

README

s3-filesystem

This crate is a simple wrapper for file interactions with S3. It enables you to open a file, write a file, and perform a walk through the objects in an S3 bucket. Both reading and writing will create a copy on your machine to make S3 feel as much like your local file system as possible.

This crate utilises the official AWS SDK for S3 operations and uses Tokio for local IO.

When using the crate, be careful! Writing files can overwrite data previously there and using S3 will incur costs.

Usage

First create an OpenOptions struct containing the bucket you wish to connect to and where you wish files to be cached to.

There are then three functions available

  • [crate::OpenOptions::open_s3]: Downloads the file and opens it and returns a Tokio File for data to be read from as standard.

  • [crate::OpenOptions::write_s3]: Writes the file to disk and to S3, returning the Tokio File.

  • [crate::OpenOptions::walkdir]: Walks through the objects in the S3 bucket, with an optional path to walk through a subset of objects.

Open a file

use s3_filesystem::OpenOptions;
use tokio::io::AsyncReadExt;

#[tokio::main]
async fn main() {
    let bucket = "my_aws_s3_bucket".to_string();


    // If a custom S3 client is needed, replace None with Some(client).
    // Default behavior is to use AWS CLI env.
    let open_options = OpenOptions::new(bucket, None)
        .await
        .mount_path("data/test/")
        .force_download(true);

    let mut file = open_options.open_s3("some_folder/some_file.csv").await.unwrap();

    let mut string = String::new();

    // Read the example file and print it.
    file.read_to_string(&mut string).await.unwrap();

    println!("String: {}", string);

}

Write a file

use s3_filesystem::OpenOptions;
use tokio::fs;

const BUCKET: &'static str = "test-bucket";

#[tokio::main]
async fn main() {
    let bucket = BUCKET.to_string();

    let open_options = OpenOptions::new(bucket, None)
        .await
        .mount_path("data/test/")
        .force_download(true);

    let data = fs::read("data/manifest.txt").await.unwrap();

    open_options.write_s3("manifest.txt", &data).await.unwrap();

    println!("Data uploaded successfully");
}

Walkdir

use s3_filesystem::OpenOptions;

#[tokio::main]
async fn main() {
    let bucket = "my_aws_s3_bucket".to_string();

    let open_options = OpenOptions::new(bucket, None).await;
   
    let data = open_options.walkdir("").await.unwrap();

    for dat in data {
        println!("Data: {:?}", dat);
    }
}

Walkdir and download

use s3_filesystem::OpenOptions;

#[tokio::main]
async fn main() {
    let bucket = "my_aws_s3_bucket".to_string();

    let open_options = OpenOptions::new(bucket, None)
        .await
        .mount_path("data/test/")
        .force_download(false);

    let data = open_options

        .walkdir("some_bucket_sub_folder")
        .await
        .unwrap();

    // WARNING!
    // Downloads and opens every file in the sub folder!
    for entry in data {
        if entry.folder {
            continue;
        }

        let s3_stuff = open_options.open_s3(&entry.path).await.unwrap();

        println!("Entry: {:?} downloaded", entry.path);
    }
}



TODOs

  • Add feature flags for automatic decompression?
  • Look for changes in the file? If bytes is different download, if not read from cache. Beats generic force download config.

Test on more operating systems with more edge cases - currently little testing has occurred.

Commit count: 9

cargo fmt