Skip to content

Instantly share code, notes, and snippets.

@ugovaretto
Last active April 13, 2022 11:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ugovaretto/99fa2dbed1313f47a2b53bee6623573d to your computer and use it in GitHub Desktop.
Save ugovaretto/99fa2dbed1313f47a2b53bee6623573d to your computer and use it in GitHub Desktop.
Upload data into S3 bucket with AWS Rust S3 SDK
[package]
name = "Upload to S3"
version = "0.1.0"
authors = ["Ugo Varetto <ugo.varetto@csiro.au>"]
edition = 2021
[dependencies]
aws-config = { git = "https://github.com/awslabs/aws-sdk-rust", branch = "next" }
# snippet-start:[s3.rust.s3-object-lambda-cargo.toml]
aws-endpoint = { git = "https://github.com/awslabs/aws-sdk-rust", branch = "next" }
# snippet-end:[s3.rust.s3-object-lambda-cargo.toml]
aws-sdk-s3 = { git = "https://github.com/awslabs/aws-sdk-rust", branch = "next" }
tokio = { version = "1", features = ["full"] }
http = "0.2"
// Upload data to s3 bucket
// Initialisation:
//
// #1
// use aws_config::meta::region::RegionProviderChain;
// let region_provider = RegionProviderChain::default_provider().or_else("us-east-1");
// let config = aws_config::from_env().region(region_provider).load().await;
// let client = Client::new(&config);
// #2
// let conf = aws_config::from_env()
// .credentials_provider(
// aws_config::profile::ProfileFileCredentialsProvider::builder()
// .profile_name("acacia")
// .build())
// .load()
// .await;
// #3
// let conf = aws_config::from_env()
// .credentials_provider(aws_sdk_s3::Credentials::new(
// aws_access_key_id,
// aws_secret_access_key,
// None,
// None,
// "custom profile",
// )).load().await;
//
// MULTIPART UPLOAD:
// let u = client.create_multipart_upload().send().await?;
// if let Some(x) = u.upload_id() {
// let r = client.upload_part().set_upload_id(Some(x.to_owned()));
// }
//let region_provider = RegionProviderChain::default_provider().or_else("us-east-1");
//let config = aws_config::from_env().region(region_provider).load().await;
//let client = Client::new(&config);
//
//let bucket = "bucket";
//let key = "Test.docx";
//
//let purl = client.create_multipart_upload()
// .bucket(bucket)
// .key(key)
// .send()
// .await;
//
//let part_upload = client.upload_part()
// .body(some_data)
// .bucket(bucket)
// .key(key)
// .part_number(1)
// .upload_id(upload_id)
// .send()
// .await;
use aws_sdk_s3::types::ByteStream;
use aws_sdk_s3::{Client, Endpoint, Error}; // snippet-end:[s3.rust.client-use]
use std::path::Path;
#[tokio::main]
async fn main() -> Result<(), aws_sdk_s3::Error> {
let args = std::env::args().collect::<Vec<_>>();
let usage = format!("{} <profile> <url> <bucket> <key> <input file>", args[0]);
let profile = args.get(1).expect(&usage);
let url = args.get(2).expect(&usage);
let bucket = args.get(3).expect(&usage);
let key = args.get(4).expect(&usage);
let file_name = args.get(5).expect(&usage);
// credentials are read from .aws/credentials file
let conf = aws_config::from_env()
.region("us-east-1")
.credentials_provider(
aws_config::profile::ProfileFileCredentialsProvider::builder()
.profile_name(profile)
.build(),
)
.load()
.await;
let uri = url.parse::<http::uri::Uri>().expect("Invalid URL");
let ep = Endpoint::immutable(uri);
let s3_conf = aws_sdk_s3::config::Builder::from(&conf)
.endpoint_resolver(ep)
.build();
let client = Client::from_conf(s3_conf);
upload(&client, &bucket, &file_name, &key).await?;
Ok(())
}
// upload file to bucket/key
use std::time::Instant;
pub async fn upload(
client: &Client,
bucket: &str,
file_name: &str,
key: &str,
) -> Result<(), Error> {
let body = ByteStream::from_path(Path::new(file_name))
.await
.expect(&format!("Cannot read from {}", file_name));
let start = Instant::now();
client
.put_object()
.bucket(bucket)
.key(key)
.body(body)
.send()
.await?;
let elapsed = start.elapsed();
println!(
"Uploaded file {} in {:.2} s",
file_name,
elapsed.as_secs_f32()
);
Ok(())
}
// upload from slice
pub async fn upload_from_memory(
client: &Client,
bucket: &str,
data: &[u8],
key: &str,
) -> Result<(), Error> {
let buf = data.to_vec();
let body = ByteStream::from(buf);
let start = Instant::now();
client
.put_object()
.bucket(bucket)
.key(key)
.content_length(data.len() as i64)
.body(body)
.send()
.await?;
let elapsed = start.elapsed();
println!(
"Uploaded {} bytes in {:.2} s",
data.len(),
elapsed.as_secs_f32()
);
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment