atproto_client#
Alpha, pre-release. Pre-1.0, evolving alongside at-record; expect breaking changes between 0.x releases.
A small, transport-agnostic atproto client for Gleam.
No app or lexicon knowledge: XRPC, identity resolution, OAuth discovery,
blobs, and generic repo CRUD. Dual-target (erlang + javascript); browser-only
consumers want the sibling atproto_browser instead,
which owns the atproto/browser/* namespace within the shared atproto/
prefix.
Installation#
gleam add atproto_client
Usage#
The client carries a send function instead of a hardcoded HTTP backend, so
you choose the transport per target. On Erlang, gleam_httpc's send_bits
maps onto the client's TransportError channel:
import atproto/xrpc
import atproto_core/xrpc as core_xrpc
import gleam/httpc
import gleam/result
import gleam/string
fn client() -> xrpc.Client {
xrpc.Client(send: fn(req) {
httpc.send_bits(req)
|> result.map_error(fn(error) {
case error {
httpc.ResponseTimeout -> core_xrpc.Timeout
httpc.FailedToConnect(_, _) ->
core_xrpc.ConnectionFailed(string.inspect(error))
_ -> core_xrpc.Other(string.inspect(error))
}
})
})
}
Resolve an identity, then read its records:
import atproto/identity
import atproto/repo
import gleam/dynamic/decode
let assert Ok(pds) =
identity.resolve_pds(client(), identity.default_resolver, "someone.bsky.social")
let assert Ok(rows) =
repo.list_records(
client(),
pds,
access_token,
did,
"app.bsky.feed.post",
decode.dynamic,
)
For the full walkthrough, including both authentication routes, see the getting started guide.
Architecture#
Core#
| Module | What it does |
|---|---|
atproto/xrpc |
Client, TransportError, XrpcError, get/post_json, parse |
atproto/identity |
resolve_pds (handle/DID -> PDS) via Slingshot resolveMiniDoc |
atproto/auth |
create_session/refresh_session (com.atproto.server.createSession) |
atproto/repo |
list_records/create_record/get_record/put_record/delete_record/upload_blob |
atproto/blob |
Blob type, its codec, and public_url for refs returned by repo.upload_blob |
atproto/uri |
at-uri helpers (rkey) |
atproto/constellation |
get_backlinks against the microcosm backlink index |
OAuth#
The full atproto OAuth client flow for a confidential client, one module per step:
| Module | What it does |
|---|---|
atproto/oauth/metadata |
Discover the authorization server and its endpoints from a PDS |
atproto/oauth/flow |
start: PAR + PKCE + DPoP, returns the authorization URL and a pending Flow |
atproto/oauth/tokens |
exchange_code/refresh/revoke against the token endpoint |
atproto/oauth/resource |
Wraps a Client so every request carries the DPoP-bound access token |
atproto/oauth/runner |
Interprets the sans-io effect kernel against a synchronous Client |
The modules above are sync wrappers over the sans-io effect kernel in
atproto_core. Its
TransportError/XrpcError types are aliased through atproto/xrpc;
constructing the variants needs atproto_core/xrpc.
Development#
gleam test