I’ve uploaded the first version of bovine to pypi, you can find it at https://pypi.org/project/bovine/. The functionality in there is much slimmer than the full server, I have running at mymath.rocks. It’s basically just an “ActivityPub Client”, for some meaning of the word.
Now the warning, once I finish writing up the example, everybody with access to pip and a domain will be able to copy and paste together something they can use to send valid HTTP signed ActivityPub activities.
I personally consider this a good thing, as it will make it easier for people to get started. On the other hand, I don’t know if I should expect abuse.
My vision is that this is just python code and not a dedicated server. I’ve also updated to version 0.0.9 as I found some not so nice things when working out the fake server example.
The result is available at
If I wanted to make everything easier to understand, I should probably even create a synchronous version, which has become the first issue on codeberg.
I think it depends on what you are talking about. The library bovine on pypi will contain three things (after I do some refactoring to make stuff clearer):
BovineActor: An implementation of the network interface used by an ActivityPub Server to make the “actor network calls”:
POST /inbox of other actors
GET object_id (when proxying elements for client)
BovineClient: An implementation that allows one to communicate with the ActivityPub Server as an ActivityPub Client. Operations include:
POST /outbox results in ActivityPub Actor performing POST /inbox to the recipients
POST /proxyUrl results in ActivityPub Actor performing GET object_id
GET /inbox results in retrieving what other Actors have send to it
GET /outbox results in retrieving what other Clients of the same Actor have send to it
furthermore, it encapsulates creating ActivityStream objects through factories …
Various helper stuff for handling signatures of HTTP requests or OrderedCollections …
I’ll try to have a clear picture of what 3 should be before going for bovine 0.1.0 on pypi. The important part is that I think 1 and 2 offer two classes that should encapsulate a lot of behavior in a way, one can then forget about it.
There are some “white lies” above, because there is for example a caching layer between proxyUrl and GET.
BovineActor as described above, is unable to receive messages. It doesn’t expose a server endpoint. It is meant to perform calls.
The other half to get to an ActivityPub server is contained in bovine_fedi, but that code works but isn’t really good. There is too much small stuff that was build in a particular way just to work.
The point of separating out the ActivityPub client code is that I can now build things like longhorn, what is behind blog.mymath.rocks with bovine as a proper dependency. You do not want to pull the entire server as a dependency, just the code you actually need.
Also I’ve done the split into BovineClient and BovineActor for it. There is still a lot of work to do, like documenting the Activity-, ObjectFactory classes, and explain how to verify signatures.
However, I am quite confident that one can now use the package to start doing some stuff in python, if one is so inclined. The main advantage is that, I believe the interfaces for BovineClient and BovineActor should be stable.
I’ve tried to create a diagram of how I see the architecture of these things progress. It’s not great yet.
I also coined the term ActivityPub Bot for basically what it says. It’s a bot that sits on your ActivityClient and does some automated tasks such as accepting follow requests.