service — Utilities for implementing AbstractClient services

Protocol extensions or in general support for parts of the XMPP protocol are implemented using Service classes, or rather, classes which use the Meta metaclass.

Both of these are provided in this module.

class aioxmpp.service.Service(client, *, logger_base=None)[source]

A Service is used to implement XMPP or XEP protocol parts, on top of the more or less fixed stanza handling implemented in aioxmpp.node and aioxmpp.stream.

Service is a base class which can be used by extension developers to implement support for custom or standardized protocol extensions. Some of the features for which aioxmpp has support are also implemented using Service subclasses.

client must be a AbstractClient to which the service will be attached. The client cannot be changed later, for the sake of simplicity.

logger_base may be a logging.Logger instance or None. If it is None, a logger is automatically created, by taking the fully qualified name of the Service subclass which is being instanciated. Otherwise, the logger is passed to derive_logger() and the result is used as value for the logger attribute.

To implement your own service, derive from Service. If your service depends on other services (such as aioxmpp.pubsub or aioxmpp.disco), these dependencies must be declared as documented in the service meta class Meta.

To stay forward compatible, accept arbitrary keyword arguments and pass them down to Service. As it is not possible to directly pass arguments to Services on construction (due to the way aioxmpp.node.AbstractClient.summon() works), there is no need for you to introduce custom arguments, and thus there should be no conflicts.

client[source]

The client to which the Service is bound. This attribute is read-only.

If the service has been shut down using shutdown(), this reads as None.

derive_logger(logger)[source]

Return a child of logger specific for this instance. This is called after _client has been set, from the constructor.

The child name is calculated by the default implementation in a way specific for aioxmpp services; it is not meant to be used by non-aioxmpp classes; do not rely on the way how the child name is calculated.

coroutine shutdown()[source]

Close the service and wait for it to completely shut down.

Some services which are still running may depend on this service. In that case, the service may refuse to shut down instead of shutting down, by raising a RuntimeError exception.

Note

Developers creating subclasses of Service to implement services should not override this method. Instead, they should override the _shutdown() method.

class aioxmpp.service.Meta([inherit_dependencies=True])[source]

The metaclass for services. The Service class uses it and in general you should just inherit from Service and define the dependency attributes as needed.

Services have dependencies. A Meta instance (i.e. a service class) can declare dependencies using the following two attributes.

ORDER_BEFORE

An iterable of Service classes before which the class which is currently being declared needs to be instanciated.

Thus, any service which occurs in ORDER_BEFORE will be instanciated after this class (if at all).

New in version 0.3.

SERVICE_BEFORE

Before 0.3, this was the name of the ORDER_BEFORE attribute. It is still supported, but use emits a DeprecationWarning. It must not be mixed with ORDER_BEFORE or ORDER_AFTER on a class declaration, or the declaration will raise ValueError.

Deprecated since version 0.3: Support for this attribute will be removed in 1.0; starting with 1.0, using this attribute will raise a TypeError on class declaration and a AttributeError when accessing it on a class or instance.

ORDER_AFTER

An iterable of Service classes which would be instanciated after the class which is currently being declared, if at all.

Classes which are declared in this attribute are not forced to be instanciated (unlike with ORDER_BEFORE). However, if any of these classes is requested, it is made sure that this class is instanciated before.

New in version 0.3.

SERVICE_AFTER

Before 0.3, this was the name of the ORDER_AFTER attribute. It is still supported, but use emits a DeprecationWarning. It must not be mixed with ORDER_BEFORE or ORDER_AFTER on a class declaration, or the declaration will raise ValueError.

Deprecated since version 0.3: See SERVICE_BEFORE for details on the deprecation cycle.

The dependencies are inherited from bases unless the inherit_dependencies keyword argument is set to false.

After a class has been instanciated, the full set of dependencies is provided in the attributes, including all transitive relationships. These attributes are updated when new classes are declared.

Dependency relationships must not have cycles; a cycle results in a ValueError when the class causing the cycle is declared.

Example:

class Foo(metaclass=service.Meta):
    pass

class Bar(metaclass=service.Meta):
    ORDER_BEFORE = [Foo]

class Baz(metaclass=service.Meta):
    ORDER_BEFORE = [Bar]

class Fourth(metaclass=service.Meta):
    ORDER_BEFORE = [Bar]

Baz and Fourth will be instanciated before Bar and Bar will be instanciated before Foo. There is no dependency relationship between Baz and Fourth.

Inheritance works too:

class Foo(metaclass=service.Meta):
    pass

class Bar(metaclass=service.Meta):
    ORDER_BEFORE = [Foo]

class Baz(Bar):
    # has ORDER_BEFORE == {Foo}
    pass

class Fourth(Bar, inherit_dependencies=False):
    # has empty ORDER_BEFORE
    pass