Skip to content

Instantly share code, notes, and snippets.

Last active Sep 22, 2015
What would you like to do?
Copy an annotatation from one Hypothesis instance to another
#!/usr/bin/env python2.7
import argparse
import json
import requests
def get_annotation(url, id_):
return requests.get(url + "/api/annotations/" + id_).json()
def login(username, password, url):
"""Login to a Hypothesis site and return the user ID and API token.
The API token can be used in Authorization headers in subsequent requests
to the API like so:
Authorization: Bearer <api_token>
:returns: A 2-tuple (userid, api_token)
# Get an XSRF-TOKEN and an unauthenticated session token from /app.
# We need these to post the login form.
response = requests.get(url + "/app")
xsrf_token = response.cookies["XSRF-TOKEN"]
unauthenticated_session_token = response.cookies["session"]
# Login, getting an authenticated session token.
response =
url + "/app?__formid__=login",
data=json.dumps({"username": username, "password": password}),
cookies={"session": unauthenticated_session_token},
headers={"X-CSRF-TOKEN": xsrf_token})
authenticated_session_token = response.cookies["session"]
userid = response.json()['model']['userid']
# Exchange our authenticated session token for an API token.
response = requests.get(
url + "/api/token?assertion=" + xsrf_token,
cookies={"session": authenticated_session_token},
api_token = response.text
return (userid, api_token)
def create_annotation(username, password, url, annotation):
"""Create a new annotation using the Hypothesis API and return it."""
userid, api_token = login(username, password, url)
response =
url + "/api/annotations",
headers={"Authorization": "Bearer " + api_token})
return response.json()
def main():
"""Copy an annotation from one Hypothesis instance to another."""
parser = argparse.ArgumentParser(
description="Copy annotations between Hypothesis instances.\n\n"
"For example:\n\n"
" %(prog)s seanh pass '' "
"'' 't9YqjMY2Ql6jvxQEUSRK8w'",
help="Username of the account to use to create new annotations with "
"on the Hypothesis instance that you're copying to, for example: "
help="Password for the given username, for example: 'pass'")
help="Base URL of the Hypothesis instance that you want to copy "
"annotations from, for example: ''")
help="Base URL of the Hypothesis instance that you want to copy "
"annotations to, for example: ''")
help="The ID of the annotation to copy, for example: "
args = parser.parse_args()
if args.from_url.endswith("/"):
args.from_url = args.from_url[:-1]
if args.to_url.endswith("/"):
args.to_url =[:-1]
print create_annotation(
args.username, args.password, args.to_url,
if __name__ == "__main__":
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment