<!--
SPDX-FileCopyrightText: 2023 Helge
SPDX-FileCopyrightText: 2024 helge
SPDX-License-Identifier: MIT
-->
# Bovine
Bovine is a basic utility library for the Fediverse. It can be used both to build ActivityPub Client applications and ActivityPub Servers. In addition to [ActivityPub](https://activitypub.rocks/) support, it also provides utilities to deal with [webfinger](https://webfinger.net), nodeinfo, and HTTP Signatures.
The [bovine library](https://pypi.org/project/bovine/) can just be installed via pip
```bash
pip install bovine
```
Documentation including tutorials is available at [ReadTheDocs](https://bovine.readthedocs.io/en/latest/).
## A quick Fediverse server with docker compose
Using the [bovine docker image](https://hub.docker.com/r/helgekr/bovine), the following [docker compose file](https://codeberg.org/bovine/bovine/src/branch/main/bovine/resources/docker/docker-compose.yaml), and a service such as [ngrok](https://ngrok.com/) allowing one to expose a local port to the internet, one can create a python shell that allows one to use bovine
to interact with the Fediverse
```yml
services:
bovine:
image: helgekr/bovine
environment:
- "BOVINE_TEST_HOSTNAME=${NGROK_HOSTNAME}"
- "BOVINE_TEST_PROTOCOL=https"
volumes: ["bovine_shared:/bovine"]
ports: ["5000:80"]
command: python -mbovine.testing serve --port 80 --reload --save_config=/bovine/config.toml
repl:
image: helgekr/bovine
command: python -mbovine.testing shell --load_config=/bovine/config.toml
depends_on: [bovine]
profiles: ["repl"]
volumes: ["bovine_shared:/bovine"]
volumes:
bovine_shared:
```
When using ngrok with `ngrok http 5000`, you can directly run the above file via
```bash
NGROK_HOSTNAME=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq '.tunnels[0].public_url' | sed "s|https://||g" | sed 's|"||g') docker compose run repl
```
otherwise you will have to set the variable `BOVINE_TEST_HOSTNAME` to the appropriate host.
By using
```python
>>> helge = await webfinger("acct:helge@mymath.rocks")
>>> inbox = (await actor.get(helge))["inbox"]
>>> helge
"https://mymath.rocks/endpoints/SYn3cl_N4HAPfPHgo2x37XunLEmhV9LnxCggcYwyec0"
```
one can resolve an acct uri to the actor's uri and
then record its inbox. Then one
can create a message via
```python
>>> mention = {"href": helge, "type": "Mention"}
>>> note = object_factory.note(to={helge}, content="Writing a README thus talking to myself", tag=[mention]).as_public().build()
>>> note
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Note",
"attributedTo": "https://8fc-2003-c1-c73c-a901-b426-f511-88e5-77e3.ngrok-free.app/buttercup",
"to": ["https://mymath.rocks/endpoints/SYn3cl_N4HAPfPHgo2x37XunLEmhV9LnxCggcYwyec0", "https://www.w3.org/ns/activitystreams#Public"],
"id": "https://8fc-2003-c1-c73c-a901-b426-f511-88e5-77e3.ngrok-free.app/HFL5hpzi",
"published": "2024-11-24T12:30:54Z",
"content": "Writing a README thus talking to myself",
}
```
By then running
```python
>>> await actor.post(inbox, activity_factory.create(note).build())
<ClientResponse(https://mymath.rocks/endpoints/SYONtD8yAKPapRuifwDJ8P0OhcuB7ntjkHdxh_OkrWQ) [202 None]>
```
one can post the message. It should then appear in your Fedi client
![Screenshot of the message from buttercup](./buttercup.png)
One can view messages received in the inbox via
```bash
docker compose logs -f
```
Further information on the testing server can be
found in [Using bovine with the fediverse-pasture](https://bovine.readthedocs.io/en/latest/tutorials/pasture/)
in the documentation.
## Feedback
Issues about bovine should be filed as an [issue](https://codeberg.org/bovine/bovine/issues).
## Running BDD Tests
bovine uses the [fediverse-features](https://codeberg.org/helge/fediverse-features#)
to provide BDD tests. These can be run by first downloading the feature files
via
```bash
poetry run python -mfediverse_features
```
and then running behave
```bash
poetry run behave
```
## Contributing
If you want to contribute, you can start by working on issues labeled [Good first issue](https://codeberg.org/bovine/bovine/issues?q=&type=all&state=open&labels=110885&milestone=0&assignee=0&poster=0). The tech stack is currently based on asynchronous python, using the following components:
- [aiohttp](https://docs.aiohttp.org/en/stable/index.html) for http requests.
- [quart](https://quart.palletsprojects.com/en/latest/) as a webserver.
- [cryptography](https://cryptography.io/en/latest/).
- [pytest](https://docs.pytest.org/en/7.3.x/) for testing.
- [ruff](https://pypi.org/project/ruff/) for linting.
Raw data
{
"_id": null,
"home_page": "https://codeberg.org/bovine/bovine",
"name": "bovine",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.11",
"maintainer_email": null,
"keywords": "ActivityPub, FediVerse",
"author": "Helge",
"author_email": "helge.krueger@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/30/69/c43dafbca9221f9f367fe91f8459ee490590b29ff15df674cbc738bd23c9/bovine-0.5.15.tar.gz",
"platform": null,
"description": "<!--\nSPDX-FileCopyrightText: 2023 Helge\nSPDX-FileCopyrightText: 2024 helge\n\nSPDX-License-Identifier: MIT\n-->\n\n# Bovine\n\nBovine is a basic utility library for the Fediverse. It can be used both to build ActivityPub Client applications and ActivityPub Servers. In addition to [ActivityPub](https://activitypub.rocks/) support, it also provides utilities to deal with [webfinger](https://webfinger.net), nodeinfo, and HTTP Signatures.\n\nThe [bovine library](https://pypi.org/project/bovine/) can just be installed via pip\n\n```bash\npip install bovine\n```\n\nDocumentation including tutorials is available at [ReadTheDocs](https://bovine.readthedocs.io/en/latest/).\n\n## A quick Fediverse server with docker compose\n\nUsing the [bovine docker image](https://hub.docker.com/r/helgekr/bovine), the following [docker compose file](https://codeberg.org/bovine/bovine/src/branch/main/bovine/resources/docker/docker-compose.yaml), and a service such as [ngrok](https://ngrok.com/) allowing one to expose a local port to the internet, one can create a python shell that allows one to use bovine\nto interact with the Fediverse\n\n```yml\nservices:\n bovine:\n image: helgekr/bovine\n environment:\n - \"BOVINE_TEST_HOSTNAME=${NGROK_HOSTNAME}\"\n - \"BOVINE_TEST_PROTOCOL=https\"\n volumes: [\"bovine_shared:/bovine\"]\n ports: [\"5000:80\"]\n command: python -mbovine.testing serve --port 80 --reload --save_config=/bovine/config.toml\n repl:\n image: helgekr/bovine\n command: python -mbovine.testing shell --load_config=/bovine/config.toml\n depends_on: [bovine]\n profiles: [\"repl\"]\n volumes: [\"bovine_shared:/bovine\"]\nvolumes:\n bovine_shared:\n```\n\nWhen using ngrok with `ngrok http 5000`, you can directly run the above file via\n\n```bash\nNGROK_HOSTNAME=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq '.tunnels[0].public_url' | sed \"s|https://||g\" | sed 's|\"||g') docker compose run repl\n```\n\notherwise you will have to set the variable `BOVINE_TEST_HOSTNAME` to the appropriate host.\n\nBy using\n\n```python\n>>> helge = await webfinger(\"acct:helge@mymath.rocks\")\n>>> inbox = (await actor.get(helge))[\"inbox\"]\n>>> helge\n\"https://mymath.rocks/endpoints/SYn3cl_N4HAPfPHgo2x37XunLEmhV9LnxCggcYwyec0\"\n```\n\none can resolve an acct uri to the actor's uri and\nthen record its inbox. Then one\ncan create a message via\n\n```python\n>>> mention = {\"href\": helge, \"type\": \"Mention\"}\n>>> note = object_factory.note(to={helge}, content=\"Writing a README thus talking to myself\", tag=[mention]).as_public().build()\n>>> note\n{\n \"@context\": \"https://www.w3.org/ns/activitystreams\",\n \"type\": \"Note\",\n \"attributedTo\": \"https://8fc-2003-c1-c73c-a901-b426-f511-88e5-77e3.ngrok-free.app/buttercup\",\n \"to\": [\"https://mymath.rocks/endpoints/SYn3cl_N4HAPfPHgo2x37XunLEmhV9LnxCggcYwyec0\", \"https://www.w3.org/ns/activitystreams#Public\"],\n \"id\": \"https://8fc-2003-c1-c73c-a901-b426-f511-88e5-77e3.ngrok-free.app/HFL5hpzi\",\n \"published\": \"2024-11-24T12:30:54Z\",\n \"content\": \"Writing a README thus talking to myself\",\n}\n```\n\nBy then running\n\n```python\n>>> await actor.post(inbox, activity_factory.create(note).build())\n<ClientResponse(https://mymath.rocks/endpoints/SYONtD8yAKPapRuifwDJ8P0OhcuB7ntjkHdxh_OkrWQ) [202 None]>\n```\n\none can post the message. It should then appear in your Fedi client\n\n![Screenshot of the message from buttercup](./buttercup.png)\n\nOne can view messages received in the inbox via\n\n```bash\ndocker compose logs -f\n```\n\nFurther information on the testing server can be\nfound in [Using bovine with the fediverse-pasture](https://bovine.readthedocs.io/en/latest/tutorials/pasture/)\nin the documentation.\n\n## Feedback\n\nIssues about bovine should be filed as an [issue](https://codeberg.org/bovine/bovine/issues).\n\n## Running BDD Tests\n\nbovine uses the [fediverse-features](https://codeberg.org/helge/fediverse-features#)\nto provide BDD tests. These can be run by first downloading the feature files\nvia\n\n```bash\npoetry run python -mfediverse_features\n```\n\nand then running behave\n\n```bash\npoetry run behave\n```\n\n## Contributing\n\nIf you want to contribute, you can start by working on issues labeled [Good first issue](https://codeberg.org/bovine/bovine/issues?q=&type=all&state=open&labels=110885&milestone=0&assignee=0&poster=0). The tech stack is currently based on asynchronous python, using the following components:\n\n- [aiohttp](https://docs.aiohttp.org/en/stable/index.html) for http requests.\n- [quart](https://quart.palletsprojects.com/en/latest/) as a webserver.\n- [cryptography](https://cryptography.io/en/latest/).\n- [pytest](https://docs.pytest.org/en/7.3.x/) for testing.\n- [ruff](https://pypi.org/project/ruff/) for linting.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Core functionality of bovine needed to build fediverse applications",
"version": "0.5.15",
"project_urls": {
"Documentation": "https://bovine.readthedocs.io/en/latest/",
"Homepage": "https://codeberg.org/bovine/bovine",
"Repository": "https://codeberg.org/bovine/bovine"
},
"split_keywords": [
"activitypub",
" fediverse"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "21aba62b3a8b338064e85d3ecd6dbafc209e6182d9d15953005ec6062c64584a",
"md5": "49afa1a273008f9bfd149125556c7dc2",
"sha256": "8accf266b7f1e0e5358f9b2d85ec328f27e650a080100258e46eef989331d3df"
},
"downloads": -1,
"filename": "bovine-0.5.15-py3-none-any.whl",
"has_sig": false,
"md5_digest": "49afa1a273008f9bfd149125556c7dc2",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.11",
"size": 249884,
"upload_time": "2024-12-26T19:34:03",
"upload_time_iso_8601": "2024-12-26T19:34:03.312045Z",
"url": "https://files.pythonhosted.org/packages/21/ab/a62b3a8b338064e85d3ecd6dbafc209e6182d9d15953005ec6062c64584a/bovine-0.5.15-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "3069c43dafbca9221f9f367fe91f8459ee490590b29ff15df674cbc738bd23c9",
"md5": "a77f02f120b1323eafa4ceb8feb70cbb",
"sha256": "75831d2113534f8e8cdacfde49e9ede932f8ba3469382bdb3f6dccf68342818a"
},
"downloads": -1,
"filename": "bovine-0.5.15.tar.gz",
"has_sig": false,
"md5_digest": "a77f02f120b1323eafa4ceb8feb70cbb",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.11",
"size": 406228,
"upload_time": "2024-12-26T19:34:05",
"upload_time_iso_8601": "2024-12-26T19:34:05.062005Z",
"url": "https://files.pythonhosted.org/packages/30/69/c43dafbca9221f9f367fe91f8459ee490590b29ff15df674cbc738bd23c9/bovine-0.5.15.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-26 19:34:05",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": true,
"codeberg_user": "bovine",
"codeberg_project": "bovine",
"lcname": "bovine"
}