Skip to content

Instantly share code, notes, and snippets.

@robertknight
Created October 28, 2024 13:09
Show Gist options
  • Save robertknight/3f9e60eb1690f652cc858b3752a46a1a to your computer and use it in GitHub Desktop.
Save robertknight/3f9e60eb1690f652cc858b3752a46a1a to your computer and use it in GitHub Desktop.
Minimalist Hypothesis export script
import getpass
import json
import re
import sys
import requests
GROUP_URL_PATTERN = "https://hypothes.is/groups/([^/]+)/.*"
api_token = getpass.getpass(
"Enter developer token (from https://hypothes.is/account/developer): "
)
group_url = input("Enter group URL: ")
group_id_match = re.match(GROUP_URL_PATTERN, group_url)
if not group_id_match:
print(f"{group_url} is not a valid group URL", file=sys.stderr)
sys.exit(1)
group_id = group_id_match.group(1)
search_api = "https://hypothes.is/api/search"
output_file = "annotations.json"
search_after = None
annotations = []
page_size = 200
total = None
while True:
rsp = requests.get(
search_api,
params={
"group": group_id,
"limit": page_size,
"search_after": search_after,
"order": "asc",
"sort": "created",
},
headers={"Authorization": f"Bearer {api_token}"},
)
rsp.raise_for_status()
data = rsp.json()
rows = data["rows"]
total = data["total"]
if not rows:
break
annotations += rows
search_after = rows[-1]["created"]
print(f"Fetched {len(annotations)} of {total} annotations...", file=sys.stderr)
with open(output_file, "w") as fp:
json.dump(annotations, fp, indent=2, sort_keys=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment