Mastodon.py 2.3.3 is finally tagged, and here’s a few new things that it supports that I think are neat!

In an earlier draft of this post, it was version 2.3.2, but I noticed during writing that I forgot to document the new Collections endpoint. So, writing it has already paid off. Hooray!

Websocket streaming

This fixes a long-standing gap - Mastodon.py has always been able to use the SSE streaming API, but Mastodon itself uses for the most part Websocket based streaming, with a slightly better (frankly - superior) overall API layout. Some servers that offer a Mastodon-like API, like GoToSocial, even offer only the Websocket API, meaning it wasn’t possible to stream things from them using Mastodon.py at all.

Well, not anymore - we now support both SSE and Websocket streams. New and shiny:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from mastodon import Mastodon, CallbackStreamListener
mastodon_api = Mastodon([...])

def print_status_content(status):
    print(status.content)

listener = CallbackStreamListener(update_handler=print_status_content)
stream_handle = mastodon_api.stream_open_websocket(listener)
stream_handle.subscribe("user")

# Will now print out statuses until the script stops
while True:
    pass 

You can subscribe to multiple streams over the same connection (or unsubscribe if you need to), or have multiple connections if you’d like (though that is not recommended). The existing methods have also been updated to make a relatively drop-in replacement of HTTP SSE based streaming with websocket streaming possible. The usual automatic reconnection stuff still works as-is (and of course with the same caveats about possibly missing some statuses).

Check out the full documentation here!

Annual reports

Just in time for that to be relevant, Annual Report support is finally in a slightly better shape than it was before.

We can now retrieve annual reports / “year in review” data, kick off the generation of such a report, and check if any year in report campaign is currently active:

1
2
3
4
5
6
7
8
9
from mastodon import Mastodon, CallbackStreamListener
mastodon_api = Mastodon([...])

# At time of publishing: None
print("Currently active campaign year:", mastodon_api.instance_v2().wrapstodon)

# For me: "oracle"
print("Your Archetype for the Annual Report 2025:", \
      mastodon_api.annual_report(year=2025).annual_reports[0].data.archetype)

These reports have different schemas. The last years schema was Version 2, there could be a new one for the new year, but thanks to our forward compatibility setup, even if I don’t get around to updating the supported schemas, you’ll hopefully be able to access the new report for 2026 anyways, when the time rolls around in 2 or months!

The usual slew of small improvements

A lot of smaller stuff has also been fixed or improved. Some highlights:

  • Pagination support is now much better. The pagination functions support more endpoints, even those where Mastodon paginates in a kind of weird way, and there’s a new Pagination iterator.
  • Starting from Mastodon 4.6, posting polls with image attachments is legal, and so Mastodon.py supports that now, as well!
  • This includes the newly added Collections, one of the things added in 4.6.
  • In Mastodon.py version 2.0 we added a whole type system. While this is nice (though internally, there is still a lot of work to be done), it was also a bit slow. Thanks to an idea from @toelke, we now cache type hints, speeding the whole casting process up by roughly 60 times (!) - very noticeable on smaller systems!
  • IDs are now again numerically comparable wherever that is possible, per a suggestion from @haraldg, and ID parsing for Pleromalikes has been fixed, and some other bugs for dealing with other third party implementations of the Mastodon API have been addressed, thanks to reports and work from @gunchleoc and @xsuchy.
  • Some other small bugs have been squashed, like bad error reports when a media file was not found (Thanks to @aescling) and an error in, ironically, the streaming API error handling (Thanks to @dylanpulver)
  • Test coverage is slightly improved, and after some digging around in internals, we finally can rerecord HTTP SSE streaming API tests on versions of Python above 3.9 now!
  • And a bunch of other stuff - you can have a look at the changelog.

We have a JOSS publication now

I’ve mentioned this previously, but I feel it is worth mentioning again: We now have a publication for Mastodon.py in the Journal of Open Source Software. If you use Mastodon.py in any context where it might be good to cite it, especially if you are (considering) doing research on the network or its users, please have a look!

In closing

Mastodon.py contains a lot of code by not just me, but also a lot of other people. As usual, thank you so much to everyone who reports issues or submits a PR! Also as usual, if you do want to Gently Encourage me to address your favourite issue that I don’t even know about, or implement some thing or other, you can throw money at me here, which will generally work. Or, if you have any questions whatsoever, I’m usually happy to help - just open an issue on github, or talk to me on Mastodon (for example, by replying to this post)!