package awskit
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=788e91d57b9eed047bdef011aec476e94588be20e2e2f1b8495cf48b1a90cf0f
sha512=0d441d599f3f3efb766270258bb4d8c9cd660943eb7f90ced0ec6f61a6790f5fb8977ca5cf87f466d84701ee34dbfdf81fe5043b568a2236411f577e698c6d1e
doc/guides.html
AWS Core Guides
The core package is a pure foundation plus explicit runtime adapters at the edge. Service packages use this foundation for signing, request construction, response metadata, and structured errors.
Credentials
Create explicit credentials with result-returning or exception-raising constructors:
let credentials =
Awskit.Credentials.create_exn
~access_key_id:"AKIAIOSFODNN7EXAMPLE"
~secret_access_key:"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
()Temporary credentials include a session token:
let credentials =
Awskit.Credentials.create_exn
~access_key_id:"ASIATESTSESSIONTOKEN"
~secret_access_key:"secret"
~session_token:"FwoGZXIvYXdz..."
()Credentials are opaque. Use Awskit.Credentials.access_key_id and Awskit.Credentials.session_token to read non-secret fields. The secret access key is accepted at construction time but not exposed afterward.
Environment Variables
awskit-unix and awskit-lwt-unix can read:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN
AWS_REGION
AWS_DEFAULT_REGION
AWS_PROFILE
AWS_SHARED_CREDENTIALS_FILE
AWS_CONFIG_FILE
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
AWS_CONTAINER_CREDENTIALS_FULL_URI
AWS_CONTAINER_AUTHORIZATION_TOKEN
AWS_CONTAINER_AUTHORIZATION_TOKEN_FILEawskit-unix also reads static shared AWS profiles from $HOME/.aws/credentials and $HOME/.aws/config. Named profiles use AWS_PROFILE, defaulting to "default". Environment credentials win over profile files when present.
awskit-lwt-unix extends the local static sources with refreshable ECS container credentials and EC2 instance profile credentials. The EC2 provider uses IMDSv2 when available and refreshes metadata credentials before expiration. Process providers, web identity, and STS assume-role profiles remain future work.
Regions And Endpoints
Regions are explicit values:
let region = Awskit.Region.of_string_exn "us-east-1"Endpoints are scheme/host/port records:
let endpoint =
Awskit.Endpoint.https
~host:"s3.us-east-1.amazonaws.com"
()Runtime adapters can take endpoint overrides, but service-specific packages usually expose their own endpoint configuration because addressing rules are service-specific. For S3, pass endpoint and addressing options directly to the awskit-s3 adapter create functions.
Signing
Awskit.Signing implements AWS Signature Version 4 without IO.
Use payload_hash metadata instead of passing a raw body to signing:
let signed =
Awskit.Signing.sign_request
~credentials
~region
~service:"s3"
~method_:`PUT
~path:"/my-key"
~query:""
~headers:[ ("host", "my-bucket.s3.us-east-1.amazonaws.com") ]
~payload_hash:(Awskit.Body.Payload_hash.sha256_of_string "hello")
~now:Ptime.epochFor presigned or streaming cases, service packages may use explicit payload hash values such as UNSIGNED-PAYLOAD.
Useful low-level helpers:
Structured Errors
Core errors are structured values:
type t =
| Validation of validation
| Signing of string
| Transport of transport
| Service of service
| Decode of string
| Body of bodyUse Awskit.Error.retry_class for manual retry decisions:
match Awskit.Error.retry_class err with
| `Throttled | `Retryable -> retry ()
| `Auth -> refresh_or_fail ()
| `Not_found -> handle_missing ()
| `Conflict | `Fatal | `Unknown -> fail errService packages preserve Awskit.Error.t and add classifier helpers. For example, awskit-s3 exposes Awskit_s3.Error.is_no_such_key and Awskit_s3.Error.is_precondition_failed.
Retry Policy
Service packages use Awskit.Retry for built-in retries. The default policy retries retryable transport failures, throttling responses, and 5xx service responses when the request body is replayable.
let retry_policy =
Awskit.Retry.create_exn
~max_attempts:4
~base_delay:(Ptime.Span.of_float_s 0.2 |> Option.get)
~max_delay:(Ptime.Span.of_float_s 3.0 |> Option.get)
~jitter:0.5
()Use Awskit.Retry.disabled when an application wants to own all retry behavior itself.
Runtime Body Model
The runtime abstraction keeps HTTP metadata separate from bodies:
- request bodies are passed separately to
Runtime.with_response - response bodies are valid inside the
with_responsecallback - response body readers are scoped through
Runtime.Response_body.with_reader - request and response records are body-free
This lets service packages stream bodies without forcing all adapters to buffer data in memory.
Request bodies carry a descriptor:
{
Awskit.Body.Request.content_length = Some 5L;
payload_hash = Awskit.Body.Payload_hash.sha256_of_string "hello";
replayable = true;
}The descriptor records the declared request body length, the payload hash used for signing, and whether the body can be replayed. Service packages may reject unknown lengths. For example, S3 PutObject and UploadPart currently require a known content_length; Awskit does not implement SigV4 aws-chunked streaming for unknown-length request bodies.
For custom Runtime.Request_body.of_stream values, the producer callback is part of the request operation. Errors returned by that callback are request body failures. When a known length is declared, the producer must emit exactly that number of bytes; prefer Runtime.Request_body.of_string or Runtime.Request_body.of_bytes when data is already buffered. Mark a custom stream replayable only if a retry can recreate the same body.
Response bodies must be consumed inside the with_response callback, normally through Runtime.Response_body.with_reader:
Runtime.with_response conn request body ~f:(fun response body ->
Runtime.Response_body.with_reader body ~consume:(fun reader ->
Runtime.Response_body.read reader bytes ~off:0 ~len:(Bytes.length bytes)))Service packages expose higher-level helpers when buffering is intentional. For example, awskit-s3 uses Object.get_as_string ~max_bytes. These helpers keep response-size limits explicit when buffering or draining a streaming response.
Response body readers are scoped. After the consumer returns successfully, the runtime drains the remaining response body up to max_response_drain_bytes so the connection can be reused. If the consumer succeeds but draining exceeds the cap, the operation returns the drain error. If the consumer itself fails, the consumer error wins.
Choosing An Adapter
Eio
Use awskit-eio for direct-style OCaml 5 applications:
Eio.Switch.run @@ fun sw ->
let conn =
Awskit_eio.create
~env
~sw
~region
~credentials
()
in
ignore connThe monad type is type 'a t = 'a. Errors are returned as result values by service operations.
Lwt Unix
Use awskit-lwt-unix for ordinary Lwt applications on Unix:
let conn =
Awskit_lwt_unix.create
~region:"us-east-1"
~credentials
()
|> Result.get_okOperations in service packages return Lwt.t.
Generic Lwt
Use awskit-lwt when you need to provide a custom Cohttp_lwt.S.Client:
module Runtime = Awskit_lwt.Make (Cohttp_lwt_unix.Client)Custom Runtime Adapters
Implement Awskit.Runtime.S when integrating another concurrency or HTTP stack. The service package functors need:
- a monad type and bind/return
- connection region, credentials, clock, and optional endpoint
- request body constructors and request descriptors
- response body scoped consumption
- HTTP transport through
with_response
S3 adapters extend the core runtime with s3_endpoint_config so S3 endpoint resolution can stay AWS-aware without putting S3 concepts into the pure core.