Skip to content

Commit 77bd0a4

Browse files
committed
v1.0.0
1 parent be341b4 commit 77bd0a4

14 files changed

+97
-19
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Changelog
2+
3+
## v1.0.0 - 2024-09-04
4+
5+
- Initial release with create_bucket, delete_bucket, delete_object,
6+
delete_objects, get_object, head_bucket, head_object, list_buckets,
7+
list_objects, and put_object.

README.md

+42-8
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,58 @@
11
# bucket
22

3+
Gleam S3 API client, suitable for AWS S3, Garage, Minio, Storj,
4+
Backblaze B2, Cloudflare R2, Ceph, Wasabi, and so on!
5+
36
[![Package Version](https://img.shields.io/hexpm/v/bucket)](https://hex.pm/packages/bucket)
47
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/bucket/)
58

9+
This package uses the _sans-io_ approach, meaning it does not send HTTP requests
10+
itself, instead it gives you functions for creating HTTP requests for and
11+
decoding HTTP responses from an S3 API, and you send the requests with a HTTP
12+
client of your choosing.
13+
14+
This HTTP client independence gives you full control over HTTP, and means this
15+
library can be used on both the Erlang and JavaScript runtimes.
16+
617
```sh
718
gleam add bucket@1
819
```
920
```gleam
1021
import bucket
22+
import bucket/get_object.{Found}
23+
import gleam/bit_array
24+
import gleam/http.{Https}
25+
import gleam/io
26+
import httpc
1127
28+
/// This program downloads an object and prints the string contents.
29+
///
30+
/// It uses `let assert` to handle errors, but in a real program you'd most
31+
/// likely want to use pattern matching or the `gleam/result` module to handle
32+
/// the error values gracefully.
33+
///
1234
pub fn main() {
13-
// TODO: An example of the project in use
14-
}
15-
```
35+
let creds = bucket.credentials(
36+
host: "s3-api-host.example.com",
37+
access_key_id: "YOUR_ACCESS_KEY",
38+
secret_access_key: "YOUR_SECRET_ACCESS_KEY",
39+
)
1640
17-
Further documentation can be found at <https://hexdocs.pm/bucket>.
41+
// Create a HTTP request to download an object
42+
let request =
43+
get_object.request(bucket: "my-bucket", key: "my/key.txt")
44+
|> get_object.build()
1845
19-
## Development
46+
// Send the HTTP request
47+
let assert Ok(response) = httpc.send_bits(request)
2048
21-
```sh
22-
gleam run # Run the project
23-
gleam test # Run the tests
49+
// Decode the response from the API
50+
let assert Ok(Found(object)) = get_object.response(response)
51+
52+
// Print the string contents
53+
let assert Ok(text) = bit_array.from_string(object)
54+
io.println(text)
55+
}
2456
```
57+
58+
Further documentation can be found at <https://hexdocs.pm/bucket>.

gleam.toml

+6-11
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
name = "bucket"
22
version = "1.0.0"
3-
4-
# Fill out these fields if you intend to generate HTML documentation or publish
5-
# your project to the Hex package manager.
6-
#
7-
# description = ""
8-
# licences = ["Apache-2.0"]
9-
# repository = { type = "github", user = "", repo = "" }
10-
# links = [{ title = "Website", href = "" }]
11-
#
12-
# For a full reference of all the available options, you can have a look at
13-
# https://gleam.run/writing-gleam/gleam-toml/.
3+
description = "Gleam S3 API client, suitable for AWS S3, Garage, Minio, Storj, Backblaze B2, Cloudflare R2, Ceph, Wasabi, and so on!"
4+
licences = ["Apache-2.0"]
5+
repository = { type = "github", user = "lpil", repo = "antigone" }
6+
links = [
7+
{ title = "Sponsor", href = "https://github.com/sponsors/lpil" },
8+
]
149

1510
[dependencies]
1611
gleam_stdlib = ">= 0.34.0 and < 2.0.0"

src/bucket.gleam

+32
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub type BucketError {
99
S3Error(http_status: Int, error: ErrorObject)
1010
}
1111

12+
/// An error from S3.
1213
pub type ErrorObject {
1314
ErrorObject(
1415
code: String,
@@ -18,6 +19,7 @@ pub type ErrorObject {
1819
)
1920
}
2021

22+
/// The creds used to connect to an S3 API.
2123
pub type Credentials {
2224
Credentials(
2325
scheme: Scheme,
@@ -29,6 +31,36 @@ pub type Credentials {
2931
)
3032
}
3133

34+
pub fn credentials(
35+
host: String,
36+
access_key_id: String,
37+
secret_access_key: String,
38+
) -> Credentials {
39+
Credentials(
40+
host:,
41+
access_key_id:,
42+
secret_access_key:,
43+
region: "eu-west-1",
44+
port: option.None,
45+
scheme: http.Https,
46+
)
47+
}
48+
49+
/// Set the region for the credentials.
50+
pub fn with_region(creds: Credentials, region: String) -> Credentials {
51+
Credentials(..creds, region:)
52+
}
53+
54+
/// Set the port for the credentials.
55+
pub fn with_port(creds: Credentials, port: Int) -> Credentials {
56+
Credentials(..creds, port: option.Some(port))
57+
}
58+
59+
/// Set the scheme for the credentials. You should use HTTPS unless not possible.
60+
pub fn with_scheme(creds: Credentials, scheme: http.Scheme) -> Credentials {
61+
Credentials(..creds, scheme:)
62+
}
63+
3264
pub type Bucket {
3365
Bucket(name: String, creation_date: String)
3466
}

src/bucket/create_bucket.gleam

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import gleam/option.{type Option}
88
import gleam/string_builder
99
import xmb
1010

11+
/// The parameters for the API request
1112
pub type RequestBuilder {
1213
RequestBuilder(name: String, region: Option(String))
1314
}

src/bucket/delete_bucket.gleam

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import gleam/http/request.{type Request, Request}
55
import gleam/http/response.{type Response}
66
import gleam/option.{type Option}
77

8+
/// The parameters for the API request
89
pub type RequestBuilder {
910
RequestBuilder(name: String, expected_bucket_owner: Option(String))
1011
}

src/bucket/delete_object.gleam

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import gleam/http
44
import gleam/http/request.{type Request, Request}
55
import gleam/http/response.{type Response}
66

7+
/// The parameters for the API request
78
pub type RequestBuilder {
89
RequestBuilder(bucket: String, key: String)
910
}

src/bucket/delete_objects.gleam

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import gleam/result
1212
import gleam/string_builder
1313
import xmb
1414

15+
/// The parameters for the API request
1516
pub type RequestBuilder {
1617
RequestBuilder(bucket: String, objects: List(ObjectIdentifier))
1718
}

src/bucket/get_object.gleam

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import gleam/http
66
import gleam/http/request.{type Request, Request}
77
import gleam/http/response.{type Response}
88

9+
/// The parameters for the API request
910
pub type RequestBuilder {
1011
RequestBuilder(bucket: String, key: String)
1112
}

src/bucket/head_bucket.gleam

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import gleam/http/request.{type Request, Request}
77
import gleam/http/response.{type Response}
88
import gleam/option.{type Option}
99

10+
/// The parameters for the API request
1011
pub type RequestBuilder {
1112
RequestBuilder(name: String, expected_bucket_owner: Option(String))
1213
}

src/bucket/head_object.gleam

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import gleam/http/request.{type Request, Request}
77
import gleam/http/response.{type Response}
88
import gleam/option.{type Option}
99

10+
/// The parameters for the API request
1011
pub type RequestBuilder {
1112
RequestBuilder(
1213
bucket: String,

src/bucket/list_buckets.gleam

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub type ListAllMyBucketsResult {
1414
)
1515
}
1616

17+
/// The parameters for the API request
1718
pub type RequestBuilder {
1819
RequestBuilder(continuation_token: Option(String), max_buckets: Option(Int))
1920
}

src/bucket/list_objects.gleam

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub type Object {
1515
Object(key: String, last_modified: String, etag: String, size: Int)
1616
}
1717

18+
/// The parameters for the API request
1819
pub type RequestBuilder {
1920
RequestBuilder(
2021
bucket: String,

src/bucket/put_object.gleam

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub type PutObjectResult {
1010
PutObjectResult(etag: String)
1111
}
1212

13+
/// The parameters for the API request
1314
pub type RequestBuilder {
1415
RequestBuilder(bucket: String, key: String, body: BitArray)
1516
}

0 commit comments

Comments
 (0)