roster — RFC 6121 roster implementation

This subpackage provides a aioxmpp.service.Service to interact with RFC 6121 rosters.

class aioxmpp.roster.Service(client)

A roster client aioxmpp.service.Service.

client must be a AbstractClient or subclass. Ideally, you create Service instances using AbstractClient.summon().

The interaction with a roster service happens mainly by accessing the attributes holding the state and using the events to be notified of state changes:

Attributes for accessing the roster:

items

A dictionary mapping JID instances to corresponding Item instances.

groups

A dictionary which allows group-based access to Item instances. The dictionaries keys are the names of the groups, the values are set instances, which hold the Item instances in that group.

At no point one can observe empty set instances in this dictionary.

The Item instances stay the same, as long as they represent the identical roster entry on the remote side. That is, if the name or subscription state are changed in the server side roster, the Item instance stays the same, but the attributes are mutated. However, if the entry is removed from the server roster and re-added later for the same JID, it will be a different Item instance.

Signals:

signal on_initial_roster_received()

Fires when the initial roster has been received. Note that if roster versioning is used, the initial roster may not be up-to-date. The server is allowed to tell the client to re-use its local state and deliver changes using roster pushes. In that case, the on_initial_roster_received() event fires immediately, so that the user sees whatever roster has been set up for versioning before the stream was established; updates pushed by the server are delivered using the normal events.

The roster data has already been imported at the time the callback is fired.

Note that the initial roster is diffed against whatever is in the local store and events are fired just like for normal push updates. Thus, in general, you won’t need this signal; it might be better to listen for the events below.

signal on_entry_added(item)

Fires when an item has been added to the roster. The attributes of the item are up-to-date when this callback fires.

signal on_entry_name_changed(item)

Fires when a roster update changed the name of the item. The new name is already applied to the item.

signal on_entry_subscription_state_changed(item)

Fires when a roster update changes any of the Item.subscription, Item.ask or Item.approved attributes. The new values are already applied to item.

The event always fires once per update, even if the update changes more than one of the above attributes.

signal on_entry_added_to_group(item, group_name)

Fires when an update adds an item to a group. The Item.groups attribute is already updated (not only with this, but also other group updates, including removals) when this event is fired.

The event fires for each added group in an update, thus it may fire more than once per update.

The name of the new group is in group_name.

signal on_entry_removed_from_group(item, group_name)

Fires when an update removes an item from a group. The Item.groups attribute is already updated (not only with this, but also other group updates, including additions) when this event is fired.

The event fires for each removed group in an update, thus it may fire more than once per update.

The name of the new group is in group_name.

signal on_entry_removed(item)

Fires after an entry has been removed from the roster. The entry is already removed from all bookkeeping structures, but the values on the item object are the same as right before the removal.

Modifying roster contents:

coroutine set_entry(jid, *, name=<object object at 0x7fd4bc86f610>, add_to_groups=frozenset(), remove_from_groups=frozenset(), timeout=None)

Set properties of a roster entry or add a new roster entry. The roster entry is identified by its bare jid.

If an entry already exists, all values default to those stored in the existing entry. For example, if no name is given, the current name of the entry is re-used, if any.

If the entry does not exist, it will be created on the server side.

The remove_from_groups and add_to_groups arguments have to be based on the locally cached state, as XMPP does not support sending diffs. remove_from_groups takes precedence over add_to_groups.

timeout is the time in seconds to wait for a confirmation by the server.

Note that the changes may not be visible immediately after his coroutine returns in the items and groups attributes. The Service waits for the “official” roster push from the server for updating the data structures and firing events, to ensure that consistent state with other clients is achieved.

This may raise arbitrary errors.XMPPError exceptions if the server replies with an error and also any kind of connection error if the connection gets fatally terminated while waiting for a response.

coroutine remove_entry(jid, *, timeout=None)

Request removal of the roster entry identified by the given bare jid. If the entry currently has any subscription state, the server will send the corresponding unsubscribing presence stanzas.

timeout is the maximum time in seconds to wait for a reply from the server.

This may raise arbitrary errors.XMPPError exceptions if the server replies with an error and also any kind of connection error if the connection gets fatally terminated while waiting for a response.

Managing presence subscriptions:

approve(peer_jid)

(Pre-)approve a subscription request from peer_jid.

This sends a "subscribed" presence to the peer; if the peer has previously asked for a subscription, this will seal the deal and create the subscription.

If the peer has not requested a subscription (yet), it is marked as pre-approved by the server. A future subscription request by the peer will then be confirmed by the server automatically.

subscribe(peer_jid)

Request presence subscription with the given peer_jid.

This is deliberately not a coroutine; we don’t know whether the peer is online (usually) and they may defer the confirmation very long, if they confirm at all. Use on_subscribed() to get notified when a peer accepted a subscription request.

signal on_subscribe(stanza)

Fires when a peer requested a subscription. The whole stanza recevied is included as stanza.

See also

To approve a subscription request, use approve().

signal on_subscribed(stanza)

Fires when a peer has confirmed a previous subscription request. The "subscribed" stanza is included as stanza.

signal on_unsubscribe(stanza)

Fires when a peer cancelled their subscription for our presence. As per RFC 6121, the server forwards the "unsubscribe" presence stanza (which is included as stanza argument) before sending the roster push.

Unless your application is interested in the specific cause of a subscription state change, it is not neccessary to use this signal; the subscription state change will be covered by on_entry_subscription_state_changed().

signal on_unsubscribed(stanza)

Fires when a peer cancelled our subscription. As per RFC 6121, the server forwards the "unsubscribed" presence stanza (which is included as stanza argument) before sending the roster push.

Unless your application is interested in the specific cause of a subscription state change, it is not neccessary to use this signal; the subscription state change will be covered by on_entry_subscription_state_changed().

Import/Export of roster data:

export_as_json()

Export the whole roster as currently stored on the client side into a JSON-compatible dictionary and return that dictionary.

import_from_json(data)

Replace the current roster with the export_as_json()-compatible dictionary in data.

No events are fired during this activity. After this method completes, the whole roster contents are exchanged with the contents from data.

Also, no data is transferred to the server; this method is intended to be used for roster versioning. See below (in the docs of Service).

To make use of roster versioning, use the above two methods. The general workflow is to export_as_json() the roster after disconnecting and storing it for the next connection attempt. Before connecting, the stored data needs to be loaded using import_from_json(). This only needs to happen after a new Service has been created, as roster services won’t delete roster contents between two connections on the same node.AbstractClient instance.

class aioxmpp.roster.Item(jid, *, approved=False, ask=None, subscription='none', name=None, groups=())

Represent an entry in the roster. These entries are mutable, see the documentation of Service for details on the lifetime of Item instances within a Service instance.

jid

The JID of the entry. This is always a bare JID.

name

The display name of the entry, if any.

groups

A set of names of groups in which the roster entry is.

subscription

The subscription status of the entry. One of "none", "to", "from" and "both" (in contrast to xso.Item, "remove" cannot occur here).

ask

The ask attribute of the roster entry.

approved

The approved attribute of the roster entry.

The data of a roster entry can conveniently be exported to JSON:

export_as_json()

Return a json-compatible dictionary which contains the attributes of this Item except its JID.

To mutate the roster entry, some handy methods are provided:

update_from_json(data)

Update the attributes of this Item using the values obtained from the dictionary data.

The format of data should be the same as the format returned by export_as_json().

update_from_xso_item(xso_item)

Update the attributes (except jid) with the values obtained from the gixen xso_item.

xso_item must be a valid xso.Item instance.

To create a roster entry from a xso.Item, use the from_xso_item() class method.

classmethod from_xso_item(xso_item)

Create a Item with the jid set to the xso.Item.jid obtained from xso_item. Then update that instance with xso_item using update_from_xso_item() and return it.

Note

Do not confuse this with the XSO xso.Item.

roster.xso — IQ payloads and stream feature

The submodule aioxmpp.roster.xso contains the XSO classes which describe the IQ payloads used by this subpackage.

class aioxmpp.roster.xso.Query(*, ver=None, items=())[source]

A query which fetches data from the roster or sends new items to the roster.

ver

The version of the roster, if any. See the RFC for the detailed semantics.

items

The items in the roster query.

class aioxmpp.roster.xso.Item(jid, *, name=None, groups=(), subscription='none', approved=False, ask=None)[source]

A contact item in a roster.

jid

The bare JID of the contact.

name

The optional display name of the contact.

groups

A XSOList of Group instances which describe the roster groups in which the contact is.

The following attributes represent the subscription status of the contact. A client must not set these attributes when sending roster items to the server. To change subscription status, use presence stanzas of the respective type. The only exception is a subscription value of "remove", which is used to remove an entry from the roster.

subscription

Primary subscription status, one of "none" (the default), "to", "from" and "both".

In addition, subscription can be set to "remove" to remove an item from the roster during a roster set. Removing an entry from the roster will also cancel any presence subscriptions from and to that entries entity.

approved

Whether the subscription has been pre-approved by the owning entity.

ask

Subscription sub-states, one of "subscribe" and None.

Note

Do not confuse this class with Item.

class aioxmpp.roster.xso.Group(*, name=None)[source]

A group declaration for a contact in a roster.

name

The name of the group.

The stream feature which is used by servers to announce support for roster versioning:

class aioxmpp.roster.xso.RosterVersioningFeature[source]

Roster versioning feature.