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

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.

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.

For rules with respect to inheriting from Service see the documentation of the used metaclass, Meta.

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.

Support for this attribute will be removed in 1.x; 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.

Deprecated since version 0.3.

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.

See SERVICE_BEFORE for details on the deprecation cycle.

Deprecated since version 0.3.

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