Page
Library
Module
Module type
Parameter
Class
Class type
Source
Forked from awsm which is Copyright (c) Solvuu, Inc. Released under the MIT license.
Pure OCaml client for AWS. Code is auto-generated for all services based on the API declared in botocore. Higher level functions are sometimes provided on top of this base to (e.g.) support multi-part uploads to S3.
Nearly all of AWS's 400+ APIs are supported (generated from botocore 1.43.9, freshened 2026-05-17). Three I/O flavors:
awso-async — Jane Street Async backendawso-lwt — Lwt backendawso-sync — synchronous (blocking) backend; uses libcurl under the hoodThere is additionally a command-line tool awso-cli for all APIs composed using Core.Command.
opam install awso-async # Async
opam install awso-lwt # Lwt
opam install awso-sync # synchronous (blocking)
opam install awso-cli # umbrella CLI binaryNote: the AWS surface is massive and this package can take a lengthy amount of time and space to build.
See the examples directory.
Here is a short example that lists all EC2 instances using Async:
(* ec2_describe_instances.ml *)
open! Core
open! Async
module Ec2 = Awso_ec2_async
let print_row a b c d = printf "%-16s %-15s %-39s %-40s\n" a b c d
let print_instance instance =
let name =
Option.bind instance.Ec2.Instance.tags ~f:(fun tags ->
List.find_map tags ~f:(function
| { Ec2.Tag.key = Some "Name"; value = Some v } -> Some v
| _ -> None))
in
let instance_type =
match instance.Ec2.Instance.instanceType with
| Some it -> Ec2.InstanceType.to_string it
| None -> ""
in
print_row
instance_type
(Option.value instance.publicIpAddress ~default:"")
(Option.value instance.ipv6Address ~default:"")
(Option.value name ~default:"")
;;
let ec2_describe_instances () =
match%bind Ec2.describe_instances (Ec2.DescribeInstancesRequest.make ()) with
| Error e ->
failwithf !"Ec2.describe_instances: %{Yojson.Safe}" (Ec2.Ec2_error.to_json e) ()
| Ok { reservations; _ } -> (
let instances =
reservations
|> Option.value ~default:[]
|> List.concat_map ~f:(function
| { Ec2.Reservation.instances = None; _ } -> []
| { instances = Some instances; _ } -> instances)
in
match instances with
| [] ->
print_endline "no instances";
return ()
| instances ->
print_row "instance-type" "public ipv4" "public ipv6" "name";
print_row
(String.make 16 '-')
(String.make 15 '-')
(String.make 39 '-')
(String.make 40 '-');
List.iter instances ~f:print_instance;
return ())
;;
let () =
let cmd =
Command.async
~summary:"Test script: list EC2 instances in default region"
(let%map_open.Command () = return () in
fun () -> ec2_describe_instances ())
in
Command_unix.run cmd
;;; dune
(executable
(name ec2_describe_instances)
(libraries awso-async.ec2 core_unix.command_unix)
(preprocess
(pps ppx_jane)))Make sure to populate ~/.aws/config and ~/.aws/credentials in the usual way, then:
dune exec ./ec2_describe_instances.exePath | Purpose | Shipped to opam? |
|---|---|---|
| Core runtime: auth, HTTP, config, regions | Yes ( |
| Async backend | Yes ( |
| Lwt backend | Yes ( |
| Synchronous (blocking) backend, libcurl-based | Yes ( |
| Jane Street Core compatibility shim | Yes ( |
| Auto-generated per-service bindings (~400 services) | Yes (under |
| A bit like the Python aws cli | Yes ( |
| The code generator that produces | No: private library |
| Vendored botocore JSON used by the codegen | No |
| Important maintainer tools that use | No |
| Example programs | No, not installed |
aws/ tree committed to git?aws/<service>/ contains roughly 400 services worth of generated OCaml. We commit it on purpose so that opam install awso-async (or any sibling package) never has to run the codegen at install time. End users get a ~25 dependency build instead of ~50+: ppxlib, sedlex, ocamlgraph, and the rest of the codegen toolchain stay private to maintainers. The decision trades repo size for install-time simplicity and predictability.
Regeneration is a maintainer concern, but you can re-generate yourself like so:
make generate-codeAfter regenerating, commit the resulting diff alongside whatever change prompted it.
Generate API docs locally with opam install odoc then make doc.