#hypothesis #annotation #api #cli

bin+lib hypothesis

a Rust wrapper and CLI for the Hypothesis API

16 releases (8 breaking)

0.10.4 Aug 25, 2022
0.10.3 Apr 30, 2022
0.10.2 Apr 13, 2021
0.9.1 Mar 26, 2021
0.6.0 Jul 23, 2020

#390 in Command line utilities

Download history 3/week @ 2022-11-24 4/week @ 2022-12-01 16/week @ 2022-12-08 20/week @ 2022-12-15 9/week @ 2022-12-22 6/week @ 2022-12-29 6/week @ 2023-01-05 7/week @ 2023-01-12 17/week @ 2023-01-19 19/week @ 2023-01-26 12/week @ 2023-02-02 35/week @ 2023-02-09 58/week @ 2023-02-16 19/week @ 2023-02-23 6/week @ 2023-03-02 10/week @ 2023-03-09

102 downloads per month
Used in gooseberry

MIT license

1.5K SLoC

Crates.io Docs.rs CI GitHub release dependency status

A Rust API for Hypothesis


A lightweight wrapper and CLI for the Hypothesis Web API v1.0.0. It includes all APIKey authorized endpoints related to

  • annotations (create / update / delete / search / fetch / flag),
  • groups (create / update / list / fetch / leave / members)
  • profile (user information / groups)

Installation and Usage


You'll need a Hypothesis account, and a personal API token obtained as described here. Set the environment variables $HYPOTHESIS_NAME and $HYPOTHESIS_KEY to your username and the developer API key respectively.

As a command-line utility:

cargo install hypothesis

Run hypothesis --help to see subcommands and options. NOTE: the CLI doesn't currently have all the capabilities of the Rust crate, specifically bulk actions and updating dates are not supported.

Generate shell completions:

hypothesis complete zsh > .oh-my-zsh/completions/_hypothesis
exec zsh

As a Rust crate

Add to your Cargo.toml:

hypothesis = {version = "0.4.0", default-features = false}
tokio = { version = "0.2", features = ["macros"] }


use hypothesis::Hypothesis;
use hypothesis::annotations::{InputAnnotation, Target, Selector};

async fn main() -> Result<(), hypothesis::errors::HypothesisError> {
    let api = Hypothesis::from_env()?;
    let new_annotation = InputAnnotation::builder()
            .text("this is a comment")
               .selector(vec![Selector::new_quote("exact text in website to highlight",
                                                  "prefix of text",
                                                  "suffix of text")])
           .tags(vec!["tag1".to_string(), "tag2".to_string()])

See the documentation of the API struct (Hypothesis) for a list of possible queries. Use bulk functions to perform multiple actions - e.g. api.fetch_annotations instead of a loop around api.fetch_annotation.

Check the documentation for more usage examples.




Make sure you have a .env file (added to .gitignore) in the repo root with HYPOTHESIS_NAME, HYPOTHESIS_KEY, and TEST_GROUP_ID

Caveats / Todo:

  • Only supports APIKey authorization and hypothes.is authority (i.e. single users).
  • Target.selector.RangeSelector doesn't seem to follow W3C standards. It's just a hashmap for now.
  • Annotation hypermedia links are stored as a hashmap, b/c I don't know all the possible values.
  • Need to figure out how Document works to properly document it (hah).
  • Can't delete a group after making it, can leave it though (maybe it's the same thing?)
  • No idea what UserProfile.preferences and UserProfile.features mean.
  • CLI just dumps output as JSON, this is fine right? Fancier CLIs can build on top of this (or use the crate directly)


~314K SLoC