Usage

Entities

Federation has it’s own base entity classes. When incoming messages are processed, the protocol specific entity mappers transform the messages into our base entities. In reverse, when creating outgoing payloads, outgoing protocol specific messages are constructed from the base entities.

Entity types are as follows below.

Protocol entities

Each protocol additionally has it’s own variants of the base entities, for example Diaspora entities in federation.entities.diaspora.entities. All the protocol specific entities subclass the base entities so you can safely work with for example DiasporaPost and use isinstance(obj, Post).

When creating incoming objects from messages, protocol specific entity classes are returned. This is to ensure protocol specific extra attributes or methods are passed back to the caller.

For sending messages out, either base or protocol specific entities can be passed to the outbound senders. Base entities should be preferred unless the caller knows which protocol to send to.

If you need the correct protocol speficic entity class from the base entity, each protocol will define a get_outbound_entity function, for example the Diaspora function as follows.

Discovery

Federation provides many generators to allow providing the discovery documents that are necessary for the Diaspora protocol for example. The have been made as Pythonic as possible so that library users don’t have to meddle with the various documents and their internals.

The protocols themselves are too complex to document within this library, please consult protocol documentation on what kind of discovery documents are expected to be served by the application.

Generators

Helper methods

Generator classes

Fetchers

High level utility functions to fetch remote objects. These should be favoured instead of protocol specific utility functions.

Inbound

High level utility functions to pass incoming messages to. These should be favoured instead of protocol specific utility functions.

Outbound

High level utility functions to pass outbound entities to. These should be favoured instead of protocol specific utility functions.

Django

Some ready provided views and URL configuration exist for Django.

Note! Django is not part of the normal requirements for this library. It must be installed separately.

Configuration

To use the Django views, ensure a modern version of Django is installed and add the views to your URL config for example as follows. The URL’s must be mounted on root if Diaspora protocol support is required.

url(r"", include("federation.hostmeta.django.urls")),

Some settings need to be set in Django settings. An example is below:

FEDERATION = {
    "base_url": "https://myserver.domain.tld,
    "get_object_function": "myproject.utils.get_object",
    "get_profile_function": "myproject.utils.get_profile",
    "nodeinfo2_function": "myproject.utils.get_nodeinfo2_data",
    "process_payload_function": "myproject.utils.process_payload",
    "search_path": "/search/?q=",
}
  • base_url is the base URL of the server, ie protocol://domain.tld.
  • get_object_function should be the full path to a function that will return the object matching the ActivityPub ID for the request object passed to this function.
  • get_profile_function should be the full path to a function that should return a Profile entity. The function should take the following parameters: handle, guid and request. It should look up a profile with one or more of the provided parameters.
  • nodeinfo2_function (optional) function that returns data for generating a NodeInfo2 document. Once configured the path /.well-known/x-nodeinfo2 will automatically generate a NodeInfo2 document. The function should return a dict corresponding to the NodeInfo2 schema, with the following minimum items:
{server:
    baseUrl
    name
    software
    version
}
openRegistrations
  • process_payload_function (optional) function that takes in a request object. It should return True if successful (or placed in queue for processing later) or False in case of any errors.
  • search_path (optional) site search path which ends in a parameter for search input, for example “/search?q=”

Protocols

The code for opening and creating protocol messages lives under each protocol module in federation.protocols.

Each protocol defines a protocol.Protocol class under it’s own module. This is expected to contain certain methods that are used by the higher level functions that are called on incoming messages and when sending outbound messages. Everything that is needed to transform an entity into a message payload and vice versa should be here.

Instead of calling methods directly for a specific protocol, higher level generic functions should be normally used.

Utils

Various utils are provided for internal and external usage.

Diaspora

Network

federation.utils.network.fetch_country_by_ip(ip)

Fetches country code by IP

Returns empty string if the request fails in non-200 code.

Uses the ipdata.co service which has the following rules:

  • Max 1500 requests per day

See: https://ipdata.co/docs.html#python-library

federation.utils.network.fetch_document(url=None, host=None, path='/', timeout=10, raise_ssl_errors=True)

Helper method to fetch remote document.

Must be given either the url or host. If url is given, only that will be tried without falling back to http from https. If host given, path will be added to it. Will fall back to http on non-success status code.

Parameters:
  • url – Full url to fetch, including protocol
  • host – Domain part only without path or protocol
  • path – Path without domain (defaults to “/”)
  • timeout – Seconds to wait for response (defaults to 10)
  • raise_ssl_errors – Pass False if you want to try HTTP even for sites with SSL errors (default True)
Returns:

Tuple of document (str or None), status code (int or None) and error (an exception class instance or None)

Raises:

ValueError – If neither url nor host are given as parameters

federation.utils.network.fetch_host_ip_and_country(host)

Fetch ip and country by host

federation.utils.network.send_document(url, data, timeout=10, *args, **kwargs)

Helper method to send a document via POST.

Additional *args and **kwargs will be passed on to requests.post.

Parameters:
  • url – Full url to send to, including protocol
  • data – Dictionary (will be form-encoded), bytes, or file-like object to send in the body
  • timeout – Seconds to wait for response (defaults to 10)
Returns:

Tuple of status code (int or None) and error (exception class instance or None)

Exceptions

Various custom exception classes might be returned.

exception federation.exceptions.EncryptedMessageError

Encrypted message could not be opened.

exception federation.exceptions.NoSenderKeyFoundError

Sender private key was not available to sign a payload message.

exception federation.exceptions.NoSuitableProtocolFoundError

No suitable protocol found to pass this payload message to.

exception federation.exceptions.SignatureVerificationError

Authenticity of the signature could not be verified given the key.