Skip to main content

Python Libraries

Python libraries for implementing ActivityPub.

bovine

Modern ActivityPub library for Python.

PropertyValue
Repositorycodeberg.org/bovine/bovine
Documentationbovine.readthedocs.io
LicenseMIT
StatusActive

Features

  • Async/await support
  • ActivityPub client and server
  • HTTP Signatures
  • WebFinger

Example

from bovine import BovineClient
from bovine.activitystreams import build_actor

# Create an actor
actor = build_actor(
actor_id="https://example.com/users/alice",
name="Alice",
preferred_username="alice"
)

# Send an activity
client = BovineClient(private_key, key_id)
await client.post(
inbox_url="https://remote.example/inbox",
activity=activity
)

Federation

Django library for federation protocols.

PropertyValue
Repositorygithub.com/jaywink/federation
Documentationfederation.readthedocs.io
LicenseBSD-3
StatusActive

Features

  • Django integration
  • Multiple protocols (ActivityPub, Diaspora)
  • Inbound/outbound handling

Example

from federation.entities import Post
from federation.outbound import handle_send

post = Post(
id="https://example.com/posts/123",
actor_id="https://example.com/users/alice",
raw_content="Hello, Fediverse!",
)

handle_send(post, recipients)

little-boxes

ActivityPub toolkit.

PropertyValue
Repositorygithub.com/tsileo/little-boxes
LicenseISC
StatusMaintenance

Example

from little_boxes import activitypub as ap

class MyBackend(ap.Backend):
def fetch_iri(self, iri):
# Fetch remote object
pass

def inbox_new(self, as_actor, activity):
# Handle incoming activity
pass

backend = MyBackend()
ap.use_backend(backend)

# Create an activity
note = ap.Note(
content="Hello!",
to=[ap.AS_PUBLIC],
attributedTo="https://example.com/users/alice"
)

httpsig

HTTP Signature library.

PropertyValue
Repositorygithub.com/ahknight/httpsig
piphttpsig
StatusStable

Signing

from httpsig import HTTPSignatureAuth
import requests

auth = HTTPSignatureAuth(
key_id='https://example.com/users/alice#main-key',
secret=private_key,
algorithm='rsa-sha256',
headers=['(request-target)', 'host', 'date', 'digest']
)

response = requests.post(
'https://remote.example/inbox',
json=activity,
auth=auth
)

PyLD

JSON-LD processor.

PropertyValue
Repositorygithub.com/digitalbazaar/pyld
pipPyLD
StatusActive

Example

from pyld import jsonld

# Expand
expanded = jsonld.expand(document)

# Compact
compacted = jsonld.compact(expanded, {
"@context": "https://www.w3.org/ns/activitystreams"
})

Comparison

LibraryFrameworkProtocolsComplexity
bovineAny/asyncActivityPubMedium
federationDjangoMultipleHigh
little-boxesAnyActivityPubMedium
httpsigAny-Low

Quick Start

For Django projects: Use Federation.

For async projects: Use bovine.

For Flask/other: Use little-boxes or build custom.

Example: Minimal Server

from flask import Flask, request, jsonify
from httpsig import HTTPSignatureAuth
import json

app = Flask(__name__)

@app.route('/users/<username>', methods=['GET'])
def actor(username):
return jsonify({
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Person",
"id": f"https://example.com/users/{username}",
"preferredUsername": username,
"inbox": f"https://example.com/users/{username}/inbox",
"outbox": f"https://example.com/users/{username}/outbox"
})

@app.route('/users/<username>/inbox', methods=['POST'])
def inbox(username):
activity = request.json
# Process activity
return '', 202

See Also