Modular ActivityPub/Fediverse Server
Go to file
helge b607e3004f
ci/woodpecker/push/test Pipeline was successful Details
ci/woodpecker/tag/release Pipeline failed Details
ci/woodpecker/tag/test Pipeline was successful Details
Merge pull request 'bovine 0.4.0' (#49) from helge/bovine:dev into main
Reviewed-on: #49
2023-09-20 15:07:53 +00:00
.woodpecker Update to get tests green 2023-09-01 20:10:00 +02:00
bovine fixes 2023-09-20 17:07:37 +02:00
bovine_herd fixes 2023-09-20 17:07:37 +02:00
bovine_process bovine_store, bovine_process 0.4.0 2023-09-20 12:48:27 +02:00
bovine_pubsub Final update to bovine 0.4.0 2023-09-20 15:42:22 +02:00
bovine_store bovine_store, bovine_process 0.4.0 2023-09-20 12:48:27 +02:00
bovine_tool update pyproject.toml to 0.3.2 2023-08-27 14:29:00 +02:00
bovine_web Enable using processor for outbo 2023-08-29 19:20:30 +02:00
ci Cleanup of propan interfaces 2023-08-30 18:32:27 +02:00
docs Add abilitie to run tests against sqlite/postgres in docker 2023-08-17 16:56:34 +02:00
examples improve_user_management (#7) 2023-04-25 18:37:24 +00:00
features First feature test 2023-07-22 19:08:45 +02:00
http_tests Change signature of BovineClient / BovineActor 2023-09-20 09:47:37 +02:00
tests Use amqp for inbox processing 2023-08-29 15:47:41 +02:00
.gitignore Fix test 2023-06-18 10:06:03 +02:00
LICENSE Initial commit 2023-01-17 15:00:46 +01:00 Add documentation how to run tests with docker compose 2023-08-18 11:35:44 +02:00 use query params in target 2023-09-10 10:55:16 +02:00
docker-compose.yml Cleanup of propan interfaces 2023-08-30 18:32:27 +02:00


Bovine is meant to be a modular FediVerse server that supports ActivityPub. During its history, as how to split the tasks between different modules has become clearer, and the split is not done yet. A lot of the changes are due to the realization that parts can be split away as an ActivityPub Client. Here an ActivityPub Client is an application that communicates with just a single ActivityPub Server.

There are a few more structural comments to make about ActivityPub. One job of a server should be to perform basic validation and sanitation for data it passes to clients (or receives for clients). Doing this for ActivityPub has some consequences:

  • Objects are represented by json-ld with an id.
  • If these objects are sanitized and validated by the server, this means that the object changes.
  • Thus there are two representation: 1. outside (as seen in the Fediverse), 2. inside as passed to clients.

This is not ideal, due to an object with an id now representing two different things. It unfortunately seems unavoidable.

Parts of bovine

When done, these parts should only depend on the parts above them. So bovine_process can be used with only bovine and bovine_store. Furthermore, bovine_store and bovine_process should just provide simple interfaces that can be swapped out.

  • bovine (pypi, docs) provides the basic ActivityPub communication with some form of authorization. Currently, HTTP Signatures and Moo-Auth-1 are supported.

  • bovine_store (pypi, docs)is used to store json-ld by their id and provide a certain level of visibility and access control.

    • Serves requests directly represented by objects
    • Contains the actor storage code, and methods to manage actors
    • Tested with both PostgreSQL and sqlite3 databases
  • bovine_process (pypi) contains the Activity processing described in ActivityPub.

    • Contains tests for the side effects of activities
    • Supported: follow, accept, create, update, delete
  • bovine_pubsub (pypi) allows events to be propagated to subscribers. Two variants exist

    • Using asyncio.Queue in the case of a single worker
    • Using Redis for multiple workers. Enabled through setting the environment variable BOVINE_REDIS to the URI of the redis server.
  • bovine_herd (pypi) the FediVerse server implementation. This contains

    • Webfinger, nodeinfo
    • Requests to endpoints not directly represented by objects, i.e. POST inbox
    • Glue code to make everything work together
  • bovine_tool (pypi) basic tools to administer actors in the bovine_store.

  • tests contains a test suite that ensures that bovine_herd properly implements a FediVerse server

Existing ActivityPub Clients

  • mechanical_bull automatically accepts follow requests. This was part of the evolution of my thinking how to separate out ActivityPub Clients.
  • longhorn is a blog. One can visit mine at
  • calf provides a simple terminal user interface for the inbox. This might get expanded into a full client in the future.

Running tests

Using docker, one can run tests in various environments. For this first run

docker compose up -d

Then by running

docker compose run main ./ 
docker compose run main_sqlite ./ 
docker compose run main_11 ./ 
docker compose run main_sqlite_11 ./ 

one can run tests in various configurations. main runs tests using postgres and python 3.10, main_11 runs tests using postgres and python 3.11, main_sqlite runs tests using sqlite3 and python 3.10.