minimal-activitypub


Nameminimal-activitypub JSON
Version 0.5.1 PyPI version JSON
download
home_pagehttps://codeberg.org/MarvinsMastodonTools/mastodonamnesia
SummaryMinimal inplementation of ActivityPub Interface
upload_time2023-02-08 07:08:32
maintainer
docs_urlNone
authormarvin8
requires_python>=3.9,<4.0
licenseAGPL-3.0-or-later
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Minimal-ActivityPub
===================

|Repo| |CI| |Downloads|

|Safety| |pip-audit| |Interrogate|

|Codestyle| |Version| |Wheel|

|AGPL|


Minimal-ActivityPub is a minimal Python implementation of the ActivityPub rest API used by
`Mastodon <https://joinmastodon.org/>`_,
`Pleroma <https://pleroma.social/>`_,
and others. This implementation makes use of asyncio where appropriate. It is intended to be used as a library by other
applications. No standalone functionality is provided.

Minimal refers to the fact that only API calls I need for my other projects;
`MastodonAmnesia <https://codeberg.org/MarvinsMastodonTools/mastodonamnesia>`_ and
`TootBot <https://codeberg.org/MarvinsMastodonTools/tootbot>`_ are implemented.

**DO NOT** expect a full or complete implementation of all `ActivityPub API <https://activitypub.rocks/>`_ functionality.

API Methods Currently Implemented
==================================

Client to Server Methods
----------------------------------
- get_auth_token
- verify_credentials
- determine_instance_type
- get_account_statuses
- delete_status
- post_status
- post_media
- undo_reblog
- undo_favourite
- create_app (documentation to follow)
- generate_authorization_url (documentation to follow)
- validate_authorization_code (documentation to follow)


Server to Server Methods
----------------------------------
No API methods for server to server communications have been implemented.

Usage
==================================
Minimal-ActivityPub is available on `PyPi <https://pypi.org/>`_ as `minimal-activitypub` and can be added to an
application the same as any other python library.

Add `minimal-activitypub` as a requirement to your project and/or install using pip::

    pip install minimal-activitypub

Workflow overview
----------------------------------
In general you need the authenticate to an ActivityPub server instance. To do so you require an `access_token`, so generally
you'll want to use the method ``get_auth_token`` when setting up the initial connection.

After that I think it is a good idea to verify the credentials using the ``verify_credentials`` method and determine the
server type using the ``determine_instance_type`` method.

After that you use which ever method(s) that are needed for your use case.

.. Todo: Add individual explanation for each method.

Example for ``get_auth_token(...)``
-----------------------------------------
To get an Auth Token (also referred to as an access token) your code needs to be able to login to the Fediverse instance.
In this API implementation we do so using the user_name (email for Mastodon instances) and the user's password.
Neither of these values is being stored after an auth token has been obtained.

.. code-block:: python

    async def example(instance, user_name, password):
        async with aiohttp.ClientSession() as session:
            access_token = await ActivityPub.get_auth_token(
                instance_url=instance,
                username=user_name,
                password=password,
                session=session,
        )

Example for ``verify_credentials(...)``
-----------------------------------------
``verify_credentials(...)`` ensures that the access_token is valid and returns information about the user that the
access_token has been created for. It is good practice to check the validity of the access_token with this method call
before any further interaction with the Fediverse instance.

.. code-block:: python

    async def example(instance, access_token):
        async with aiohttp.ClientSession() as session:
            instance = ActivityPub(
                instance=instance,
                access_token=access_token,
                session=session,
            )
            user_info = await instance.verify_credentials()
            account_id = user_info["id"]
            user_name = user_info["username"]

Example for ``determine_instance_type()``
-----------------------------------------
``determine_instance_type()`` checks what type of server we are interacting with. At this time minimal-activitypub only
check for Pleroma and otherwise defaults to Mastodon.
This method updates the instance variable ``is_instance_pleroma`` to ``True`` if the Fediverse server is
running Pleroma

.. code-block:: python

    async def example(instance, access_token):
        async with aiohttp.ClientSession() as session:
            instance = ActivityPub(
                instance=instance,
                access_token=access_token,
                session=session,
            )
            await instance.determine_instance_type()

Example for ``get_account_statuses(...)``
-----------------------------------------
``get_account_statuses(...)`` retrieves a list of the most recent toots posted by the account identified by its id.
This method updates the instance variables ``pagination_max_id`` and ``pagination_min_id`` with the values for ``min_id``
and ``max_id`` returned by the server in the http response header.
These values can be used to paginate forward and backwards through the history of toots.

.. code-block:: python

    async def example(account_id):
        async with aiohttp.ClientSession() as session:
            instance = ActivityPub(
                instance=instance,
                access_token=access_token,
                session=session,
            )
            toots = await instance.get_account_statuses(account_id=account_id)

            # retrieving the next set of toots
            if instance.pagination_max_id:
                toots = await instance.get_account_statuses(
                    account_id=account_id,
                    max_id=instance.pagination_max_id,
                )

Example for ``delete_status(...)``
-----------------------------------------
``delete_status(...)`` deletes a toot / post / status identified by its id.
This method returns the deleted toot / post / status.

.. code-block:: python

    async def example(toot_id):
        async with aiohttp.ClientSession() as session:
            instance = ActivityPub(
                instance=instance,
                access_token=access_token,
                session=session,
            )
            deleted_toot = await instance.delete_status(status_id=toot_id)

Example for ``post_status(...)``
-----------------------------------------
``post_status(...)`` creates a toot / post / status identified.
This method returns the created toot / post / status.

.. code-block:: python

    async def example(status_text: str):
        async with aiohttp.ClientSession() as session:
            instance = ActivityPub(
                instance=instance,
                access_token=access_token,
                session=session,
            )

            toot = await instance.post_status(
                status=status_text,
            )

Example for ``post_media(...)``
-----------------------------------------
``post_media(...)`` sends an image or video to the server. This needs to be done to be able to attach an image or
video to a toot / post / status
This method returns a dictionary containing details for this media on server, such a `id`, `url` etc.

.. code-block:: python

    async def example(media_path: str):
        async with aiohttp.ClientSession() as session:
            instance = ActivityPub(
                instance=instance,
                access_token=access_token,
                session=session,
            )

            mime_type = magic.from_file(media_path, mime=True)
            async with aiofiles.open(file=media_path, mode="rb") as upload:
                media = await instance.post_media(
                    file=upload,
                    mime_type=mime_type,
                )

            media_ids = [media['id'], ]
            toot = await instance.post_status(
                status="Test status with media attached",
                media_ids=media_ids,
            )

Contributing
==================================
Issues and pull requests are welcome.

Minimal-ActivityPub is using `pre-commit <https://pre-commit.com/>`_ and `Poetry <https://python-poetry.org/>`_.
Please install and use both pre-commit and Poetry if you'd like to contribute.

To make sure you have all required python modules installed with Poetry is as easy as ``poetry install`` in the root of the
project directory

Licensing
==================================
Minimal-ActivityPub is licences under licensed under the `GNU Affero General Public License v3.0 <http://www.gnu.org/licenses/agpl-3.0.html>`_

Supporting Minimal-ActivityPub
==================================

There are a number of ways you can support Minimal-ActivityPub:

- Create an issue with problems or ideas you have with/for Minimal-ActivityPub
- You can `buy me a coffee <https://www.buymeacoffee.com/marvin8>`_.
- You can send me small change in Monero to the address below:

Monero donation address:
----------------------------------
`8ADQkCya3orL178dADn4bnKuF1JuVGEG97HPRgmXgmZ2cZFSkWU9M2v7BssEGeTRNN2V5p6bSyHa83nrdu1XffDX3cnjKVu`


.. |AGPL| image:: https://www.gnu.org/graphics/agplv3-with-text-162x68.png
    :alt: AGLP 3 or later
    :target:  https://codeberg.org/MarvinsMastodonTools/minimal-activitypub/src/branch/main/LICENSE.md

.. |Repo| image:: https://img.shields.io/badge/repo-Codeberg.org-blue
    :alt: Repo at Codeberg.org
    :target: https://codeberg.org/MarvinsMastodonTools/minimal-activitypub

.. |Downloads| image:: https://pepy.tech/badge/minimal-activitypub
    :alt: Download count
    :target: https://pepy.tech/project/minimal-activitypub

.. |Codestyle| image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :alt: Code style: black
    :target: https://github.com/psf/black

.. |Safety| image:: https://img.shields.io/badge/Safety--DB-checked-green
    :alt: Checked against PyUp Safety DB
    :target: https://pyup.io/safety/

.. |pip-audit| image:: https://img.shields.io/badge/pip--audit-checked-green
    :alt: Checked with pip-audit
    :target: https://pypi.org/project/pip-audit/

.. |Version| image:: https://img.shields.io/pypi/pyversions/minimal-activitypub
    :alt: PyPI - Python Version

.. |Wheel| image:: https://img.shields.io/pypi/wheel/minimal-activitypub
    :alt: PyPI - Wheel

.. |CI| image:: https://ci.codeberg.org/api/badges/MarvinsMastodonTools/minimal-activitypub/status.svg
    :alt: CI / Woodpecker
    :target: https://ci.codeberg.org/MarvinsMastodonTools/minimal-activitypub

.. |Interrogate| image:: https://codeberg.org/MarvinsMastodonTools/minimal-activitypub/raw/branch/main/interrogate_badge.svg
    :alt: Doc-string coverage
    :target: https://interrogate.readthedocs.io/en/latest/

            

Raw data

            {
    "_id": null,
    "home_page": "https://codeberg.org/MarvinsMastodonTools/mastodonamnesia",
    "name": "minimal-activitypub",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.9,<4.0",
    "maintainer_email": "",
    "keywords": "",
    "author": "marvin8",
    "author_email": "marvin8@tuta.io",
    "download_url": "https://files.pythonhosted.org/packages/54/a5/7ccc988d8eba85433df8b478f02f69c4db774ac7422e9823fd5b63423c20/minimal_activitypub-0.5.1.tar.gz",
    "platform": null,
    "description": "Minimal-ActivityPub\n===================\n\n|Repo| |CI| |Downloads|\n\n|Safety| |pip-audit| |Interrogate|\n\n|Codestyle| |Version| |Wheel|\n\n|AGPL|\n\n\nMinimal-ActivityPub is a minimal Python implementation of the ActivityPub rest API used by\n`Mastodon <https://joinmastodon.org/>`_,\n`Pleroma <https://pleroma.social/>`_,\nand others. This implementation makes use of asyncio where appropriate. It is intended to be used as a library by other\napplications. No standalone functionality is provided.\n\nMinimal refers to the fact that only API calls I need for my other projects;\n`MastodonAmnesia <https://codeberg.org/MarvinsMastodonTools/mastodonamnesia>`_ and\n`TootBot <https://codeberg.org/MarvinsMastodonTools/tootbot>`_ are implemented.\n\n**DO NOT** expect a full or complete implementation of all `ActivityPub API <https://activitypub.rocks/>`_ functionality.\n\nAPI Methods Currently Implemented\n==================================\n\nClient to Server Methods\n----------------------------------\n- get_auth_token\n- verify_credentials\n- determine_instance_type\n- get_account_statuses\n- delete_status\n- post_status\n- post_media\n- undo_reblog\n- undo_favourite\n- create_app (documentation to follow)\n- generate_authorization_url (documentation to follow)\n- validate_authorization_code (documentation to follow)\n\n\nServer to Server Methods\n----------------------------------\nNo API methods for server to server communications have been implemented.\n\nUsage\n==================================\nMinimal-ActivityPub is available on `PyPi <https://pypi.org/>`_ as `minimal-activitypub` and can be added to an\napplication the same as any other python library.\n\nAdd `minimal-activitypub` as a requirement to your project and/or install using pip::\n\n    pip install minimal-activitypub\n\nWorkflow overview\n----------------------------------\nIn general you need the authenticate to an ActivityPub server instance. To do so you require an `access_token`, so generally\nyou'll want to use the method ``get_auth_token`` when setting up the initial connection.\n\nAfter that I think it is a good idea to verify the credentials using the ``verify_credentials`` method and determine the\nserver type using the ``determine_instance_type`` method.\n\nAfter that you use which ever method(s) that are needed for your use case.\n\n.. Todo: Add individual explanation for each method.\n\nExample for ``get_auth_token(...)``\n-----------------------------------------\nTo get an Auth Token (also referred to as an access token) your code needs to be able to login to the Fediverse instance.\nIn this API implementation we do so using the user_name (email for Mastodon instances) and the user's password.\nNeither of these values is being stored after an auth token has been obtained.\n\n.. code-block:: python\n\n    async def example(instance, user_name, password):\n        async with aiohttp.ClientSession() as session:\n            access_token = await ActivityPub.get_auth_token(\n                instance_url=instance,\n                username=user_name,\n                password=password,\n                session=session,\n        )\n\nExample for ``verify_credentials(...)``\n-----------------------------------------\n``verify_credentials(...)`` ensures that the access_token is valid and returns information about the user that the\naccess_token has been created for. It is good practice to check the validity of the access_token with this method call\nbefore any further interaction with the Fediverse instance.\n\n.. code-block:: python\n\n    async def example(instance, access_token):\n        async with aiohttp.ClientSession() as session:\n            instance = ActivityPub(\n                instance=instance,\n                access_token=access_token,\n                session=session,\n            )\n            user_info = await instance.verify_credentials()\n            account_id = user_info[\"id\"]\n            user_name = user_info[\"username\"]\n\nExample for ``determine_instance_type()``\n-----------------------------------------\n``determine_instance_type()`` checks what type of server we are interacting with. At this time minimal-activitypub only\ncheck for Pleroma and otherwise defaults to Mastodon.\nThis method updates the instance variable ``is_instance_pleroma`` to ``True`` if the Fediverse server is\nrunning Pleroma\n\n.. code-block:: python\n\n    async def example(instance, access_token):\n        async with aiohttp.ClientSession() as session:\n            instance = ActivityPub(\n                instance=instance,\n                access_token=access_token,\n                session=session,\n            )\n            await instance.determine_instance_type()\n\nExample for ``get_account_statuses(...)``\n-----------------------------------------\n``get_account_statuses(...)`` retrieves a list of the most recent toots posted by the account identified by its id.\nThis method updates the instance variables ``pagination_max_id`` and ``pagination_min_id`` with the values for ``min_id``\nand ``max_id`` returned by the server in the http response header.\nThese values can be used to paginate forward and backwards through the history of toots.\n\n.. code-block:: python\n\n    async def example(account_id):\n        async with aiohttp.ClientSession() as session:\n            instance = ActivityPub(\n                instance=instance,\n                access_token=access_token,\n                session=session,\n            )\n            toots = await instance.get_account_statuses(account_id=account_id)\n\n            # retrieving the next set of toots\n            if instance.pagination_max_id:\n                toots = await instance.get_account_statuses(\n                    account_id=account_id,\n                    max_id=instance.pagination_max_id,\n                )\n\nExample for ``delete_status(...)``\n-----------------------------------------\n``delete_status(...)`` deletes a toot / post / status identified by its id.\nThis method returns the deleted toot / post / status.\n\n.. code-block:: python\n\n    async def example(toot_id):\n        async with aiohttp.ClientSession() as session:\n            instance = ActivityPub(\n                instance=instance,\n                access_token=access_token,\n                session=session,\n            )\n            deleted_toot = await instance.delete_status(status_id=toot_id)\n\nExample for ``post_status(...)``\n-----------------------------------------\n``post_status(...)`` creates a toot / post / status identified.\nThis method returns the created toot / post / status.\n\n.. code-block:: python\n\n    async def example(status_text: str):\n        async with aiohttp.ClientSession() as session:\n            instance = ActivityPub(\n                instance=instance,\n                access_token=access_token,\n                session=session,\n            )\n\n            toot = await instance.post_status(\n                status=status_text,\n            )\n\nExample for ``post_media(...)``\n-----------------------------------------\n``post_media(...)`` sends an image or video to the server. This needs to be done to be able to attach an image or\nvideo to a toot / post / status\nThis method returns a dictionary containing details for this media on server, such a `id`, `url` etc.\n\n.. code-block:: python\n\n    async def example(media_path: str):\n        async with aiohttp.ClientSession() as session:\n            instance = ActivityPub(\n                instance=instance,\n                access_token=access_token,\n                session=session,\n            )\n\n            mime_type = magic.from_file(media_path, mime=True)\n            async with aiofiles.open(file=media_path, mode=\"rb\") as upload:\n                media = await instance.post_media(\n                    file=upload,\n                    mime_type=mime_type,\n                )\n\n            media_ids = [media['id'], ]\n            toot = await instance.post_status(\n                status=\"Test status with media attached\",\n                media_ids=media_ids,\n            )\n\nContributing\n==================================\nIssues and pull requests are welcome.\n\nMinimal-ActivityPub is using `pre-commit <https://pre-commit.com/>`_ and `Poetry <https://python-poetry.org/>`_.\nPlease install and use both pre-commit and Poetry if you'd like to contribute.\n\nTo make sure you have all required python modules installed with Poetry is as easy as ``poetry install`` in the root of the\nproject directory\n\nLicensing\n==================================\nMinimal-ActivityPub is licences under licensed under the `GNU Affero General Public License v3.0 <http://www.gnu.org/licenses/agpl-3.0.html>`_\n\nSupporting Minimal-ActivityPub\n==================================\n\nThere are a number of ways you can support Minimal-ActivityPub:\n\n- Create an issue with problems or ideas you have with/for Minimal-ActivityPub\n- You can `buy me a coffee <https://www.buymeacoffee.com/marvin8>`_.\n- You can send me small change in Monero to the address below:\n\nMonero donation address:\n----------------------------------\n`8ADQkCya3orL178dADn4bnKuF1JuVGEG97HPRgmXgmZ2cZFSkWU9M2v7BssEGeTRNN2V5p6bSyHa83nrdu1XffDX3cnjKVu`\n\n\n.. |AGPL| image:: https://www.gnu.org/graphics/agplv3-with-text-162x68.png\n    :alt: AGLP 3 or later\n    :target:  https://codeberg.org/MarvinsMastodonTools/minimal-activitypub/src/branch/main/LICENSE.md\n\n.. |Repo| image:: https://img.shields.io/badge/repo-Codeberg.org-blue\n    :alt: Repo at Codeberg.org\n    :target: https://codeberg.org/MarvinsMastodonTools/minimal-activitypub\n\n.. |Downloads| image:: https://pepy.tech/badge/minimal-activitypub\n    :alt: Download count\n    :target: https://pepy.tech/project/minimal-activitypub\n\n.. |Codestyle| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n    :alt: Code style: black\n    :target: https://github.com/psf/black\n\n.. |Safety| image:: https://img.shields.io/badge/Safety--DB-checked-green\n    :alt: Checked against PyUp Safety DB\n    :target: https://pyup.io/safety/\n\n.. |pip-audit| image:: https://img.shields.io/badge/pip--audit-checked-green\n    :alt: Checked with pip-audit\n    :target: https://pypi.org/project/pip-audit/\n\n.. |Version| image:: https://img.shields.io/pypi/pyversions/minimal-activitypub\n    :alt: PyPI - Python Version\n\n.. |Wheel| image:: https://img.shields.io/pypi/wheel/minimal-activitypub\n    :alt: PyPI - Wheel\n\n.. |CI| image:: https://ci.codeberg.org/api/badges/MarvinsMastodonTools/minimal-activitypub/status.svg\n    :alt: CI / Woodpecker\n    :target: https://ci.codeberg.org/MarvinsMastodonTools/minimal-activitypub\n\n.. |Interrogate| image:: https://codeberg.org/MarvinsMastodonTools/minimal-activitypub/raw/branch/main/interrogate_badge.svg\n    :alt: Doc-string coverage\n    :target: https://interrogate.readthedocs.io/en/latest/\n",
    "bugtrack_url": null,
    "license": "AGPL-3.0-or-later",
    "summary": "Minimal inplementation of ActivityPub Interface",
    "version": "0.5.1",
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b0eb43bcf087c3f99f49955c4ae2e3eb23044ff2dedfcdf4b89e3f1e3765e343",
                "md5": "98c5db779a0486d2dab129021d2d3266",
                "sha256": "e001fb6cc14e04d42006aab20aae4efe25e3bec5bf07da0f6b6539a2ce7b1161"
            },
            "downloads": -1,
            "filename": "minimal_activitypub-0.5.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "98c5db779a0486d2dab129021d2d3266",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9,<4.0",
            "size": 22614,
            "upload_time": "2023-02-08T07:08:29",
            "upload_time_iso_8601": "2023-02-08T07:08:29.972370Z",
            "url": "https://files.pythonhosted.org/packages/b0/eb/43bcf087c3f99f49955c4ae2e3eb23044ff2dedfcdf4b89e3f1e3765e343/minimal_activitypub-0.5.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "54a57ccc988d8eba85433df8b478f02f69c4db774ac7422e9823fd5b63423c20",
                "md5": "34f89a146c937419fcc4ea4a86f5a952",
                "sha256": "824633701e4f8ef714719f685efea0b8b7be1b5f955570650f90a9e6c51279b8"
            },
            "downloads": -1,
            "filename": "minimal_activitypub-0.5.1.tar.gz",
            "has_sig": false,
            "md5_digest": "34f89a146c937419fcc4ea4a86f5a952",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9,<4.0",
            "size": 26506,
            "upload_time": "2023-02-08T07:08:32",
            "upload_time_iso_8601": "2023-02-08T07:08:32.002627Z",
            "url": "https://files.pythonhosted.org/packages/54/a5/7ccc988d8eba85433df8b478f02f69c4db774ac7422e9823fd5b63423c20/minimal_activitypub-0.5.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-02-08 07:08:32",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "lcname": "minimal-activitypub"
}
        
Elapsed time: 0.11159s