Back to Freedom.Tech Back
All Granary releasesAll versions
Release Thu, Jul 2, 2026 3 min read

Granary 11.0

Original release notes

Breaking changes:

  • as2
  • Rename link_tags to render_content, and expand it to also HTML-escape plain text content, convert newlines to `

, and convert leading spaces to  . It now renders even when there are no indexed tags. The inline RE: ...` link for a quoted post is now rendered here too. (bridgy-fed#990

  • from_as1: Stop rendering inline RE: ... link for quoted posts.
  • nostr:
  • verify now raises ValueError on failure instead of returning False.
  • Rename sign to hash_and_sign.
  • reddit:
  • Remove deprecated Reddit.praw_to_actor, user_to_actor, praw_to_object, and praw_to_activity method aliases.

Non-breaking changes:

  • Packaging: migrate from setup.py to pyproject.toml.
  • Start on Farcaster support! (snarfed/bridgy-fed#447).
  • Speed up to_as1 conversions: parse HTML content lazily in Source.postprocess_object (only when first_link_to_attachment is set), drop a redundant trim_nulls pass in as2 and nostr to_as1, and copy the input via JSON round trip instead of copy.deepcopy in as2.to_as1 (snarfed/bridgy-fed#2488).
  • as1:
  • Bug fix for converting HTML content to plain text when it includes square brackets ([ and ]) (snarfed/bridgy-fed#1605).
  • Optimize is_content_html to avoid full HTML parsing in most cases, eg when content has no elements.
  • If an object or activity doesn't have url, fall back to id for populating link rel="self".
  • bluesky:
  • Convert application and service actors to/from the Bluesky bot self-label.
  • from_as1:
  • Support Payment Pointers in actors' monetization property. If that value starts with $, eg $wallet.com/user, it's converted to https://, eg https://wallet.com/user.
  • De-dupe tags in output site.standard.document records.
  • Limit DM (chat.bsky.convo.defs#messageInput) output to record embeds only, not other types.
  • Convert raw domains in mention tags to home page URLs in app.bsky.richtext.facet#link.uri.
  • Posts with more than 4 images now use app.bsky.embed.gallery instead of app.bsky.embed.images.
  • to_as1:
  • Add support for site.standard.document records, converting them to AS1 article objects.
  • Add support for site.standard.publication records, converting them to AS1 person objects.
  • Populate width and height on AS1 image objects from aspectRatio in app.bsky.embed.images and app.bsky.embed.images#view embeds.
  • Support app.bsky.embed.gallery and app.bsky.embed.gallery#view embeds.
  • Join multiple content warnings with ; instead of `

because [Mastodon doesn't support HTML in summary`](https://github.com/mastodon/mastodon/issues/34079#issuecomment-2703397374).

  • New Bluesky.from_auth(auth_entity, client_metadata=None) classmethod: creates a Bluesky instance from an oauth_dropins.bluesky.BlueskyAuth entity, handling both legacy app password sessions and OAuth DPoP tokens.
  • microformats2:
  • from_as1: convert stream.duration (int seconds) to ISO 8601 duration string for the duration mf2 property; also accept ISO 8601 strings passed through from AS1.
  • to_as1: fix quotation-of h-cite attachments to have objectType note, enabling correct quote post conversion to ActivityPub (snarfed/bridgy-fed#1146).
  • nostr:
  • from_as1: fix crash when converting an article object with no id.
  • to_as1:
  • Support NIP-71 video events (kinds 21, 22, 34235, 34236), converting them to notes with video attachments. Also extracts imeta image (thumbnail) and duration, the top-level published_at tag, and the top-level alt tag (as a fallback displayName on the first video/audio attachment).
  • Stop converting Nostr summary to AS1 summary.
  • Nostr constructor: raise ValueError on invalid relay URL.
  • Nostr.query: skip NIP-42 AUTH challenge gracefully when no privkey is set.

Migrate tests from mox3 to unittest.mock.