Crates.io | ossify |
lib.rs | ossify |
version | 0.1.3 |
created_at | 2025-08-06 06:24:39.330026+00 |
updated_at | 2025-09-25 08:07:04.197737+00 |
description | A modern, easy-to-use, and reqwest-powered Rust SDK for Alibaba Cloud Object Storage Service (OSS) |
homepage | |
repository | https://github.com/honsunrise/ossify |
max_upload_size | |
id | 1783464 |
size | 336,602 |
A modern, easy-to-use, and reqwest-powered Rust SDK for Alibaba Cloud Object Storage Service (OSS). Built with developer experience in mind, this SDK provides a clean, intuitive API that makes working with OSS straightforward and enjoyable.
reqwest
HTTP client with full async/await supportAdd this to your Cargo.toml
:
[dependencies]
ossify = "0.1.0"
tokio = { version = "1.0", features = ["full"] }
use ossify::Client;
use ossify::ops::bucket::BucketOperations;
use ossify::ops::object::base::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a client
let client = Client::builder()
.endpoint("https://oss-cn-hangzhou.aliyuncs.com")
.region("cn-hangzhou")
.bucket("my-bucket")
.access_key_id("your-access-key-id")
.access_key_secret("your-access-key-secret")
.build()?;
// Upload a file
let data = b"Hello, OSS!";
let response = client.put_object("hello.txt", data, None).await?;
println!("Upload successful! ETag: {}", response.etag);
// Download the file
let content = client.get_object("hello.txt", Default::default(), None).await?;
println!("Downloaded content: {}", String::from_utf8_lossy(&content));
Ok(())
}
use ossify::ops::bucket::*;
// Create a bucket
let config = PutBucketConfiguration::new();
client.put_bucket(config, None).await?;
// List objects
let options = ListObjectsOptions::new().max_keys(100);
let result = client.list_objects(Some(options)).await?;
// Get bucket info
let info = client.get_bucket_info().await?;
println!("Bucket: {}, Location: {}", info.name, info.location);
// Delete bucket
client.delete_bucket().await?;
use ossify::ops::object::base::*;
// Upload object with options
let options = PutObjectOptions::new()
.content_type("text/plain")
.storage_class(StorageClass::Standard);
client.put_object("file.txt", data, Some(options)).await?;
// Download with range
let params = GetObjectParams::new();
let options = GetObjectOptions::new().range("bytes=0-1023");
let content = client.get_object("file.txt", params, Some(options)).await?;
// Get object metadata
let metadata = client.head_object("file.txt", None).await?;
println!("Size: {}, Last Modified: {:?}", metadata.content_length, metadata.last_modified);
// Delete object
client.delete_object("file.txt", None).await?;
use ossify::ops::object::multipart_upload::*;
// Initialize multipart upload
let result = client.initiate_multipart_upload("large-file.bin", None).await?;
let upload_id = result.upload_id;
// Upload parts
let part1 = client.upload_part("large-file.bin", &upload_id, 1, &chunk1).await?;
let part2 = client.upload_part("large-file.bin", &upload_id, 2, &chunk2).await?;
// Complete upload
let parts = vec![
Part::new(1, part1.etag),
Part::new(2, part2.etag),
];
let options = CompleteMultipartUploadOptions::new().parts(parts);
client.complete_multipart_upload("large-file.bin", &upload_id, Some(options)).await?;
The SDK provides a flexible builder pattern for configuration:
use ossify::{Client, UrlStyle};
use std::time::Duration;
let client = Client::builder()
.endpoint("https://oss-cn-hangzhou.aliyuncs.com")
.public_endpoint("https://oss-cn-hangzhou.aliyuncs.com") // Optional
.region("cn-hangzhou")
.bucket("my-bucket")
.access_key_id("your-access-key-id")
.access_key_secret("your-access-key-secret")
.security_token("your-sts-token") // Optional, for temporary credentials
.http_timeout(Duration::from_secs(30))
.url_style(UrlStyle::VirtualHosted) // VirtualHosted, Path, or CName
.build()?;
https://bucket.oss-cn-hangzhou.aliyuncs.com/object
https://oss-cn-hangzhou.aliyuncs.com/bucket/object
https://custom-domain.com/object
The SDK supports multiple authentication methods:
// Basic credentials
let client = Client::builder()
.access_key_id("your-key")
.access_key_secret("your-secret")
.build()?;
// With STS token (temporary credentials)
let client = Client::builder()
.access_key_id("your-key")
.access_key_secret("your-secret")
.security_token("your-sts-token")
.build()?;
Generate presigned URLs for secure, temporary access:
use ossify::QueryAuthOptions;
let auth_options = QueryAuthOptions::builder()
.expires_in(3600) // 1 hour
.build()?;
let url = client.presign_get_object(
"private-file.jpg",
true, // public endpoint
GetObjectParams::new(),
None,
auth_options
).await?;
println!("Presigned URL: {}", url);
Efficient handling of large files with streaming:
// The SDK uses reqwest's streaming capabilities internally
// for efficient memory usage with large objects
Comprehensive error types for robust applications:
use ossify::Error;
match client.get_object("nonexistent.txt", Default::default(), None).await {
Ok(content) => println!("File content: {:?}", content),
Err(Error::HttpError(status)) if status.as_u16() == 404 => {
println!("File not found");
},
Err(e) => eprintln!("Error: {}", e),
}
This SDK is built with modern Rust practices:
tokio
and reqwest
Cow
and Bytes
For detailed documentation and examples, visit:
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the MIT License - see the LICENSE file for details.
Happy coding with OSS and Rust! 🦀✨