Welcome to Serena’s documentation!

Serena is a structurally concurrent AMQP 0-9-1 client library, for usage with the AnyIO library.

Requirements

  1. Serena requires at least Python 3.11.

  2. Serena is primarily tested against RabbitMQ, but any broker that supports the errata version of AMQP is supported.

  3. The AMQP server must support publisher confirms. (RabbitMQ does support this.)

Installation

Serena can be installed from PyPI:

$ poetry add serena

It can then be imported from the serena package.

Basic Usage

Serena is a relatively thin wrapper around the AMQP 0-9-1 specification, and as such you should familiarise yourself with the AMQP Model before using this library.

First, you need to open a connection. You can do this with the open_connection() context manager provided, like so:

from serena import open_connection

async with open_connection(
    host="127.0.0.1", port=5672,
    username="guest", password="guest",
    virtual_host="/",
) as conn:
    ...

The resulting AMQPConnection can then be used to open a channel using AMQPConnection.open_channel(), like so:

from serena import open_connection

async with open_connection(...) as conn:
    async with conn.open_channel() as channel:
        ...

Error Handling

There are situations where you or someone else (usually, somebody else) makes a programming error that the server doesn’t like.

In these situations, the server will return a Close message that is handled by client machinery, and either the connection or the channel will close. Which one happens is specified in the AMQP specification.

Either way, a UnexpectedCloseError will be raised:

  • If the channel is closed, then it will be raised by the method itself

  • If the connection is closed, then the entire connection will die and it will be raised by the async with block. In addition, all code inside the connection will be cancelled.

class serena.UnexpectedCloseError(reply_code, reply_message, class_id, method_id)

Bases: AMQPError

Thrown when the connection or a channeel closes unexpectedly.

classmethod of(payload)

Creates a new UnexpectedCloseError from a close payload.

Return type:

UnexpectedCloseError

reply_code: ReplyCode

The server-provided error code.

reply_message: str

The server-provided error text.

class_id: int

The class ID of the method that caused this error.

method_id: int

The method ID of the method that caused this error.

Some other errors may be raised for programming errors, such as:

class serena.MessageReturnedError(reply_code, reply_text, exchange, routing_key)

Bases: AMQPError

Thrown when a message is returned unexpectedly.

reply_code

The server-provided error code.

reply_text

The server-provided error text.

exchange

The exchange the message was returned from.

routing_key

The routing key the message was using.

Buffer Sizing

As AMQP is a multiplexed protocol, Serena internally uses several memory channels to distribute messages from the socket to individual channel objects. Memory channels apply backpressure, which means that new messages cannot be delivered when the channel is full.

To avoid this, Serena will automatically apply per-channel QoS to avoid buffering more items than the channel can support. By default, this will be the floor division by three of the channel_buffer_size (default: 48) passed when opening the connection, as every publish uses three frames minimum (Basic.Publish|Get, headers, body). This is primarily a network optimisation as it means the server can send N messages now potentially over less TCP packets instead of needing to a full cycle each time.

However, messages with a large body size may be split across multiple body frames which has the potential to overflow the buffer. When this happens, *the entire connection will block*, as the socket cannot be read from until there is room to buffer new packets in memory.

To avoid this:

  1. Increase the frame size by passing desired_frame_size=BIG to open_connection().

  2. Increase the frame size in the broker configuration.

  3. Send smaller messages.

Warning

Serena negotiates the frame size using the smallest size requested, either on the client or on the server side. You need to change it on both.

Channel Pooling

New in version 0.7.1.

Serena has a built-in channel pooling mechanism, which simplifies error handling (no need to wrap your entire async with in a try/except). See AMQPConnection.open_channel().

Naming

  1. The primary protagonist of Bishōjo Senshi Sailor Moon is called Usagi Tsukino.

  2. Usagi means “rabbit”.

  3. Her name was changed to Serena Tsukino in the 1990s DIC English dub of Sailor Moon.

  4. RabbitMQ is the most popular and well-known AMQP 0-9-1 broker.

Hence, the name Serena.