Using asyncio

1.7 Documentation

«  Differences from SleekXMPP   ::   Contents   ::   Slixmpp Quickstart - Echo Bot  »

Using asyncio

Block on IQ sending

Iq.send() now returns a Future so you can easily block with:

result = yield from iq.send()

Warning

If the reply is an IQ with an error type, this will raise an IqError, and if it timeouts, it will raise an IqTimeout. Don’t forget to catch it.

You can still use callbacks instead.

XEP plugin integration

The same changes from the SleekXMPP API apply, so you can do:

iq_info = yield from self.xmpp['xep_0030'].get_info(jid)

But the following will only return a Future:

iq_info = self.xmpp['xep_0030'].get_info(jid)

Callbacks, Event Handlers, and Stream Handlers

IQ callbacks and Event Handlers can be coroutine functions; in this case, they will be scheduled in the event loop using asyncio.async() and not ran immediately.

A CoroutineCallback class has been added as well for Stream Handlers, which will use asyncio.async() to schedule the callback.

Running the event loop

XMLStream.process() is only a thin wrapper on top of loop.run_forever() (if timeout is provided then it will only run for this amount of time, and if forever is False it will run until disconnection).

Therefore you can handle the event loop in any way you like instead of using process().

Examples

Blocking until the session is established

This code blocks until the XMPP session is fully established, which can be useful to make sure external events aren’t triggering XMPP callbacks while everything is not ready.

import asyncio, slixmpp

client = slixmpp.ClientXMPP('jid@example', 'password')
client.connected_event = asyncio.Event()
callback = lambda _: client.connected_event.set()
client.add_event_handler('session_start', callback)
client.connect()
loop.run_until_complete(event.wait())
# do some other stuff before running the event loop, e.g.
# loop.run_until_complete(httpserver.init())
client.process()

Use with other asyncio-based libraries

This code interfaces with aiohttp to retrieve two pages asynchronously when the session is established, and then send the HTML content inside a simple <message>.

import asyncio, aiohttp, slixmpp

@asyncio.coroutine
def get_pythonorg(event):
    req = yield from aiohttp.request('get', 'http://www.python.org')
    text = yield from req.text
    client.send_message(mto='jid2@example', mbody=text)

@asyncio.coroutine
def get_asyncioorg(event):
    req = yield from aiohttp.request('get', 'http://www.asyncio.org')
    text = yield from req.text
    client.send_message(mto='jid3@example', mbody=text)

client = slixmpp.ClientXMPP('jid@example', 'password')
client.add_event_handler('session_start', get_pythonorg)
client.add_event_handler('session_start', get_asyncioorg)
client.connect()
client.process()

Blocking Iq

This client checks (via XEP-0092) the software used by every entity it receives a message from. After this, it sends a message to a specific JID indicating its findings.

import asyncio, slixmpp

class ExampleClient(slixmpp.ClientXMPP):
    def __init__(self, *args, **kwargs):
        slixmpp.ClientXMPP.__init__(self, *args, **kwargs)
        self.register_plugin('xep_0092')
        self.add_event_handler('message', self.on_message)

    @asyncio.coroutine
    def on_message(self, event):
        # You should probably handle IqError and IqTimeout exceptions here
        # but this is an example.
        version = yield from self['xep_0092'].get_version(message['from'])
        text = "%s sent me a message, he runs %s" % (message['from'],
                                                     version['software_version']['name'])
        self.send_message(mto='master@example.tld', mbody=text)

client = ExampleClient('jid@example', 'password')
client.connect()
client.process()

«  Differences from SleekXMPP   ::   Contents   ::   Slixmpp Quickstart - Echo Bot  »