# `roster` — RFC 6121 roster implementation

This subpackage provides `RosterClient`, a service to interact with RFC 6121 rosters.

class aioxmpp.RosterClient(client, **kwargs)

  A roster client `aioxmpp.service.Service`.

  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.

    When the event fires, the bookkeeping structures are already updated. This implies that `on_group_added()` is called before `on_entry_added()` if the entry adds a new group.

  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.

    At the time the event fires, the bookkeeping structures for the group are already updated; this implies that `on_group_added()` fires before `on_entry_added_to_group()` if the entry added a new group.

  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.

    At the time the event fires, the bookkeeping structures are already updated; this implies that `on_group_removed()` fires before `on_entry_removed_from_group()` if the removal of an entry from a group causes the group to vanish.

  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.

    This implies that `on_group_removed()` fires before `on_entry_removed()` if the removal of an entry causes a group to vanish.

  signal on_group_added(group)

    Fires after a new group has been added to the bookkeeping structures.

    Parameters:

      group (`str`) – Name of the new group.

    At the time the event fires, the group is empty.

    New in version 0.9.

  signal on_group_removed(group)

    Fires after a new group has been removed from the bookkeeping structures.

    Parameters:

      group (`str`) – Name of the old group.

    At the time the event fires, the group is empty.

    New in version 0.9.

  Modifying roster contents:

  async set_entry(jid, *, name=<object object>, 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.

  async 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.

    Parameters:

      peer_jid – The peer to (pre-)approve.

    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.

    Note

    Pre-approval is an OPTIONAL feature in RFC 6121. It is announced as a stream feature.

  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 received 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 necessary 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 necessary 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 `Client` instance.

  Changed in version 0.8: This class was formerly known as `aioxmpp.roster.Service`. It is still available under that name, but the alias will be removed in 1.0.

class aioxmpp.roster.Service

  Alias of `RosterClient`.

  Deprecated since version 0.8: The alias will be removed in 1.0.

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(*args, **kwargs)

  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(*args, **kwargs)

  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(*args, **kwargs)

  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

  Roster versioning feature.

  See also

  `aioxmpp.nonza.StreamFeatures`