package awso-common
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=e0e7510192b7e45871cff5c60e5162a77a9fa103b6924136fb1fea5db2092b26
sha512=51a18cf74c122b021bd84ef5728b7c5b2d5e767f03d5cd2387d886edc34a68cf54a3183e2d6c4939b4c8d3e0c0e406c869d019f2ee9a0903ae4cf7ca725572f0
doc/README.html
awso - OCaml AWS client
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.
Features
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 hood
There is additionally a command-line tool awso-cli for all APIs composed using Core.Command.
Getting started
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.
Examples
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.exeRepository layout
Path | 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 |
Why is the 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.
Documentation
Generate API docs locally with opam install odoc then make doc.