### Install aioxmpp via pip
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/installation.md
Installs the aioxmpp library and its dependencies from PyPI using pip3. This is the recommended method for general use.
```bash
pip3 install aioxmpp
```
--------------------------------
### Anonymous provisioner configuration
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/dev-guide/index.md
Example configuration for using the AnonymousProvisioner with the e2etest framework.
```ini
[global]
provisioner=aioxmpp.e2etest.provision.AnonymousProvisioner
[aioxmpp.e2etest.provision.AnonymousProvisioner]
domain=localhost
pin_store=pinstore.json
pin_type=0
```
--------------------------------
### Example XML for Book Library
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/an-introduction-to-xso.md
An example XML file conforming to the book library structure defined by the XSO classes. It includes multiple books with localized titles and chapters.
```xml
The Amazing Life of Foo
Das Faszinierende Leben des Foo
F. Nord
2099-01-01
23
The Birth of Foo
Die Geburt des Foo
The Death of Foo
Der Tod des Foo
The Relevance of Pink Flamingos to Computer Science
Die Relevanz von rosa Flamingos für die Informatik
O. L. Bilderrahmen
2007-01-01
42
```
--------------------------------
### Install aioxmpp in editable mode
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/installation.md
Installs aioxmpp in editable mode from a local source repository. This is recommended for developers who want to modify the library's code. Ensure dependencies are installed first.
```bash
git clone https://github.com/horazont/aioxmpp
cd aioxmpp
git checkout devel # make sure to use the devel branch
pip3 install -e .
```
--------------------------------
### Install Dependencies on Debian 8 (Jessie) via apt
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/installation.md
Installs essential build and Python dependencies for aioxmpp on Debian 8 using apt. Includes packages like python3-dnspython, python3-openssl, and build-essential.
```bash
apt install --no-install-recommends python3-dnspython python3-openssl \
python3-pyasn1 python3-pyasn1-modules build-essential libxml2-dev \
libxslt1-dev python3-dev libz-dev python3-pip
```
--------------------------------
### Install Dependencies on Debian 9 (Stretch) via apt
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/installation.md
Installs essential build and Python dependencies for aioxmpp on Debian 9 using apt. Includes packages like python3-dnspython, python3-openssl, and python3-multidict.
```bash
apt install --no-install-recommends python3-dnspython python3-openssl \
python3-pyasn1 python3-pyasn1-modules python3-multidict \
python3-tzlocal python3-lxml python3-babel python3-pip
```
--------------------------------
### PubSub Node Configuration Methods
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/api/changelog.md
Methods for managing PubSub node configuration, including getting and setting node configurations.
```python
aioxmpp.PubSubClient.get_node_config()
aioxmpp.PubSubClient.set_node_config()
```
--------------------------------
### Install Build Dependencies on Debian 8/9 via apt
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/installation.md
Installs C build dependencies required for some Python packages like lxml and PyOpenSSL on Debian 8 and 9. This command should be run before installing other dependencies via pip.
```bash
apt install --no-install-recommends build-essential libssl-dev \
libxml2-dev libxslt1-dev python3-dev python3-openssl libz-dev \
python3-pip
```
--------------------------------
### Manage Roster with RosterClient
Source: https://context7.com/jssfr/aioxmpp/llms.txt
Utilize RosterClient to access and manage the contact list. This example demonstrates waiting for the initial roster, iterating through contacts and groups, adding new entries, requesting subscriptions, approving requests, and removing contacts. Ensure aioxmpp and asyncio are imported.
```python
import asyncio
import aioxmpp
async def roster_example(client):
# Summon the roster service
roster = client.summon(aioxmpp.RosterClient)
# Wait for initial roster to be received
initial_roster_received = asyncio.Event()
def on_initial_roster():
initial_roster_received.set()
roster.on_initial_roster_received.connect(on_initial_roster)
async with client.connected():
await initial_roster_received.wait()
# Access all roster items
for jid, item in roster.items.items():
print(f"Contact: {jid}")
print(f" Name: {item.name}")
print(f" Subscription: {item.subscription}")
print(f" Groups: {item.groups}")
# Access by group
for group_name, items in roster.groups.items():
print(f"Group '{group_name}':")
for item in items:
print(f" - {item.jid} ({item.name})")
# Add a new contact
await roster.set_entry(
aioxmpp.JID.fromstr("newcontact@example.org"),
name="New Contact",
groups=["Friends", "Work"]
)
# Request subscription
await roster.subscribe(aioxmpp.JID.fromstr("newcontact@example.org"))
# Approve subscription request
await roster.approve(aioxmpp.JID.fromstr("requester@example.org"))
# Remove contact
await roster.remove_entry(aioxmpp.JID.fromstr("oldcontact@example.org"))
# Event handlers for roster changes:
# roster.on_entry_added(item)
# roster.on_entry_name_changed(item)
# roster.on_entry_subscription_changed(item)
# roster.on_entry_removed(item)
```
--------------------------------
### Traceback for DNS NXDOMAIN error
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/pitfalls.md
Example of the traceback encountered when attempting to connect to a bare IP address.
```default
Traceback (most recent call last):
File "/home/horazont/aioxmpp/aioxmpp/network.py", line 272, in repeated_query
raise_on_no_answer=False
File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
yield self # This tells Task to wait for completion.
File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
value = future.result()
File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
raise self._exception
File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
result = self.fn(*self.args, **self.kwargs)
File "/home/horazont/.local/lib/python3.4/site-packages/dns/resolver.py", line 1051, in query
raise NXDOMAIN(qnames=qnames_to_try, responses=nxdomain_responses)
dns.resolver.NXDOMAIN: None of DNS query names exist: _xmpp-client._tcp.192.168.122.1., _xmpp-client._tcp.192.168.122.1.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/horazont/aioxmpp/aioxmpp/node.py", line 710, in _on_main_done
task.result()
File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
raise self._exception
File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
result = coro.throw(exc)
File "/home/horazont/aioxmpp/aioxmpp/node.py", line 868, in _main
yield from self._main_impl()
File "/home/horazont/aioxmpp/aioxmpp/node.py", line 830, in _main_impl
logger=self.logger)
File "/home/horazont/aioxmpp/aioxmpp/node.py", line 337, in connect_xmlstream
logger=logger,
File "/home/horazont/aioxmpp/aioxmpp/node.py", line 142, in discover_connectors
"xmpp-client",
File "/home/horazont/aioxmpp/aioxmpp/network.py", line 318, in lookup_srv
**kwargs)
File "/home/horazont/aioxmpp/aioxmpp/network.py", line 280, in repeated_query
"nameserver error, most likely DNSSEC validation failed",
aioxmpp.network.ValidationError: nameserver error, most likely DNSSEC validation failed
```
--------------------------------
### Implement an echo bot callback
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/quickstart.md
An example of a message callback that echoes the body of received messages back to the sender.
```python
def message_received(msg):
if not msg.body:
# do not reflect anything without a body
return
reply = msg.make_reply()
reply.body.update(msg.body)
client.enqueue(reply)
```
--------------------------------
### Receive and Echo Messages with SimpleMessageDispatcher
Source: https://context7.com/jssfr/aioxmpp/llms.txt
Register callbacks for incoming CHAT and NORMAL messages using SimpleMessageDispatcher. This example sets up an echo bot that prints received messages and sends them back to the sender. Ensure aioxmpp and asyncio are imported.
```python
import asyncio
import aioxmpp
import aioxmpp.dispatcher
async def echo_bot(jid, password):
client = aioxmpp.PresenceManagedClient(
jid,
aioxmpp.make_security_layer(password)
)
def on_chat_message(msg):
if not msg.body:
return # Ignore empty messages
print(f"Received from {msg.from_}: {msg.body.any()}")
# Echo back
reply = aioxmpp.Message(
type_=msg.type_,
to=msg.from_
)
reply.body.update(msg.body)
client.enqueue(reply)
# Summon the message dispatcher service
dispatcher = client.summon(aioxmpp.dispatcher.SimpleMessageDispatcher)
# Register callback for CHAT messages from any sender (None = any)
dispatcher.register_callback(
aioxmpp.MessageType.CHAT,
None, # from_jid filter (None accepts all)
on_chat_message
)
# Also handle normal messages
dispatcher.register_callback(
aioxmpp.MessageType.NORMAL,
None,
on_chat_message
)
async with client.connected():
print("Echo bot running... Press Ctrl+C to stop")
while True:
await asyncio.sleep(1)
# Run: asyncio.run(echo_bot(aioxmpp.JID.fromstr("bot@example.org"), "password"))
```
--------------------------------
### Register Handler for Software Version IQ
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/quickstart.md
This snippet shows how to register an asynchronous handler for incoming IQ requests of type 'GET' that carry a `Query` payload. The handler constructs and returns a `Query` object with software details. Ensure the client is connected before registering handlers.
```python
from aioxmpp.version.xso import Query
async def handler(iq):
print("software version request from {!r}".format(iq.from_))
result = Query()
result.name = "aioxmpp Quick Start Pro"
result.version = "23.42"
result.os = "MFHBμKOS (My Fancy HomeBrew Micro Kernel Operating System)"
return result
client.stream.register_iq_request_handler(
aioxmpp.IQType.GET,
Query,
handler,
)
async with client.connected():
await asyncio.sleep(30)
```
--------------------------------
### Define Book Library XSO Structures
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/an-introduction-to-xso.md
Define Python classes that map to XML elements for a book library. This includes nested structures like chapters within a book, and attributes like chapter start page.
```python
import aioxmpp.xso
namespace = "urn:uuid:39ba7586-fb65-4ec8-80ce-f3a9f2890490"
class Chapter(aioxmpp.xso.XSO):
TAG = namespace, "chapter"
title = aioxmpp.xso.ChildTextMap((namespace, "title"))
start_page = aioxmpp.xso.Attr(
"start-page",
type_=aioxmpp.xso.Integer()
)
class TableOfContents(aioxmpp.xso.XSO):
TAG = namespace, "toc"
chapters = aioxmpp.xso.ChildList([Chapter])
class Book(aioxmpp.xso.XSO):
TAG = namespace, "book"
id_ = aioxmpp.xso.Attr("id")
author = aioxmpp.xso.ChildText((namespace, "author"))
npages = aioxmpp.xso.ChildText(
(namespace, "pages"),
type_=aioxmpp.xso.Integer(),
)
published = aioxmpp.xso.ChildText(
(namespace, "published"),
type_=aioxmpp.xso.Date(),
)
title = aioxmpp.xso.ChildTextMap((namespace, "title"))
toc = aioxmpp.xso.Child([TableOfContents])
class Library(aioxmpp.xso.XSO):
TAG = namespace, "library"
books = aioxmpp.xso.ChildList([Book])
```
--------------------------------
### Build documentation
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/README.md
Generates the HTML documentation files in the local build directory.
```makefile
make docs-html
```
--------------------------------
### Build and view documentation
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/README.md
Generates the HTML documentation and automatically opens it in the default web browser.
```makefile
make docs-view-html
```
--------------------------------
### Initialize and Connect XMPP Client
Source: https://context7.com/jssfr/aioxmpp/llms.txt
Demonstrates different ways to initialize and connect an aioxmpp client, including basic client, PresenceManagedClient, and context manager usage. Ensure you have a valid JID and security layer (password or other authentication).
```python
import asyncio
import aioxmpp
async def connect_example():
# Create a JID from string
jid = aioxmpp.JID.fromstr("user@example.org")
# Create security layer with password
security = aioxmpp.make_security_layer("your_password")
# Option 1: Basic client (manual start/stop)
client = aioxmpp.Client(jid, security)
client.start()
await client.established_event.wait()
print(f"Connected as: {client.local_jid}")
client.stop()
# Option 2: PresenceManagedClient (auto-connects when presence is available)
pmc = aioxmpp.PresenceManagedClient(jid, security)
pmc.presence = aioxmpp.PresenceState(True) # Sets available, starts connection
# Option 3: Context manager approach
async with pmc.connected() as stream:
print(f"Stream established: {pmc.local_jid}")
await asyncio.sleep(5)
# Automatically disconnects when context exits
asyncio.run(connect_example())
```
--------------------------------
### Use DiscoClient service
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/quickstart.md
Demonstrates summoning and using the DiscoClient service to query entity information.
```python
client = aioxmpp.PresenceManagedClient(
jid,
aioxmpp.make_security_layer(password)
)
disco = client.summon(aioxmpp.DiscoClient)
async with client.connected() as stream:
info = await disco.query_info(
target_jid,
)
```
--------------------------------
### Signal and Callback Patterns
Source: https://context7.com/jssfr/aioxmpp/llms.txt
Demonstrates various ways to connect to signals, including simple callbacks, manual disconnection, context managers, and future-based waiting.
```python
import aioxmpp
import aioxmpp.callbacks
async def signals_example(client):
# Simple function callback
def on_established():
print("Stream established!")
client.on_stream_established.connect(on_established)
# Async callback with disconnect
handle = client.on_stream_established.connect(on_established)
handle.disconnect() # Remove callback
# Context manager for temporary connection
with client.on_stream_established.context_connect(on_established):
# Callback active within this block
pass
# Automatically disconnected
# Future-based waiting
fut = client.on_stream_established.future()
await fut # Waits for signal to fire once
# Using AUTO_FUTURE for signal result
conn_future = asyncio.Future()
client.on_stream_established.connect(
conn_future,
client.on_stream_established.AUTO_FUTURE
)
await conn_future
```
--------------------------------
### Manage Pub/Sub Nodes and Subscriptions
Source: https://context7.com/jssfr/aioxmpp/llms.txt
Utilize PubSubClient to create, configure, subscribe to, publish to, and delete pub/sub nodes. Requires connection to a pub/sub service.
```python
import asyncio
import aioxmpp
import aioxmpp.pubsub
import aioxmpp.pubsub.xso as pubsub_xso
async def pubsub_example(client):
pubsub = client.summon(aioxmpp.PubSubClient)
service_jid = aioxmpp.JID.fromstr("pubsub.example.org")
node_name = "my_node"
async with client.connected():
# Create a node
await pubsub.create(service_jid, node_name)
# Configure node (get current config first)
config = await pubsub.get_node_config(service_jid, node_name)
# Modify config.data as needed, then:
# await pubsub.set_node_config(service_jid, node_name, config.data)
# Subscribe to notifications
def on_item_published(jid, node, item, **kwargs):
print(f"New item on {jid}/{node}: {item.id_}")
if item.registered_payload:
print(f" Payload: {item.registered_payload}")
def on_item_retracted(jid, node, id_, **kwargs):
print(f"Item {id_} retracted from {jid}/{node}")
pubsub.on_item_published.connect(on_item_published)
pubsub.on_item_retracted.connect(on_item_retracted)
# Subscribe to node
subscription = await pubsub.subscribe(service_jid, node=node_name)
subid = subscription.payload.subid
print(f"Subscribed with ID: {subid}")
# Publish an item
from aioxmpp.pubsub.xso import Item
item = Item(id_="item1")
# item.registered_payload = your_custom_xso
await pubsub.publish(service_jid, node_name, item)
# Get items from node
items_result = await pubsub.get_items(service_jid, node=node_name, max_items=10)
for item in items_result.payload.items:
print(f"Item: {item.id_}")
# Retract an item
await pubsub.retract(service_jid, node_name, id_="item1")
# Unsubscribe
await pubsub.unsubscribe(service_jid, node=node_name, subid=subid)
# Delete node
await pubsub.delete(service_jid, node_name)
```
--------------------------------
### Connect to XMPP Server
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/quickstart.md
Establishes a connection using PresenceManagedClient and a security layer.
```python
client = aioxmpp.PresenceManagedClient(
jid,
aioxmpp.make_security_layer(password)
)
async with client.connected() as stream:
...
```
--------------------------------
### Declare Message Dispatcher Dependency in aioxmpp Service
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/api/changelog.md
Classes using aioxmpp.service.message_handler() must declare a message dispatcher in their dependencies. This example shows a backward-compatible way to conditionally declare SimpleMessageDispatcher.
```python
class FooService(aioxmpp.service.Service):
ORDER_AFTER = []
try:
import aioxmpp.dispatcher
except ImportError:
pass
else:
ORDER_AFTER.append(
aioxmpp.dispatcher.SimpleMessageDispatcher
)
```
--------------------------------
### Using aioxmpp.xso.Date and aioxmpp.xso.Time
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/api/changelog.md
Demonstrates the availability of aioxmpp.xso.Date and aioxmpp.xso.Time for XEP-0082 compliance, and aioxmpp.xso.DateTime for legacy formats.
```python
aioxmpp.xso.Date
aioxmpp.xso.Time
aioxmpp.xso.DateTime
```
--------------------------------
### Run aioxmpp unittests
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/installation.md
Executes the unit tests for the aioxmpp library using the nosetests3 runner. Navigate to the source directory before running this command.
```bash
cd path/to/source/of/aioxmpp
nosetests3 tests
```
--------------------------------
### Verify e2etest configuration
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/dev-guide/index.md
Run a specific test case to validate that the e2etest configuration is correctly set up.
```console
$ python3 -m aioxmpp.e2etest tests/test_e2e.py:TestConnect
```
--------------------------------
### Upgrade pip on Debian Jessie
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/installation.md
Upgrades setuptools and pip to their latest versions on Debian Jessie. This is necessary because the default pip version on Jessie does not support the '~=' version comparison operator required by aioxmpp.
```bash
pip3 install --upgrade setuptools
```
```bash
pip3 install --upgrade pip
```
--------------------------------
### Maintain compatibility for Disco service split
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/api/changelog.md
Use this pattern to handle the transition from a single Service class to separate DiscoClient and DiscoServer classes.
```python
try:
from aioxmpp import DiscoClient, DiscoServer
except ImportError:
import aioxmpp.disco
DiscoClient = aioxmpp.disco.Service
DiscoServer = aioxmpp.disco.Service
```
--------------------------------
### Run unit tests with Nose
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/dev-guide/index.md
Execute the standard test suite using the nosetests3 runner from the repository root.
```console
$ nosetests3 tests
```
--------------------------------
### Manage Peer Presence with PresenceClient
Source: https://context7.com/jssfr/aioxmpp/llms.txt
Use PresenceClient to track peer presence and PresenceServer to manage outgoing presence broadcasts. Set presence state with available and show values, and connect event handlers for presence changes.
```python
import asyncio
import aioxmpp
async def presence_example(client):
# Track peer presence
presence_client = client.summon(aioxmpp.PresenceClient)
# Manage own presence
presence_server = client.summon(aioxmpp.PresenceServer)
# Set presence state with show value
presence_server.set_presence(
aioxmpp.PresenceState(available=True, show=aioxmpp.PresenceShow.CHAT),
status="Ready to chat!"
)
# Available show values:
# PresenceShow.NONE (default available)
# PresenceShow.AWAY
# PresenceShow.XA (extended away)
# PresenceShow.DND (do not disturb)
# PresenceShow.CHAT (free for chat)
# Presence event handlers
def on_peer_available(full_jid, stanza):
state = aioxmpp.PresenceState.from_stanza(stanza)
print(f"{full_jid} is now available: {state.show}")
def on_peer_unavailable(full_jid, stanza):
print(f"{full_jid} went offline")
def on_peer_changed(full_jid, stanza):
print(f"{full_jid} presence changed")
presence_client.on_available.connect(on_peer_available)
presence_client.on_unavailable.connect(on_peer_unavailable)
presence_client.on_changed.connect(on_peer_changed)
async with client.connected():
# Query presence for a specific JID
peer = aioxmpp.JID.fromstr("friend@example.org")
# Get all available resources for a bare JID
resources = presence_client.get_peer_resources(peer)
for resource, stanza in resources.items():
print(f"Resource {resource}: {stanza.show}")
# Get most available resource
best = presence_client.get_most_available_stanza(peer)
if best:
print(f"Most available: {best.from_}")
await asyncio.sleep(300)
```
--------------------------------
### Query Entity Capabilities with DiscoClient
Source: https://context7.com/jssfr/aioxmpp/llms.txt
Use DiscoClient to query an entity's capabilities and features. Requires an active client connection.
```python
import asyncio
import aioxmpp
import aioxmpp.disco
async def disco_example(client):
disco = client.summon(aioxmpp.DiscoClient)
disco_server = client.summon(aioxmpp.DiscoServer)
async with client.connected():
target = aioxmpp.JID.fromstr("example.org")
# Query server info
info = await disco.query_info(target)
print(f"Identities for {target}:")
for identity in info.identities:
print(f" {identity.category}/{identity.type_}: {identity.name}")
print(f"Features:")
for feature in info.features:
print(f" {feature}")
# Query items (e.g., chat rooms, services)
items = await disco.query_items(target)
for item in items.items:
print(f"Item: {item.jid} - {item.name} (node: {item.node})")
# Query a specific node
node_info = await disco.query_info(
target,
node="http://jabber.org/protocol/commands"
)
# Register custom identity on our client
disco_server.register_identity(
category="client",
type_="bot",
name="My XMPP Bot"
)
# Register supported feature
disco_server.register_feature("http://example.org/custom-feature")
```
--------------------------------
### Obtain JID and Password
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/quickstart.md
Collects user credentials for XMPP authentication.
```python
jid = aioxmpp.JID.fromstr(input("JID: "))
password = getpass.getpass()
```
--------------------------------
### PubSub Node Configuration Form
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/api/changelog.md
Represents the configuration form for a PubSub node.
```python
aioxmpp.pubsub.NodeConfigForm
```
--------------------------------
### Configure SPHINXBUILD environment variable
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/README.md
Sets the SPHINXBUILD variable to point to the correct sphinx-build executable if the default is not found.
```bash
export SPHINXBUILD=sphinx-build
```
--------------------------------
### PubSub Publish Options
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/api/changelog.md
The publish_options argument for aioxmpp.PubSubClient.publish() allows specifying options when publishing to a node.
```python
aioxmpp.PubSubClient.publish()
```
--------------------------------
### Run end-to-end tests
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/dev-guide/index.md
Execute integration tests against an XMPP server using the specialized aioxmpp.e2etest runner.
```console
$ python3 -m aioxmpp.e2etest tests
```
--------------------------------
### Capturing Raw XML Events with CapturingXSO
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/api/changelog.md
Illustrates the use of aioxmpp.xso.CapturingXSO to capture raw XML events for creating XSO instances. This is useful for re-creating XML transcripts.
```python
aioxmpp.xso.events_to_sax()
```
--------------------------------
### Use PresenceClient service
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/quickstart.md
Uses the PresenceClient service to monitor peer availability via signal connections.
```python
client = aioxmpp.PresenceManagedClient(
jid,
aioxmpp.make_security_layer(password)
)
def peer_available(jid):
print("{} came online".format(jid))
def peer_unavailable(jid):
print("{} went offline".format(jid))
presence = client.summon(aioxmpp.PresenceClient)
presence.on_bare_available.connect(peer_available)
presence.on_bare_unavailable.connect(peer_unavailable)
async with client.connected() as stream:
await asyncio.sleep(10)
```
--------------------------------
### XSO Query Language Syntax Draft
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/xso-query.md
Demonstrates the basic syntax for filtering events using the XSO Query Language, including direct property comparisons and the '@' operator for object extraction.
```default
Message.from_ == "fnord",
pubsub_xso.Event @ Message.xep0060_event,
pubsub_xso.EventItems @ pubsub_xso.Event.payload,
pubsub_xso.EventItems.node == "foo",
```
--------------------------------
### Use `connected()` Context Manager for Clean Shutdown
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/pitfalls.md
Use the `aioxmpp.Client.connected()` asynchronous context manager to ensure the client connection is closed cleanly when exiting the block, preventing lingering online states.
```python
client = aioxmpp.Client()
with client.connected() as stream:
# stream is the aioxmpp.stream.StanzaStream of the client
# do something
```
--------------------------------
### Define and parse an XSO object
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/an-introduction-to-xso.md
Demonstrates defining a class inheriting from aioxmpp.xso.XSO with attributes and child text descriptors, then parsing XML data into an instance of that class.
```python
>>> data = \
... b"" \
... b"some text" \
... b""
>>> namespace = "urn:uuid:203ef66e-4423-49f2-90c9-3cb160986734"
>>> class Node(aioxmpp.xso.XSO):
... TAG = namespace, "node"
... attr = aioxmpp.xso.Attr("a1")
... data = aioxmpp.xso.ChildText((namespace, "child"))
...
>>> buf = io.BytesIO(data)
>>> n = aioxmpp.xml.read_single_xso(buf, Node)
>>> isinstance(n, Node)
True
>>> n.attr
'foo'
>>> n.data
'some text'
```
--------------------------------
### Message Dispatching Transition Path
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/message-dispatching.md
Outlines the potential transition paths for integrating the new message dispatching system with the existing StanzaStream methods.
```APIDOC
## Transition path for existing StanzaStream methods
### Option 1: Multiple Message Dispatchers
Allow multiple Message Dispatchers. A default dispatcher is provided, and existing methods simply redirect to it. This maintains backward compatibility.
### Option 2: Single Message Dispatcher (Legacy Default)
Allow only a single Message Dispatcher. A legacy dispatcher is created by default, and existing methods redirect to it. Changes to the message dispatcher will result in loud failures if callbacks are still registered.
### Option 3: Immediate Deletion
Delete the existing StanzaStream methods immediately, requiring all users to migrate to the new dispatcher interface.
```
--------------------------------
### Global e2etest configuration
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/dev-guide/index.md
Define global settings for the e2etest runner in an INI-style configuration file.
```ini
[global]
timeout=1
provisioner=
```
--------------------------------
### XSO Query Language Alternative Syntax
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/xso-query.md
Presents an alternative syntax for the XSO Query Language using the '/' operator to chain property accesses and perform filtering.
```default
Message.from_ == "fnord",
(Message.xep0060_event / pubsub_xso.Event.payload / pubsub_xso.EventItems.node
== "foo"),
```
--------------------------------
### Console Output of Library Parsing
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/an-introduction-to-xso.md
The expected output when running the `library_load.py` script with the `library_test.xml` file. This shows the parsed book data printed to the console.
```console
$ python3 library_load.py library_test.xml
book (id = 'foo'):
author: F. Nord
published: 2099-01-01
npages: 23
title:
[en] 'The Amazing Life of Foo'
[de] 'Das Faszinierende Leben des Foo'
table of contents:
1. (page 1)
[en] 'The Birth of Foo'
[de] 'Die Geburt des Foo'
2. (page 3)
[en] 'The Death of Foo'
[de] 'Der Tod des Foo'
book (id = 'pink-flamingos'):
author: O. L. Bilderrahmen
published: 2007-01-01
npages: 42
title:
[en] 'The Relevance of Pink Flamingos to Computer Science'
[de] 'Die Relevanz von rosa Flamingos für die Informatik'
table of contents:
```
--------------------------------
### Parse XML into Book Library Structure
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/an-introduction-to-xso.md
Reads an XML file specified by a command-line argument and parses it into the defined Library XSO structure. Requires the `library_demo.py` file to be available.
```python
import sys
import aioxmpp.xml
import library_demo
with open(sys.argv[1], "r") as f:
library = aioxmpp.xml.read_single_xso(f, library_demo.Library)
for book in library.books:
print("book (id = {!r}):".format(book.id_))
print(" author:", book.author)
print(" published:", book.published)
print(" npages:", book.npages)
print(" title:")
for lang, title in book.title.items():
print(" [{!s}] {!r}".format(lang, title))
print(" table of contents:")
for i, chapter in enumerate(book.toc.chapters, 1):
print(" {}. (page {})".format(i, chapter.start_page))
for lang, title in chapter.title.items():
print(" [{!s}] {!r}".format(lang, title))
```
--------------------------------
### Manual Client Shutdown with Future
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/pitfalls.md
If the `connected()` context manager cannot be used, this snippet shows how to manually ensure `aioxmpp.Client.stop()` is called and the client has time to shut down cleanly by connecting to `on_stopped` and `on_failure` signals.
```python
if client.running:
fut = asyncio.Future()
client.on_stopped.connect(fut, client.on_stopped.AUTO_FUTURE)
client.on_failure.connect(fut, client.on_failure.AUTO_FUTURE)
try:
yield from fut
except:
# we are shutting down, ignore any exceptions from on_failure
pass
```
--------------------------------
### React to Messages with SimpleMessageDispatcher
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/quickstart.md
Registers a callback to handle incoming messages using the SimpleMessageDispatcher service.
```python
import aioxmpp.dispatcher
def message_received(msg):
print(msg)
# obtain an instance of the service (we’ll discuss services later)
message_dispatcher = client.summon(
aioxmpp.dispatcher.SimpleMessageDispatcher
)
```
--------------------------------
### Send XMPP Messages
Source: https://context7.com/jssfr/aioxmpp/llms.txt
Illustrates sending different types of XMPP messages using `client.send()` for request-response or `client.enqueue()` for fire-and-forget. Supports multilingual message bodies using `LanguageMap`. Ensure a connected client instance is available.
```python
import asyncio
import aioxmpp
async def send_messages(client):
recipient = aioxmpp.JID.fromstr("friend@example.org")
# Create a chat message
msg = aioxmpp.Message(
type_=aioxmpp.MessageType.CHAT,
to=recipient
)
# Set message body (None key means no language tag)
msg.body[None] = "Hello, World!"
# Multi-language body
msg.body[aioxmpp.structs.LanguageTag.fromstr("en")] = "Hello!"
msg.body[aioxmpp.structs.LanguageTag.fromstr("de")] = "Hallo!"
# Send and wait for transmission
await client.send(msg)
# Or use enqueue for non-blocking send (returns StanzaToken)
token = client.enqueue(msg)
print(f"Message queued with token: {token}")
# Create a reply to a received message
received_msg = msg # Assume we received this
reply = received_msg.make_reply()
reply.body[None] = "Got your message!"
await client.send(reply)
# Message types available:
# aioxmpp.MessageType.CHAT - One-to-one chat
# aioxmpp.MessageType.GROUPCHAT - Multi-user chat
# aioxmpp.MessageType.NORMAL - Standalone message (like email)
# aioxmpp.MessageType.HEADLINE - Alerts/notifications
# aioxmpp.MessageType.ERROR - Error response
```
--------------------------------
### Handle JID (Jabber ID) Objects
Source: https://context7.com/jssfr/aioxmpp/llms.txt
Shows how to create, manipulate, and query JID objects, which represent XMPP addresses. JIDs are immutable and validated upon creation. Use `jid_escape` and `jid_unescape` for special characters in the localpart.
```python
import aioxmpp
# Create JID from string
jid = aioxmpp.JID.fromstr("user@example.org/resource")
# Access components
print(f"Localpart: {jid.localpart}") # "user"
print(f"Domain: {jid.domain}") # "example.org"
print(f"Resource: {jid.resource}") # "resource"
# Create JID from components
jid2 = aioxmpp.JID("user", "example.org", "mobile")
# Get bare JID (without resource)
bare_jid = jid.bare()
print(f"Bare JID: {bare_jid}") # "user@example.org"
# Check JID properties
print(f"Is bare: {bare_jid.is_bare}") # True
print(f"Is domain: {bare_jid.is_domain}") # False
# Create modified JID
new_jid = jid.replace(resource="new_resource")
# JID escaping for special characters in localpart
escaped = aioxmpp.jid_escape("user/name@domain")
original = aioxmpp.jid_unescape(escaped)
```
--------------------------------
### Handle presence updates
Source: https://github.com/jssfr/aioxmpp/blob/devel/docs/user-guide/quickstart.md
Registers a callback to react to available presence stanzas.
```python
import aioxmpp.dispatcher
def available_presence_received(pres):
print(pres)
presence_dispatcher = client.summon(
aioxmpp.dispatcher.SimplePresenceDispatcher,
)
presence_dispatcher.register_callback(
aioxmpp.PresenceType.AVAILABLE,
None,
available_presence_received,
)
```