Skip to main content

Elixir / Phoenix

ExAws is the AWS SDK for Elixir. It supports any S3-compatible service via configuration overrides.

Install

mix.exs
defp deps do
[
{:ex_aws, "~> 2.5"},
{:ex_aws_s3, "~> 2.5"},
{:hackney, "~> 1.20"},
{:sweet_xml, "~> 0.7"},
]
end

Configure

config/runtime.exs
import Config

config :ex_aws,
access_key_id: System.fetch_env!("FILEBASE_KEY"),
secret_access_key: System.fetch_env!("FILEBASE_SECRET"),
region: "auto"

config :ex_aws, :s3,
scheme: "https://",
host: "s3.filebase.io",
port: 443

List buckets

{:ok, %{body: %{buckets: buckets}}} = ExAws.S3.list_buckets() |> ExAws.request()

Enum.each(buckets, fn b -> IO.puts(b.name) end)

Create a bucket

ExAws.S3.put_bucket("my-bucket", "auto") |> ExAws.request()

Upload an object

{:ok, body} = File.read("photo.jpg")

ExAws.S3.put_object("my-bucket", "photo.jpg", body, content_type: "image/jpeg")
|> ExAws.request()

For large files, use the streaming uploader:

"./video.mp4"
|> ExAws.S3.Upload.stream_file()
|> ExAws.S3.upload("my-bucket", "video.mp4", content_type: "video/mp4")
|> ExAws.request()

This streams the file in 5 MB parts and uses multipart upload automatically.

List objects

{:ok, %{body: body}} =
ExAws.S3.list_objects_v2("my-bucket", prefix: "photos/")
|> ExAws.request()

Enum.each(body.contents, fn obj ->
IO.puts("#{obj.key} #{obj.size}")
end)

For paginated streaming over arbitrary numbers of objects:

ExAws.S3.list_objects_v2("my-bucket", prefix: "photos/")
|> ExAws.stream!()
|> Enum.each(fn obj -> IO.puts(obj.key) end)

Download an object

{:ok, %{body: data}} =
ExAws.S3.get_object("my-bucket", "photo.jpg")
|> ExAws.request()

File.write!("./downloaded.jpg", data)

Delete an object

ExAws.S3.delete_object("my-bucket", "photo.jpg") |> ExAws.request()

Pre-signed URLs

config = ExAws.Config.new(:s3)

{:ok, url} =
ExAws.S3.presigned_url(config, :get, "my-bucket", "private.pdf",
expires_in: 3600
)

IO.puts(url)

# Pre-signed PUT
{:ok, upload_url} =
ExAws.S3.presigned_url(config, :put, "uploads", "user-#{user_id}/#{filename}",
expires_in: 600,
query_params: [{"Content-Type", "image/jpeg"}]
)

Phoenix LiveView uploads

For LiveView, use live_file_input and shovel the chunks to Filebase via ExAws in your LiveView module.

What's next