saturnin.protocol.fbsp

Saturnin reference implementation of Firebird Butler Service Protocol.

See https://firebird-butler.readthedocs.io/en/latest/rfc/4/FBSP.html

Constants

saturnin.protocol.fbsp.HEADER_FMT_FULL: Final[str] = '!4sBBH8s'

FBSP protocol control frame struct format

saturnin.protocol.fbsp.HEADER_FMT: Final[str] = '!4xBBH8s'

FBSP protocol control frame struct format without FOURCC

saturnin.protocol.fbsp.FOURCC: Final[bytes] = b'FBSP'

FBSP protocol identification (FOURCC)

saturnin.protocol.fbsp.VERSION_MASK: Final[int] = 7

FBSP protocol version mask

saturnin.protocol.fbsp.ERROR_TYPE_MASK: Final[int] = 31

FBSP protocol error mask

saturnin.protocol.fbsp.PROTO_HELLO: Final[str] = 'firebird.butler.FBSPHelloDataframe'

Protobuf message for FBSP HELLO message

saturnin.protocol.fbsp.PROTO_WELCOME: Final[str] = 'firebird.butler.FBSPWelcomeDataframe'

Protobuf message for FBSP WELCOME message

saturnin.protocol.fbsp.PROTO_CANCEL_REQ: Final[str] = 'firebird.butler.FBSPCancelRequests'

Protobuf message for FBSP CANCEL REQUEST message

saturnin.protocol.fbsp.PROTO_STATE_INFO: Final[str] = 'firebird.butler.FBSPStateInformation'

Protobuf message for FBSP STATE INFO message

saturnin.protocol.fbsp.PROTO_ERROR: Final[str] = 'firebird.butler.ErrorDescription'

Protobuf message for FBSP ERROR message

Enums

class saturnin.protocol.fbsp.MsgType(value)[source]

Bases: IntEnum

FBSP Message Type

CANCEL = 7
CLOSE = 9
DATA = 6
ERROR = 31
HELLO = 1
NOOP = 3
REPLY = 5
REQUEST = 4
STATE = 8
UNKNOWN = 0
WELCOME = 2
class saturnin.protocol.fbsp.MsgFlag(value)[source]

Bases: IntFlag

FBSP message flag

_generate_next_value_(start, count, last_values)

Generate the next value when not given.

name: the name of the member start: the initial start value or None count: the number of existing members last_values: the last value assigned or None

ACK_REPLY = 2
ACK_REQ = 1
MORE = 4
NONE = 0
class saturnin.protocol.fbsp.ErrorCode(value)[source]

Bases: IntEnum

FBSP Error Code

BAD_REQUEST = 3
CONFLICT = 14
ERROR = 5
FAILED_DEPENDENCY = 9
FBSP_VERSION_NOT_SUPPORTED = 2001
FORBIDDEN = 10
GONE = 13
INSUFFICIENT_STORAGE = 16
INTERNAL_ERROR = 6
INVALID_MESSAGE = 1
NOT_FOUND = 12
NOT_IMPLEMENTED = 4
PAYLOAD_TOO_LARGE = 15
PROTOCOL_VIOLATION = 2
REQUEST_CANCELLED = 17
REQUEST_TIMEOUT = 7
SERVICE_UNAVAILABLE = 2000
TOO_MANY_REQUESTS = 8
UNAUTHORIZED = 11

Classes

class saturnin.protocol.fbsp.FBSPMessage[source]

Bases: Message

Firebird Butler Service Protocol (FBSP) Message.

_pack_data() list[source]

Called when serialization is requested.

Note: Default implementation returns empty list.

Returns:

A list of ZMQ-compatible frames (bytes or zmq.Frame) representing the message-specific payload.

Return type:

list

_set_hdr(header: bytes) None[source]

Initialize new message from header.

Parameters:

header (bytes)

Return type:

None

_unpack_data(data: list) None[source]

Called when all fields of the message are set. Usefull for data deserialization.

Note: Default implementation does nothing.

Parameters:

data (list) – A list of remaining ZMQ frames after the header, to be deserialized into message-specific attributes.

Return type:

None

as_zmsg() TZMQMessage[source]

Returns message as sequence of ZMQ data frames.

Return type:

TZMQMessage

clear() None[source]

Clears message data.

Important

The msg_type remains the same (i.e. you can’t change the message type once message instance was created), but all other data are cleared.

Return type:

None

clear_flag(flag: MsgFlag) None[source]

Clear flag specified by flag mask.

Parameters:

flag (MsgFlag)

Return type:

None

copy() Message[source]

Returns copy of the message.

Return type:

Message

from_zmsg(zmsg: TZMQMessage) None[source]

Populate message data from sequence of ZMQ data frames.

Parameters:

zmsg (TZMQMessage) – Sequence of ZMQ frames. The first frame (header) is assumed to have been pre-processed by the message factory to set initial attributes like msg_type. This method processes subsequent frames.

Raises:

InvalidMessageError – If message is not a valid protocol message.

Return type:

None

get_header() bytes[source]

Return message header (FBSP control frame).

Return type:

bytes

get_keys() Iterable[source]

Returns iterable of dictionary keys to be used with Protocol.handlers. Keys must be provided in order of precedence (from more specific to general).

Return type:

Iterable

has_ack_reply() bool[source]

Returns True if message has ASK_REPLY flag set.

Return type:

bool

has_ack_req() bool[source]

Returns True if message has ACK_REQ flag set.

Return type:

bool

has_more() bool[source]

Returns True if message has MORE flag set.

Return type:

bool

set_flag(flag: MsgFlag) None[source]

Set flag specified by flag mask.

Parameters:

flag (MsgFlag)

Return type:

None

flags: MsgFlag

Message flags

msg_type: MsgType

Type of message

token: Token

Message token

type_data: int

Data associated with message

class saturnin.protocol.fbsp.HandshakeMessage[source]

Bases: FBSPMessage

Base FBSP client/service handshake message (HELLO or WELCOME). The message includes basic information about the Peer.

_pack_data() list[source]

Called when serialization is requested.

Return type:

list

_unpack_data(data: list) None[source]

Called when all fields of the message are set. Usefull for data deserialization.

Parameters:

data (list)

Return type:

None

clear() None[source]

Clears message attributes.

Return type:

None

data: ProtoMessage

Protobuf message instance holding peer information.

class saturnin.protocol.fbsp.HelloMessage[source]

Bases: HandshakeMessage

The HELLO message is a Client request to open a Connection to the Service. The message includes basic information about the Client and Connection parameters required by the Client.

data: FBSPHelloDataframe

FBSPHelloDataframe protobuf message with peer information

class saturnin.protocol.fbsp.WelcomeMessage[source]

Bases: HandshakeMessage

The WELCOME message is the response of the Service to the HELLO message sent by the Client, which confirms the successful creation of the required Connection and announces basic parameters of the Service and the Connection.

data: FBSPWelcomeDataframe

FBSPWelcomeDataframe protobuf message with peer information

class saturnin.protocol.fbsp.APIMessage[source]

Bases: FBSPMessage

Base FBSP client/service API message (REQUEST, REPLY, STATE). The message includes information about the API call (interface ID and API Code).

_pack_data() list[source]

Called when serialization is requested.

Return type:

list

_unpack_data(data: list) None[source]

Called when all fields of the message are set. Usefull for data deserialization.

Parameters:

data (list)

Return type:

None

clear() None[source]

Clears message attributes.

Return type:

None

property api_code: int

API Code (lower byte of Request Code)

data: list

List of bytes, typically representing data frames of the API message payload.

property interface_id: int

Interface ID (high byte of Request Code)

property request_code: int

Request Code (Interface ID + API Code)

class saturnin.protocol.fbsp.StateMessage[source]

Bases: APIMessage

The STATE message is a Client request to the Service.

_pack_data() list[source]

Called when serialization is requested.

Returns:

A list containing the serialized FBSPStateInformation protobuf message.

Return type:

list

_unpack_data(data: list) None[source]

Called when all fields of the message are set. Usefull for data deserialization.

Parameters:

data (list) – A list containing the serialized FBSPStateInformation protobuf message.

Return type:

None

clear() None[source]

Clears message attributes.

Return type:

None

property state: State

Service state

state_info: FBSPStateInformation

FBSPStateInformation protobuf message with state information

class saturnin.protocol.fbsp.DataMessage[source]

Bases: FBSPMessage

The DATA message is intended for delivery of arbitrary data between connected peers.

_pack_data() list[source]

Called when serialization is requested.

Returns:

A list of bytes containing the message data.

Return type:

list

_unpack_data(data: list) None[source]

Called when all fields of the message are set. Usefull for data deserialization.

Parameters:

data (list) – A list containing bytes or zmq.Frame data payload.

Return type:

None

clear() None[source]

Clears message attributes.

Return type:

None

data: list[bytes]

Data payload

class saturnin.protocol.fbsp.CancelMessage[source]

Bases: FBSPMessage

The CANCEL message represents a request for a Service to stop processing the previous request from the Client.

_pack_data() list[source]

Called when serialization is requested.

Returns:

A list containing the serialized FBSPCancelRequests protobuf message.

Return type:

list

_unpack_data(data: list) None[source]

Called when all fields of the message are set. Usefull for data deserialization.

Parameters:

data (list) – A list containing the serialized FBSPCancelRequests protobuf message.

Return type:

None

clear() None[source]

Clears message attributes.

Return type:

None

request: FBSPCancelRequests

FBSPCancelRequests protobuf message

class saturnin.protocol.fbsp.ErrorMessage[source]

Bases: FBSPMessage

The ERROR message notifies the Client about error condition detected by Service.

_pack_data() list[source]

Called when serialization is requested.

Returns:

A list containing the serialized ErrorDescription protobuf messages.

Return type:

list

_unpack_data(data: list) None[source]

Called when all fields of the message are set. Usefull for data deserialization.

Parameters:

data (list) – A list containing the serialized ErrorDescription protobuf messages.

Return type:

None

add_error() ErrorDescription[source]

Return newly created ErrorDescription associated with message.

Return type:

ErrorDescription

clear() None[source]

Clears message attributes.

Return type:

None

note_exception(exc: Exception) None[source]

Store information from exception into ErrorMessage.

Parameters:

exc (Exception) – The Exceptioninstance to be recorded in the error message. Handles chained exceptions viacause cause attribute.

Return type:

None

property error_code: ErrorCode

Error code

errors: list[ErrorDescription]

List of ErrorDescription protobuf messages with error information

property relates_to: MsgType

Message type this error relates to

class saturnin.protocol.fbsp.FBSPSession[source]

Bases: Session

FBSP session that holds information about attached peer.

greeting: HelloMessage

HelloMessage (for service sessions) or WelcomeMessage (for client sessions) received from peer during handshake.

partner_uid: uuid.UUID

Client peer ID for service, Service agent ID for client

class saturnin.protocol.fbsp._FBSP(*args, **kwargs)[source]

Bases: Protocol

4/FBSP - Firebird Butler Service Protocol

_FBSP__message_factory(zmsg: TypeAliasForwardRef('~saturnin.base.transport.TZMQMessage') | None = None) Message

Internal message factory.

Parameters:

zmsg (TypeAliasForwardRef('~saturnin.base.transport.TZMQMessage') | None) – The raw ZMQ message list, used here to extract the header for determining message type and initializing the correct FBSPMessage subclass.

Return type:

Message

__init__(*, session_type: type[Session])[source]
Parameters:

session_type (type[Session]) – Class for session objects.

create_ack_reply(msg: FBSPMessage) FBSPMessage[source]

Returns new message that is an ACK-REPLY response message.

Parameters:

msg (FBSPMessage) – Message to be acknowledged.

Return type:

FBSPMessage

create_data_for(msg: APIMessage) DataMessage[source]

Create new DataMessage for reply to specific reuest message.

Parameters:
  • message – Request message instance that data relates to

  • msg (APIMessage)

Return type:

DataMessage

create_message_for(message_type: MsgType, token: Token = b'\x00\x00\x00\x00\x00\x00\x00\x00', type_data: int = 0, flags: MsgFlag = <MsgFlag.NONE: 0>) FBSPMessage[source]

Create new FBSPMessage child class instance for particular FBSP message type.

Parameters:
  • message_type (MsgType) – Type of message to be created

  • token (Token) – Message token

  • type_data (int) – Message control data

  • flags (MsgFlag) – Flags

Returns:

New FBSPMessage subclass instance, initialized with the provided header details.

Return type:

FBSPMessage

validate(zmsg: TZMQMessage) None[source]

Verifies that sequence of ZMQ data frames is a valid FBSP protocol message.

If this validation passes without exception, then convert_msg() of the same message must be successful as well.

Parameters:

zmsg (TZMQMessage) – ZeroMQ multipart message to be validated against FBSP rules (FourCC, version, header structure, type-specific frames).

Raises:

InvalidMessageError – If ZMQ message is not a valid FBSP message.

Return type:

None

MESSAGE_MAP: ClassVar[dict[MsgType, FBSPMessage]] = {MsgType.HELLO: <class 'saturnin.protocol.fbsp.HelloMessage'>, MsgType.WELCOME: <class 'saturnin.protocol.fbsp.WelcomeMessage'>, MsgType.NOOP: <class 'saturnin.protocol.fbsp.FBSPMessage'>, MsgType.REQUEST: <class 'saturnin.protocol.fbsp.APIMessage'>, MsgType.REPLY: <class 'saturnin.protocol.fbsp.APIMessage'>, MsgType.DATA: <class 'saturnin.protocol.fbsp.DataMessage'>, MsgType.CANCEL: <class 'saturnin.protocol.fbsp.CancelMessage'>, MsgType.STATE: <class 'saturnin.protocol.fbsp.StateMessage'>, MsgType.CLOSE: <class 'saturnin.protocol.fbsp.FBSPMessage'>, MsgType.ERROR: <class 'saturnin.protocol.fbsp.ErrorMessage'>}

Mapping from message type to specific Message class

OID: Final[str] = '1.3.6.1.4.1.53446.1.3.1'

string with protocol OID (dot notation).

UID: Final[uuid.UUID] = UUID('98bd50a9-5863-551d-b19a-a76e2b2ee4d4')

UUID instance that identifies the protocol.

class saturnin.protocol.fbsp.FBSPService(*args, **kwargs)[source]

Bases: _FBSP

4/FBSP - Firebird Butler Service Protocol - Service side.

__init__(*, session_type: type[FBSPSession] = <class 'saturnin.protocol.fbsp.FBSPSession'>, service: ServiceDescriptor, peer: PeerDescriptor)[source]
Parameters:
accept_new_session(channel: Channel, routing_id: RoutingID, msg: FBSPMessage) bool[source]

Validates incoming message that initiated new session/transmission.

Calls on_accept_client event handler that may reject the client by raising StopError exception with appropriate error code to be sent to the client in ERROR message.

Parameters:
  • channel (Channel) – Channel that received the message.

  • routing_id (RoutingID) – Routing ID of the sender.

  • msg (FBSPMessage) – Received message.

Return type:

bool

close(channel: Channel)[source]

Close all connections to attached clients.

Parameters:

channel (Channel) – Channel used for transmission

create_error_for(msg: FBSPMessage, error_code: ErrorCode) ErrorMessage[source]

Create new ErrorMessage that relates to specific message.

Parameters:
Return type:

ErrorMessage

create_reply_for(msg: APIMessage) APIMessage[source]

Create new ReplyMessage for specific RequestMessage.

Parameters:

msg (APIMessage) – Request message instance that reply relates to

Return type:

APIMessage

create_state_for(msg: APIMessage, state: State) StateMessage[source]

Create new StateMessage that relates to specific RequestMessage.

Parameters:
  • msg (APIMessage) – Request message instance that state relates to

  • state (State) – State code

Return type:

StateMessage

create_welcome_reply(msg: HelloMessage) WelcomeMessage[source]

Create new WelcomeMessage that is a reply to client’s HELLO.

Parameters:

msg (HelloMessage) – HelloMessage from the client

Return type:

WelcomeMessage

handle_ack_reply(channel: Channel, session: FBSPSession, msg: FBSPMessage) None[source]

Process ACK-REPLY messages received from client.

If message has ACK-REPLY flag set, it calls on_ack_received event handler. Otherwise it raises StopError with PROTOCOL_VIOLATION error code.

Parameters:
Return type:

None

Note

All exceptions raised in handler are handled by handle_exception.

handle_cancel_msg(channel: Channel, session: FBSPSession, msg: CancelMessage) None[source]

Process CANCEL message received from peer.

Calls on_cancel event handler. According to FBSP, the service must send the ERROR message with appropriate error code (if request was successfuly cancelled, the code must be 17 - Request Cancelled). To follow the common pattern, the event handler must raise an StopError exception with code attribute set to the error code to be returned in ERROR message.

Parameters:
Raises:

StopError – With error code 4 - Not Implemented if event handler is not defined.

Return type:

None

Note

All exceptions raised in handler are handled by handle_exception.

handle_close_msg(channel: Channel, session: FBSPSession, msg: FBSPMessage) None[source]

Process CLOSE message received from client.

Calls on_session_closed event handler and then discards the session.

Parameters:
Return type:

None

Important

All exceptions raised by event handler are silently ignored.

handle_data_msg(channel: Channel, session: FBSPSession, msg: DataMessage) None[source]

Process DATA message received from peer.

If message is an ACK-REPLY, it calls on_ack_received event handler. Otherwise it calls on_data event handler (that must also handle the ACK-REQ if set).

If on_data event handler is not defined, the handler sends ERROR message with code 2 - Protocol violation by raising the StopError.

Parameters:
Return type:

None

Note

All exceptions raised in handler are handled by handle_exception.

handle_exception(channel: Channel, session: Session, msg: Message, exc: Exception) None[source]

Called by handle_msg() on exception in message handler.

Sends ERROR message and then calls on_exception handler.

Important

The error code is extracted ONLY from StopError exception. Other exception types will result in 6 - Internal Service Error error code.

Parameters:
  • channel (Channel) – Channel for communication with client

  • session (Session) – Client session

  • msg (Message) – Message aasociated with exception

  • exc (Exception) – Exception raised

Return type:

None

handle_hello_msg(channel: Channel, session: FBSPSession, msg: HelloMessage) None[source]

Process HELLO message received from client.

Sends WELCOME message to the client.

Parameters:
Return type:

None

Note

The HELLO message was preprocessed and approved by accept_new_session().

Note

All exceptions raised in handler are handled by handle_exception.

handle_noop_msg(channel: Channel, session: FBSPSession, msg: FBSPMessage) None[source]

Process NOOP message received from client.

If message is an ACK-REPLY, it calls on_ack_received event handler. Otherwise it sends ACK-REPLY if requested and then calls on_noop event handler.

Parameters:
Return type:

None

Note

All exceptions raised in handler are handled by handle_exception.

handle_request_msg(channel: Channel, session: FBSPSession, msg: APIMessage) None[source]

Process REQUEST message received from client.

Calls the appropriate API handler set via register_api_handler().

Important

The registered API handler is responsible for sending the ACK-REPLY message if the incoming request msg has the ACK_REQ flag set. According to FBSP specification, the request should be acknowledged once the Service has decided to accept it and before starting fulfillment. The handler may also send an ERROR message instead of an ACK-REPLY.

Parameters:
  • channel (Channel) – Channel that received the message.

  • session (FBSPSession) – Session instance.

  • msg (APIMessage) – Received message.

Return type:

None

Note

All exceptions raised in handler are handled by handle_exception.

handle_unexpected_msg(channel: Channel, session: FBSPSession, msg: FBSPMessage) None[source]

Process unexpected valid message received from client.

Sends ERROR message to the client with error code 2 - Protocol violation.

Parameters:
Return type:

None

register_api_handler(api_code: ButlerInterface, handler: Callable) None[source]

Register handler for REQUEST message for particular service API code.

Parameters:
  • api_code (ButlerInterface) – API code.

  • handler (Callable) – A callable that handles the API code matching the signature (channel: Channel, session: FBSPSession, msg: APIMessage) -> None

Return type:

None

send_close(channel: Channel, session: FBSPSession) None[source]

Sends CLOSE message to the client associated with session and calls on_session_closed event handler. The message passed to the event handler is the initial HELLO message from client.

Parameters:
  • channel (Channel) – Channel associate with data pipe.

  • session (FBSPSession) – Session associated with transmission.

Return type:

None

Important

All exceptions raised by event handler are silently ignored.

send_error(channel: Channel, session: FBSPSession, relates_to: FBSPMessage, error_code: ErrorCode, exc: Exception | None = None) None[source]

Sends ERROR message to the client associated with session.

Parameters:
  • channel (Channel) – Channel associate with data pipe.

  • session (FBSPSession) – Session associated with transmission.

  • relates_to (FBSPMessage) – FBSP message to which this ERROR is related.

  • error_code (ErrorCode) – Error code.

  • exc (Exception | None) – Exception that caused the error.

Return type:

None

api_handlers: dict[Any, Callable]
on_accept_client

eventsocket called when HELLO message is received from client.

Parameters:
  • channel – Channel that received the message.

  • msg – Received message.

The event handler may reject the client by raising the StopError exception with code attribute containing the ErrorCode to be returned in ERROR message.

If event handler does not raise an exception, the client is accepted, new session is created and WELCOME message is sent to the client.

on_ack_received

eventsocket called when ACK-REPLY NOOP, DATA, REPLY or STATE message is received.

Parameters:
  • channel – Channel that received the message.

  • session – Session instance.

  • msg – Received ACK-REPLY message.

Note

All exceptions raised by handler are handled by handle_exception.

on_cancel

eventsocket called when CANCEL message is received from client.

Parameters:
  • channel – Channel that received the message.

  • session – Session instance.

  • msg – Received message.

The event handler must raise an Error exception with code attribute set to the error code to be returned in ERROR message. If request was successfuly cancelled, the code must be ErrorCode.REQUEST_CANCELLED.

on_data

eventsocket called when DATA message is received.

Important

If handler is defined, it must send the ACK-REPLY if received message has ACK-REQ set. It’s up to service interface whether ACK-REPLY would be sent before, or after data contained within message are processed.

Parameters:
  • channel – Channel that received the message.

  • session – Session instance.

  • msg – Received message.

Note

All exceptions raised in handler are handled by handle_exception.

on_noop

eventsocket called when NOOP message is received, and after ACK-REPLY (if requested) is send.

Parameters:
  • channel – Channel associated with data pipe.

  • session – Session associated with peer.

Note

All exceptions raised in handler are handled by handle_exception.

on_session_closed

eventsocket called when CLOSE message is received or sent, to release any resources associated with current transmission.

Parameters:
  • channel – Channel associated with data pipe.

  • session – Session associated with peer.

  • msg – Received/sent CLOSE message.

  • exc – Exception that caused the error.

Note

All exceptions raised in handler are handled by handle_exception.

welcome_df: FBSPWelcomeDataframe
class saturnin.protocol.fbsp.FBSPClient(*args, **kwargs)[source]

Bases: _FBSP

4/FBSP - Firebird Butler Service Protocol - Client side.

This is the RAW version of client side FBSP protocol for clients that directly process FBSP messages received from service. Such clients call Channel.receive() and then process the returned message or sentinel.

This protocol implementation handles only essential message processing:

  • Message parsing.

  • ACK-REQ for received STATE and NOOP messages.

  • Returns INVALID sentinel for received HELLO and CANCEL messages.

  • Closes the session when CLOSE message is received.

__init__(*, session_type: type[FBSPSession] = <class 'saturnin.protocol.fbsp.FBSPSession'>)[source]
Parameters:

session_type (type[FBSPSession]) – Class for session objects.

create_request_for(session: FBSPSession, api_code: ButlerInterface, token: Token) APIMessage[source]

Returns new REQUEST message for specific API call.

Parameters:
Return type:

APIMessage

exception_for(msg: ErrorMessage) ServiceError[source]

Returns a .ServiceError exception populated with details from the provided ERROR message.

Parameters:

msg (ErrorMessage) – ERROR message received

Return type:

ServiceError

handle_close_msg(channel: Channel, session: FBSPSession, msg: FBSPMessage) FBSPMessage[source]

Process CLOSE message received from service.

Discards the session and returns the CLOSE message received.

Parameters:
Return type:

FBSPMessage

handle_fbsp_msg(channel: Channel, session: FBSPSession, msg: FBSPMessage) FBSPMessage[source]

FBSP message handler that simply returns received message.

If message is a STATE message with ACK-REQ, sends ACK-REPLY. ACK-REQ for other messages must be handled by caller.

Parameters:
Return type:

FBSPMessage

Note

All exceptions raised in handler are handled by handle_exception.

handle_noop_msg(channel: Channel, session: FBSPSession, msg: FBSPMessage) None[source]

Process NOOP message received from service.

Sends ACK-REPLY if requested.

Parameters:
Return type:

None

Note

All exceptions are handled by handle_exception.

handle_unexpected_msg(channel: Channel, session: FBSPSession, msg: FBSPMessage) FBSPMessage[source]

FBSP message handler that returns INVALID sentinel.

Parameters:
Return type:

FBSPMessage

handle_welcome_msg(channel: Channel, session: FBSPSession, msg: WelcomeMessage) WelcomeMessage[source]

Process WELCOME message received from service.

Parameters:
Return type:

WelcomeMessage

has_api(api: type[ButlerInterface]) bool[source]

Returns True if attached service supports specified interface.

Parameters:

api (type[ButlerInterface]) – Service API (interface) enumeration.

Return type:

bool

send_close(channel: Channel, session: FBSPSession) None[source]

Sends CLOSE message to the service associated with session.

Parameters:
  • channel (Channel) – Channel associate with data pipe.

  • session (FBSPSession) – Session associated with transmission.

Return type:

None

send_hello(channel: Channel, session: FBSPSession, agent: AgentDescriptor, peer: PeerDescriptor, token: Token = b'\x00\x00\x00\x00\x00\x00\x00\x00') None[source]

Sends HELLO message to the service.

Parameters:
  • channel (Channel) – Channel used for connection to the service.

  • session (FBSPSession) – Session associated with service.

  • agent (AgentDescriptor) – Agent descriptor for client.

  • peer (PeerDescriptor) – Peer descriptor for client.

  • token (Token) – FBSP message token to be used in HELLO message.

Return type:

None

class saturnin.protocol.fbsp.FBSPEventClient(*args, **kwargs)[source]

Bases: FBSPClient

4/FBSP - Firebird Butler Service Protocol - Client side.

This is the EVENT version of client side FBSP protocol for clients that process FBSP messages received from service indirectly. Such clients use central I/O loop that process incomming messages in uniform way, and actual processing is done via event handlers.

__init__(*, session_type: type[FBSPSession] = <class 'saturnin.protocol.fbsp.FBSPSession'>)[source]
Parameters:

session_type (type[FBSPSession]) – Class for session objects.

handle_ack_reply(channel: Channel, session: FBSPSession, msg: FBSPMessage) None[source]

Process ACK-REPLY messages received from service.

If message has ACK-REPLY flag set, it calls on_ack_received event handler. Otherwise it’s ignored because it violates the protocol.

Parameters:
Return type:

None

Note

All exceptions are handled by handle_exception.

handle_close_msg(channel: Channel, session: FBSPSession, msg: FBSPMessage) None[source]

Process CLOSE message received from service.

Calls on_session_closed event handler and then discards the session.

Parameters:
Return type:

None

handle_data_msg(channel: Channel, session: FBSPSession, msg: DataMessage) None[source]

Process DATA message received from serviec.

If message is an ACK-REPLY, it calls on_ack_received event handler. Otherwise it calls on_data event handler that must handle the ACK-REQ if set. If on_data event handler is not defined, the ACK-REPLY message is send by this handler.

Parameters:
Return type:

None

Note

All exceptions are handled by handle_exception.

handle_error_msg(channel: Channel, session: FBSPSession, msg: ErrorMessage) None[source]

Process ERROR message received from service.

Calls on_error event handler.

Parameters:
Return type:

None

Note

All exceptions are handled by handle_exception.

handle_noop_msg(channel: Channel, session: FBSPSession, msg: FBSPMessage) None[source]

Process NOOP message received from service.

If message is an ACK-REPLY, it calls on_ack_received event handler. Otherwise it sends ACK-REPLY if requested and then calls on_noop event handler.

Parameters:
Return type:

None

Note

All exceptions are handled by handle_exception.

handle_reply_msg(channel: Channel, session: FBSPSession, msg: APIMessage) None[source]

Process REPLY message received from service.

Calls the appropriate API handler set via register_api_handler().

Important

The registered API handler must send the ACK-REPLY message if requested. According to FBSP specification, the reply must be acknowledged without any delay, unless a previous agreement between the Client and the Service exists to handle it differently (for example when Client is prepared to accept subsequent DATA or other messages from Service).

Parameters:
  • channel (Channel) – Channel that received the message.

  • session (FBSPSession) – Session instance.

  • msg (APIMessage) – Received message.

Return type:

None

Note

All exceptions are handled by handle_exception.

handle_state_msg(channel: Channel, session: FBSPSession, msg: StateMessage) None[source]

Process STATE message received from service.

Sends ACK-REPLY if requested and calls on_state event handler.

Parameters:
Return type:

None

Note

All exceptions are handled by handle_exception.

handle_unexpected_msg(channel: Channel, session: FBSPSession, msg: HelloMessage) None[source]

Process unexpected valid message received from service.

Raises StopError with error code 2 - Protocol violation.

Parameters:
Return type:

None

Note

All exceptions are handled by handle_exception.

handle_welcome_msg(channel: Channel, session: FBSPSession, msg: WelcomeMessage) None[source]

Process WELCOME message received from service.

Calls on_service_connected event handler.

Parameters:
Return type:

None

register_api_handler(api_code: ButlerInterface, handler: Callable) None[source]

Register handler for response messages for particular service API code.

Parameters:
  • api_code (ButlerInterface) – API code.

  • handler (Callable) – Callable that handles the API code matching the signature (channel: Channel, session: FBSPSession, msg: FBSPMessage) -> None.

Return type:

None

api_handlers: dict[Any, Callable]
on_ack_received

eventsocket called when ACK-REPLY message is received.

Parameters:
  • channel – Channel that received the message.

  • session – Session instance.

  • msg – Received ACK-REPLY message.

Note

All exceptions are handled by handle_exception.

on_data

eventsocket called when DATA message is received.

Important

If handler is defined, it must send the ACK-REPLY if received message has ACK-REQ set. It’s up to service interface whether ACK-REPLY would be sent before, or after data contained within message are processed.

Parameters:
  • channel – Channel that received the message.

  • session – Session instance.

  • msg – Received message.

Note

All exceptions are handled by handle_exception.

on_error

eventsocket called when ERROR message is received.

Parameters:
  • channel – Channel that received the message.

  • session – Session instance.

  • msg – Received message.

Note

All exceptions are handled by handle_exception.

on_noop

eventsocket called when NOOP message is received, and after ACK-REPLY (if requested) is send.

Parameters:
  • channel – Channel associated with data pipe.

  • session – Session associated with peer.

on_service_connected

eventsocket called when WELCOME message is received from service.

Parameters:
  • channel – Channel that received the message.

  • session – Session instance.

  • msg – Received message.

  • protocol – This FBSPEventClient instance, passed to allow the handler to make further protocol calls if needed.

The event handler should register all service API handlers for REPLY messages (see FBSPEventClient.register_api_handler()).

on_session_closed

eventsocket called when CLOSE message is received or sent, to release any resources associated with current transmission.

Parameters:
  • channel – Channel associated with data pipe.

  • session – Session associated with peer.

  • msg – Received/sent CLOSE message.

  • exc – Exception that caused the error.

on_state

eventsocket called when STATE message is received.

Parameters:
  • channel – Channel that received the message.

  • session – Session instance.

  • msg – Received message.

Note

All exceptions are handled by handle_exception.

class saturnin.protocol.fbsp._APIHandlerChecker[source]

Bases: object

Helper class for validation of API handlers.

client_handler

Signature definition for FBSP Event Client API handlers.

service_handler

Signature definition for FBSP Service API handlers.

Functions

saturnin.protocol.fbsp.bb2h(value_hi: int, value_lo: int) int[source]

Compose two bytes (high byte, low byte) into a 16-bit unsigned word (short) value using network byte order (big-endian).

Parameters:
  • value_hi (int)

  • value_lo (int)

Return type:

int

saturnin.protocol.fbsp.msg_bytes(msg: bytes | bytearray | Frame) bytes | bytearray[source]

Return message frame as bytes.

Parameters:

msg (bytes | bytearray | Frame)

Return type:

bytes | bytearray