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.

class federation.entities.base.Comment(*args, **kwargs)[source]

Represents a comment, linked to another object.

class federation.entities.base.Image(*args, **kwargs)[source]

Reflects a single image, possibly linked to another object.

class federation.entities.base.Post(*args, **kwargs)[source]

Reflects a post, status message, etc, which will be composed from the message or to the message.

class federation.entities.base.Profile(*args, **kwargs)[source]

Represents a profile for a user.

class federation.entities.base.Reaction(*args, **kwargs)[source]

Represents a reaction to another object, for example a like.

class federation.entities.base.Relationship(*args, **kwargs)[source]

Represents a relationship between two handles.

class federation.entities.base.Retraction(*args, **kwargs)[source]

Represents a retraction of content by author.

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.

federation.entities.diaspora.mappers.get_outbound_entity(entity, private_key)[source]

Get the correct outbound entity for this protocol.

We might have to look at entity values to decide the correct outbound entity. If we cannot find one, we should raise as conversion cannot be guaranteed to the given protocol.

Private key of author is needed to be passed for signing the outbound entity.

Parameters:entity – An entity instance which can be of a base or protocol entity class.
Returns:Protocol specific entity class instance.
Raises:ValueError – If conversion cannot be done.


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. Since each web framework will have it’s own way of constructing views, one will still have to provide the view code to call the generators.

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.


Helper methods

federation.hostmeta.generators.generate_host_meta(template=None, *args, **kwargs)[source]

Generate a host-meta XRD document.

Template specific key-value pairs need to be passed as kwargs, see classes.

Parameters:template – Ready template to fill with args, for example “diaspora” (optional)
Returns:Rendered XRD document (str)
federation.hostmeta.generators.generate_legacy_webfinger(template=None, *args, **kwargs)[source]

Generate a legacy webfinger XRD document.

Template specific key-value pairs need to be passed as kwargs, see classes.

Parameters:template – Ready template to fill with args, for example “diaspora” (optional)
Returns:Rendered XRD document (str)
federation.hostmeta.generators.generate_hcard(template=None, **kwargs)[source]

Generate a hCard document.

Template specific key-value pairs need to be passed as kwargs, see classes.

Parameters:template – Ready template to fill with args, for example “diaspora” (optional)
Returns:HTML document (str)
federation.hostmeta.generators.get_nodeinfo_well_known_document(url, document_path=None)[source]

Generate a NodeInfo .well-known document.

See spec:

  • url – The full base url with protocol, ie
  • document_path – Custom NodeInfo document path if supplied (optional)


Generator classes

class federation.hostmeta.generators.DiasporaHostMeta(*args, **kwargs)[source]

Diaspora host-meta.

Required keyword args:

  • webfinger_host (str)
class federation.hostmeta.generators.DiasporaWebFinger(handle, host, guid, public_key, *args, **kwargs)[source]

Diaspora version of legacy WebFinger.

Required keyword args:

class federation.hostmeta.generators.DiasporaHCard(**kwargs)[source]

Diaspora hCard document.

Must receive the required attributes as keyword arguments to init.

class federation.hostmeta.generators.NodeInfo(software, protocols, services, open_registrations, usage, metadata, skip_validate=False, raise_on_validate=False)[source]

Generate a NodeInfo document.

See spec:

NodeInfo is unnecessarely restrictive in field values. We wont be supporting such strictness, though we will raise a warning unless validation is skipped with skip_validate=True.

For strictness, raise_on_validate=True will cause a ValidationError to be raised.

See schema document federation/hostmeta/schemas/nodeinfo-1.0.json for how to instantiate this class.

class federation.hostmeta.generators.SocialRelayWellKnown(subscribe, tags=(), scope='all', *args, **kwargs)[source]

A .well-known/social-relay document in JSON.

For apps wanting to announce their preferences towards relay applications.

See WIP spec:

Schema see schemas/social-relay-well-known.json

  • subscribe – bool
  • tags – tuple, optional
  • scope – Should be either “all” or “tags”, default is “all” if not given


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


High level retrieve profile method.

Retrieve the profile from a remote location, using either the given protocol or by checking each protocol until a user can be constructed from the remote documents.

Currently, due to no other protocols supported, always use the Diaspora protocol.

Parameters:handle – The profile handle in format username@domain.tld
Returns:federation.entities.base.Profile or None


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

federation.inbound.handle_receive(payload, user=None, sender_key_fetcher=None, skip_author_verification=False)[source]

Takes a payload and passes it to the correct protocol.

Returns a tuple of:
  • sender handle
  • protocol name
  • list of entities

NOTE! The returned sender is NOT necessarily the author of the entity. By sender here we’re talking about the sender of the payload. If this object is being relayed by the sender, the author could actually be a different identity.

  • payload – Payload blob (str)
  • user – User that will be passed to protocol.receive (only required on private encrypted content) MUST have a private_key and guid if given.
  • sender_key_fetcher – Function that accepts sender handle and returns public key (optional)
  • skip_author_verification – Don’t verify sender (test purposes, false default)

Tuple of sender handle, protocol name and list of entity objects


NoSuitableProtocolFound – When no protocol was identified to pass message to


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

federation.outbound.handle_create_payload(entity, from_user, to_user=None)[source]

Create a payload with the correct protocol.

Since we don’t know the protocol, we need to first query the recipient. However, for a PoC implementation, supporting only Diaspora, we’re going to assume that for now.

from_user must have private_key and handle attributes. to_user must have key attribute.

  • entity – Entity object to send
  • from_user – Profile sending the object
  • to_user – Profile entry to send to (required for non-public content)

Built payload message (str)

federation.outbound.handle_send(entity, from_user, recipients=None)[source]

Send an entity to remote servers.

from_user must have private_key and handle attributes.

recipients should be a list of tuples, containing:
  • recipient handle, domain or id
  • protocol (optional, if known)

Using this we will build a list of payloads per protocol, after resolving any that need to be guessed or looked up over the network. After that, each recipient will get the generated protocol payload delivered.

NOTE! This will not support Diaspora limited messages - handle_create_payload above should be directly called instead and payload sent with


The code for opening and creating protocol messages lives under each protocol module in federation.protocols. Currently Diaspora protocol is the only protocol supported.

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.


Various utils are provided for internal and external usage.


federation.utils.diaspora.parse_profile_from_hcard(hcard, handle)[source]

Parse all the fields we can from a hCard document to get a Profile.


federation.entities.Profile instance


Retrieve the remote user and return a Profile object.

Parameters:handle – User handle in username@domain.tld format
Returns:federation.entities.Profile instance or None

Retrieve a remote Diaspora hCard document.

Parameters:handle – Remote handle to retrieve
Returns:str (HTML document)

Retrieve a remote Diaspora webfinger document.

Parameters:handle – Remote handle to retrieve
Returns:XRD instance

Retrieve a remote Diaspora host-meta document.

Parameters:host – Host to retrieve from
Returns:XRD instance

Network, host=None, path='/', timeout=10, raise_ssl_errors=True)[source]

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.

  • 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)

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


ValueError – If neither url nor host are given as parameters, data, timeout=10, *args, **kwargs)[source]

Helper method to send a document via POST.

Additional *args and **kwargs will be passed on to

  • url – Full url to send to, including protocol
  • data – POST data to send (dict)
  • timeout – Seconds to wait for response (defaults to 10)

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


Various custom exception classes might be returned.

exception federation.exceptions.EncryptedMessageError[source]

Encrypted message could not be opened.

exception federation.exceptions.NoSenderKeyFoundError[source]

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

exception federation.exceptions.NoSuitableProtocolFoundError[source]

No suitable protocol found to pass this payload message to.

exception federation.exceptions.SignatureVerificationError[source]

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