# Topham A simple client library for the [sr.ht](https://sr.ht/) REST API. ## Requirements * [http-client](https://wiki.call-cc.org/eggref/5/http-client) * [intarweb](https://wiki.call-cc.org/eggref/5/intarweb) * [medea](https://wiki.call-cc.org/eggref/5/medea) * [module-declarations](https://wiki.call-cc.org/eggref/5/module-declarations) * [openssl](https://wiki.call-cc.org/eggref/5/openssl) * [optimism](https://wiki.call-cc.org/eggref/5/optimism) * [simple-exceptions](https://wiki.call-cc.org/eggref/5/simple-exceptions) ## Quick Start Create a new job on [builds.sr.ht](https://builds.sr.ht/) and fetch information about it: ```scheme (import (topham) (topham builds)) (access-token "your-access-token-goes-here") (create (job manifest: "xyz")) ; => ((#:service "builds" #:path "/api/jobs") ; (id . 1234)) (retrieve (job 1234)) ; => ((#:service "builds" #:path "/api/jobs/1234") ; (id . 1234) ; (status . "running") ; (setup_log ...) ; (tasks . #(...)) ; (runner ...)) (retrieve (manifest 1234)) ; => "xyz" ``` Subscribe or unsubscribe from a mailing list: ```scheme (create (subscription list: "~sircmpwn/sr.ht-announce")) ; => ((id . 24) ; (created . "2018-07-08T23:46:31+00:00") ; (list (name . "sr.ht-announce") ; (owner (canonical_name . "~sircmpwn") (name . "sircmpwn")))) (retrieve (subscriptions)) ; => ((#:service "lists" #:path "/api/subscriptions") ; (next . null) ; (results ; . ; #(((id . 24) ; (created . "2018-07-08T23:46:31+00:00") ; (list (name . "sr.ht-announce") ; (owner (canonical_name . "~sircmpwn") (name . "sircmpwn")))))) ; (total . 1) ; (results_per_page . 50)) (delete (subscription 24)) ; => #t ``` ## Usage ### Authentication There are two ways to authenticate API requests. The first is to set the `access-token` parameter: ```scheme (import (topham)) (access-token "...") ``` The second is to set the `SRHT_ACCESS_TOKEN` environment variable: ```scheme (import (chicken process-context)) (set-environment-variable! "SRHT_ACCESS_TOKEN" "...") ``` If both of these are set, the parameter value is used. ### Creating Requests This library follows a typical [CRUD][] pattern, where you (1) create a payload representing a remote resource, then (2) send it to the server with one of the `create`, `retrieve`, `update` or `delete` procedures. Resources are represented as Scheme objects per [medea][]'s default JSON-to-Scheme conversion rules. Requests and responses are represented as association lists, where the first item specifies a remote endpoint from which a resource should be (or has been) fetched: ```scheme (mailing-lists) ; => ((#:service "lists" #:path "/api/lists")) (mailing-list "foo") ; => ((#:service "lists" #:path "/api/lists/foo")) (mailing-list name: "foo" description: "bar") ; => ((#:service "lists" #:path "/api/lists") ; (name . "foo") ; (description . "bar")) ``` Objects of this shape are referred to as "crud" throughout this documentation. [CRUD]: https://en.wikipedia.org/wiki/Create,_read,_update_and_delete [medea]: https://wiki.call-cc.org/eggref/5/medea ### Pagination Many API responses are subject to [pagination][pagination]. To specify a starting ID, use the `page` combinator. This sets the `start` parameter for GET requests, per [sr.ht's API][pagination-api]: ```scheme (import (only (topham) retrieve page)) ; retrieve the first page of results (retrieve (emails "~user")) ; retrieve results starting from id 42 (retrieve (page (emails "~user") 42)) ``` [pagination]: https://en.wikipedia.org/wiki/Pagination [pagination-api]: https://man.sr.ht/api-conventions.md#pagination ### API #### topham The `(topham)` library provides configuration parameters and procedures for submitting CRUD requests. [parameter] (access-token) => string [parameter] (access-token string) => string Sets the client's API token for authentication. The value should be a [personal access token][tokens], which can be created (or revoked) from your [account settings page][oauth]. This library does not support OAuth-based authentication. [oauth]: https://meta.sr.ht/oauth [tokens]: https://man.sr.ht/meta.sr.ht/oauth-api.md#personal-access-tokens [parameter] (service-domain) => string [parameter] (service-domain string) => string Specifies the hostname of the remote service, useful for connecting to a sr.ht instance other than . The default value is simply `"sr.ht"`. [procedure] (create crud) => any [procedure] (retrieve crud) => any [procedure] (update crud) => any [procedure] (delete crud) => any Submits a CRUD payload to the server. These procedures correspond to the `POST`, `GET`, `PUT` and `DELETE` request methods, respectively. The result is a Scheme representation of the response (generally a "crud object"), or `#f` if the requested resource was not found. If the response is an error (other than HTTP 404), a condition of type `(exn http topham)` is signaled. [procedure] (page crud) => crud Sets the starting ID for results fetched with `retrieve`. Refer to [Pagination](#Pagination) for details. #### builds The `(topham builds)` library provides request builders for [builds.sr.ht](https://man.sr.ht/builds.sr.ht/api.md). [procedure] (job number) => crud [procedure] (job #!key argument ...) => crud In the first form, [fetches a job by ID][get-apijobsid]. In the second form, [creates a new job][post-apijobs]. `number` should be a job resource ID. [get-apijobsid]: https://man.sr.ht/builds.sr.ht/api.md#get-apijobsid [post-apijobs]: https://man.sr.ht/builds.sr.ht/api.md#post-apijobs [procedure] (manifest number) => crud [Retrieves a job's manifest][get-apijobsidmanifest]. `number` should be a job resource ID. [get-apijobsidmanifest]: https://man.sr.ht/builds.sr.ht/api.md#get-apijobsidmanifest [procedure] (start number) => crud [Starts a job][post-apijobsidstart] that was created with `execute: #f`. `number` should be a job resource ID. [post-apijobsidstart]: https://man.sr.ht/builds.sr.ht/api.md#post-apijobsidstart #### lists The `(topham lists)` library provides request builders for [lists.sr.ht](https://man.sr.ht/lists.sr.ht/api.md). [procedure] (user string) => crud [Retrieves a user][get-apiuserusername]. `string` should be a username or email address. [get-apiuserusername]: https://man.sr.ht/lists.sr.ht/api.md#get-apiuserusername [procedure] (subscriptions) => crud [Retrieves the active user's mailing list subscriptions][get-apisubscriptions]. [get-apisubscriptions]: https://man.sr.ht/lists.sr.ht/api.md#get-apisubscriptions [procedure] (subscription number) => crud [procedure] (subscription #!key list) => crud In the first form, [retrieves a subscription by ID][get-apisubscriptionssub-id]. In the second form, [subscribes to a mailing list][post-apisubscriptions]. `number` should be a subscription resource ID. [get-apisubscriptionssub-id]: https://man.sr.ht/lists.sr.ht/api.md#get-apisubscriptionssub-id [post-apisubscriptions]: https://man.sr.ht/lists.sr.ht/api.md#post-apisubscriptions [procedure] (emails) => crud [procedure] (emails string) => crud Retrieves emails sent by the [active user][get-apiemails], or by the [given user][get-apiuserusernameemails]. `string` should be a username or email address. This endpoint is subject to [pagination](#Pagination). [get-apiemails]: https://man.sr.ht/lists.sr.ht/api.md#get-apiemails [get-apiuserusernameemails]: https://man.sr.ht/lists.sr.ht/api.md#get-apiuserusernameemails [procedure] (email number) => crud [Retrieves an email][get-apiemailsemail-id]. `number` should be an email resource ID. [get-apiemailsemail-id]: https://man.sr.ht/lists.sr.ht/api.md#get-apiemailsemail-id [procedure] (thread number) => crud [Retrieves an email thread][get-apithreademail-id]. `number` should be an email resource ID. This endpoint is *not* subject to pagination. Rather, the result is a vector containing all emails in the thread. [get-apithreademail-id]: https://man.sr.ht/lists.sr.ht/api.md#get-apithreademail-id [procedure] (mailing-lists) => crud [procedure] (mailing-lists string) => crud Retrieves mailing lists belonging to the [active user][get-apilists], or to the [given user][get-apiuserusernamelists]. `string` should be a username or email address. This endpoint is subject to [pagination](#Pagination). [get-apilists]: https://man.sr.ht/lists.sr.ht/api.md#get-apilists [get-apiuserusernamelists]: https://man.sr.ht/lists.sr.ht/api.md#get-apiuserusernamelists [procedure] (mailing-list string string) => crud [procedure] (mailing-list string #!key description) => crud [procedure] (mailing-list #!key name description) => crud In the first form, [retrieves a subscription by ID][get-apiuserusernamelistslist-name]. In the second form, [updates a mailing list][put-apilistslist-name]. In the third form, [creates a mailing list][post-apilists]. The `string` arguments should be user and list names. [get-apiuserusernamelistslist-name]: https://man.sr.ht/lists.sr.ht/api.md#get-apiuserusernamelistslist-name [put-apilistslist-name]: https://man.sr.ht/lists.sr.ht/api.md#put-apilistslist-name [post-apilists]: https://man.sr.ht/lists.sr.ht/api.md#post-apilists [procedure] (posts string) => crud [procedure] (posts string string) => crud Retrieves posts to a mailing list, given a [list name][get-apilistslist-namepost] or [list owner and name][get-apiuserusernamelistslist-nameposts]. In the first form, the `string` argument be a mailing list name, where the list is assumed to belong to the active user. In the second form, the arguments should be a username (the list owner) and mailing list name. This endpoint is subject to [pagination](#Pagination). [get-apilistslist-namepost]: https://man.sr.ht/lists.sr.ht/api.md#get-apilistslist-nameposts [get-apiuserusernamelistslist-nameposts]: https://man.sr.ht/lists.sr.ht/api.md#get-apiuserusernamelistslist-nameposts #### meta The `(topham meta)` library provides request builders for [meta.sr.ht](https://man.sr.ht/meta.sr.ht/api.md). [procedure] (profile) => crud [procedure] (profile #!key argument ...) => crud In the first form, [fetches the active user's profile][get-apiuserprofile]. In the second form, [updates the user's profile][put-apiuserprofile]. [get-apiuserprofile]: https://man.sr.ht/meta.sr.ht/user-api.md#get-apiuserprofile [put-apiuserprofile]: https://man.sr.ht/meta.sr.ht/user-api.md#put-apiuserprofile [procedure] (audit-log) => crud [Retrieves the active user's audit log][get-apiuseraudit-log]. This endpoint is subject to [pagination](#Pagination). [get-apiuseraudit-log]: https://man.sr.ht/meta.sr.ht/user-api.md#get-apiuseraudit-log [procedure] (ssh-keys) => crud [Retrieves the active user's SSH keys][get-apiuserssh-keys]. This endpoint is subject to [pagination](#Pagination). [get-apiuserssh-keys]: https://man.sr.ht/meta.sr.ht/user-api.md#get-apiuserssh-keys [procedure] (ssh-key number) => crud [procedure] (ssh-key #!key ssh-key) => crud In the first form, [fetches an SSH key by ID][get-apiuserssh-keysid]. In the second form, [creates a new SSH key][post-apiuserssh-keys]. `number` should be a key resource ID. [get-apiuserssh-keysid]: https://man.sr.ht/meta.sr.ht/user-api.md#get-apiuserssh-keysid [post-apiuserssh-keys]: https://man.sr.ht/meta.sr.ht/user-api.md#post-apiuserssh-keys [procedure] (pgp-keys) => crud [Retrieves the active user's PGP keys][get-apiuserpgp-keys]. This endpoint is subject to [pagination](#Pagination). [get-apiuserpgp-keys]: https://man.sr.ht/meta.sr.ht/user-api.md#get-apiuserpgp-keys [procedure] (pgp-key number) => crud [procedure] (pgp-key #!key pgp-key) => crud In the first form, [fetches a PGP key by ID][get-apiuserpgp-keysid]. In the second form, [creates a new PGP key][post-apiuserpgp-keys]. `number` should be a key resource ID. [get-apiuserpgp-keysid]: https://man.sr.ht/meta.sr.ht/user-api.md#get-apiuserpgp-keysid [post-apiuserpgp-keys]: https://man.sr.ht/meta.sr.ht/user-api.md#post-apiuserpgp-keys #### paste The `(topham paste)` library provides request builders for [paste.sr.ht](https://man.sr.ht/paste.sr.ht/api.md). [procedure] (paste string) => crud [procedure] (paste #!key contents filename visibility) => crud In the first form, [fetches a paste by ID][get-apipastessha]. In the second form, [creates a new paste][post-apipastes]. `string` should be a paste SHA. [get-apipastessha]: https://man.sr.ht/paste.sr.ht/api.md#get-apipastessha [post-apipastes]: https://man.sr.ht/paste.sr.ht/api.md#post-apipastes [procedure] (blob string) => crud [Fetches a blob][get-apiblobssha]. `string` should be a blob SHA. [get-apiblobssha]: https://man.sr.ht/paste.sr.ht/api.md#get-apiblobssha [procedure] (pastes) => crud [Retrieves a list of pastes][get-apipastes]. This endpoint is subject to [pagination](#Pagination). [get-apipastes]: https://man.sr.ht/paste.sr.ht/api.md#get-apipastes ## Links * Sources: * Issues: * Documentation: ## License Topham is licensed under the [3-clause BSD license][license]. [license]: https://opensource.org/licenses/BSD-3-Clause