(2023)
This is an example/exercise. We’ll access our Mastodon account from a Python script using the REST API with OAuth.
Note: many people recommend the requests
library, which is slightly more ergonoic than the built-in urllib
we use here.
(Also note that urllib3
is unrelated to urllib
. 🙄)
Log into the “Development” section of our Mastodon account (https://mastodon.social/settings/applications) and create a “New Application”.
For this exercise we need permission to read:accounts
and write:statuses
.
This gives us:
The access token defines the access privileges of the client for particular resources. The access token shown in the Mastondon interface is provided by Mastodon for testing purposes. For routine production use, a client should acquire a new access token using the client key and secret rather that using the one shown here.
$ touch api_test.py
$ chmod 700 api_test.py
#! /usr/bin/env python3
"""
This example code shows how to call a REST API with OAuth from python.
© 2023 Paul Gorman.
Distributed under the MIT License (https://opensource.org/license/mit/).
"""
import argparse
import json
import sys
import urllib.parse
import urllib.request
API_TOKEN = ".....TOKEN....."
MASTODON_ACCOUNT_ID = "1234" # Look up your Mastodon account ID with https://INSTANCE/api/v1/accounts/lookup?acct=USERNAME
MASTODON_SERVER = "https://mastodon.social/"
debug = False
def getAccount(id=MASTODON_ACCOUNT_ID, server=MASTODON_SERVER, token=API_TOKEN):
"""
Get user account info for `id` from Mastodon server `server` using OAuth API token `token`.
Return a Python object based on the JSON response.
"""
MASTODON_ACCOUNT_ENDPOINT = "/api/v1/accounts/"
url = urllib.parse.urljoin(server, MASTODON_ACCOUNT_ENDPOINT)
url = urllib.parse.urljoin(url, id)
headers = {
"Authorization": "Bearer " + token
}
req = urllib.request.Request(url, headers=headers)
with urllib.request.urlopen(req) as response:
res = json.loads(response.read())
if debug:
print("HTTP response:", response.status)
return res
def postStatus(status="TEST!", visibility="public", server=MASTODON_SERVER, token=API_TOKEN):
"""
Post new status update `status` to Mastodon server `server` using OAuth API token `token`.
Return a Python object based on the JSON response.
"""
MASTODON_STATUSES_ENDPOINT = "/api/v1/statuses"
url = urllib.parse.urljoin(server, MASTODON_STATUSES_ENDPOINT)
headers = {
"Authorization": "Bearer " + token
}
query = {
"status": status,
"visibility": visibility
}
data = urllib.parse.urlencode(query)
data = data.encode('utf-8')
req = urllib.request.Request(url, data, headers)
with urllib.request.urlopen(req) as response:
res = json.loads(response.read())
if debug:
print("HTTP response:", response.status)
return res
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--debug", help="print debug message to the command line")
args = parser.parse_args()
if args.debug:
debug = True
print(getAccount(MASTODON_ACCOUNT_ID))
print(postStatus("This is a test.", "private"))
if __name__ == "__main__":
sys.exit(main())