Transports

Transports are somewhat low level interface concerned with transporting messages across through different means. “Messages” in this case are simple strings. All transports need to support two different interfaces:

class tinyrpc.transports.ServerTransport

Bases: object

Abstract base class for all server transports.

The server side implementation of the transport component. Requests and replies encoded by the protocol component are exchanged between client and server using the ServerTransport and ClientTransport classes.

receive_message()

Receive a message from the transport.

Blocks until a message has been received. May return an opaque context object to its caller that should be passed on to send_reply() to identify the transport or requester later on. Use and function of the context object are entirely controlled by the transport instance.

The message must be treated as a binary entity as only the protocol level will know how to interpret the message.

If the transport encodes the message in some way, the opposite end is responsible for decoding it before it is passed to either client or server.

Returns

A tuple consisting of (context, message). Where context can be any valid Python type and message must be a bytes object.

send_reply(context, reply)

Sends a reply to a client.

The client is usually identified by passing context as returned from the original receive_message() call.

The reply must be a bytes object since only the protocol level will know how to construct the reply.

Parameters
  • context (any) – A context returned by receive_message().

  • reply (bytes) – The reply to return to the client.

class tinyrpc.transports.ClientTransport

Bases: object

Abstract base class for all client transports.

The client side implementation of the transport component. Requests and replies encoded by the protocol component are exchanged between client and server using the ServerTransport and ClientTransport classes.

send_message(message, expect_reply=True)

Send a message to the server and possibly receive a reply.

Sends a message to the connected server.

The message must be treated as a binary entity as only the protocol level will know how to interpret the message.

If the transport encodes the message in some way, the opposite end is responsible for decoding it before it is passed to either client or server.

This function will block until the reply has been received.

Parameters
  • message (bytes) – The request to send to the server.

  • expect_reply (bool) – Some protocols allow notifications for which a reply is not expected. When this flag is False the transport may not wait for a response from the server. Note that it is still the responsibility of the transport layer how to implement this. It is still possible that the server sends some form of reply regardless the value of this flag.

Returns

The servers reply to the request.

Return type

bytes

Note that these transports are of relevance when using tinyrpc-built in facilities. They can be coopted for any other purpose, if you simply need reliable server-client message passing as well.

Also note that the client transport interface is not designed for asynchronous use. For simple use cases (sending multiple concurrent requests) monkey patching with gevent may get the job done.

Transport implementations

A few transport implementations are included with tinyrpc:

0mq

Based on zmq, supports 0mq based sockets. Highly recommended:

class tinyrpc.transports.zmq.ZmqServerTransport(socket)

Bases: tinyrpc.transports.ServerTransport

Server transport based on a zmq.ROUTER socket.

Parameters

socket – A zmq.ROUTER socket instance, bound to an endpoint.

receive_message()

Receive a message from the transport.

Blocks until a message has been received. May return an opaque context object to its caller that should be passed on to send_reply() to identify the transport or requester later on. Use and function of the context object are entirely controlled by the transport instance.

The message must be treated as a binary entity as only the protocol level will know how to interpret the message.

If the transport encodes the message in some way, the opposite end is responsible for decoding it before it is passed to either client or server.

Returns

A tuple consisting of (context, message). Where context can be any valid Python type and message must be a bytes object.

send_reply(context, reply)

Sends a reply to a client.

The client is usually identified by passing context as returned from the original receive_message() call.

The reply must be a bytes object since only the protocol level will know how to construct the reply.

Parameters
  • context (any) – A context returned by receive_message().

  • reply (bytes) – The reply to return to the client.

classmethod create(zmq_context, endpoint)

Create new server transport.

Instead of creating the socket yourself, you can call this function and merely pass the zmq.core.context.Context instance.

By passing a context imported from zmq.green, you can use green (gevent) 0mq sockets as well.

Parameters
  • zmq_context – A 0mq context.

  • endpoint – The endpoint clients will connect to.

class tinyrpc.transports.zmq.ZmqClientTransport(socket)

Bases: tinyrpc.transports.ClientTransport

Client transport based on a zmq.REQ socket.

Parameters

socket – A zmq.REQ socket instance, connected to the server socket.

send_message(message, expect_reply=True)

Send a message to the server and possibly receive a reply.

Sends a message to the connected server.

The message must be treated as a binary entity as only the protocol level will know how to interpret the message.

If the transport encodes the message in some way, the opposite end is responsible for decoding it before it is passed to either client or server.

This function will block until the reply has been received.

Parameters
  • message (bytes) – The request to send to the server.

  • expect_reply (bool) – Some protocols allow notifications for which a reply is not expected. When this flag is False the transport may not wait for a response from the server. Note that it is still the responsibility of the transport layer how to implement this. It is still possible that the server sends some form of reply regardless the value of this flag.

Returns

The servers reply to the request.

Return type

bytes

classmethod create(zmq_context, endpoint)

Create new client transport.

Instead of creating the socket yourself, you can call this function and merely pass the zmq.core.context.Context instance.

By passing a context imported from zmq.green, you can use green (gevent) 0mq sockets as well.

Parameters
  • zmq_context – A 0mq context.

  • endpoint – The endpoint the server is bound to.

HTTP

There is only an HTTP client, no server (use WSGI instead).

class tinyrpc.transports.http.HttpPostClientTransport(endpoint, post_method=None, **kwargs)

Bases: tinyrpc.transports.ClientTransport

HTTP POST based client transport.

Requires requests. Submits messages to a server using the body of an HTTP POST request. Replies are taken from the responses body.

Parameters
  • endpoint (str) – The URL to send POST data to.

  • post_method (callable) – allows to replace requests.post with another method, e.g. the post method of a requests.Session() instance.

  • kwargs (dict) – Additional parameters for requests.post().

send_message(message, expect_reply=True)

Send a message to the server and possibly receive a reply.

Sends a message to the connected server.

The message must be treated as a binary entity as only the protocol level will know how to interpret the message.

If the transport encodes the message in some way, the opposite end is responsible for decoding it before it is passed to either client or server.

This function will block until the reply has been received.

Parameters
  • message (bytes) – The request to send to the server.

  • expect_reply (bool) – Some protocols allow notifications for which a reply is not expected. When this flag is False the transport may not wait for a response from the server. Note that it is still the responsibility of the transport layer how to implement this. It is still possible that the server sends some form of reply regardless the value of this flag.

Returns

The servers reply to the request.

Return type

bytes

Note

To set a timeout on your client transport provide a timeout keyword parameter like:

transport = HttpPostClientTransport(endpoint, timeout=0.1)

It will result in a requests.exceptions.Timeout exception when a timeout occurs.

WSGI

class tinyrpc.transports.wsgi.WsgiServerTransport(max_content_length=4096, queue_class=<class 'queue.Queue'>, allow_origin='*')

Bases: tinyrpc.transports.ServerTransport

WSGI transport.

Requires werkzeug.

Due to the nature of WSGI, this transport has a few pecularities: It must be run in a thread, greenlet or some other form of concurrent execution primitive.

This is due to handle() blocking while waiting for a call to send_reply().

The parameter queue_class must be used to supply a proper queue class for the chosen concurrency mechanism (i.e. when using gevent, set it to gevent.queue.Queue).

Parameters
  • max_content_length – The maximum request content size allowed. Should be set to a sane value to prevent DoS-Attacks.

  • queue_class – The Queue class to use.

  • allow_origin – The Access-Control-Allow-Origin header. Defaults to * (so change it if you need actual security).

receive_message()

Receive a message from the transport.

Blocks until a message has been received. May return an opaque context object to its caller that should be passed on to send_reply() to identify the transport or requester later on. Use and function of the context object are entirely controlled by the transport instance.

The message must be treated as a binary entity as only the protocol level will know how to interpret the message.

If the transport encodes the message in some way, the opposite end is responsible for decoding it before it is passed to either client or server.

Returns

A tuple consisting of (context, message). Where context can be any valid Python type and message must be a bytes object.

send_reply(context, reply)

Sends a reply to a client.

The client is usually identified by passing context as returned from the original receive_message() call.

The reply must be a bytes object since only the protocol level will know how to construct the reply.

Parameters
  • context (any) – A context returned by receive_message().

  • reply (bytes) – The reply to return to the client.

handle(environ, start_response)

WSGI handler function.

The transport will serve a request by reading the message and putting it into an internal buffer. It will then block until another concurrently running function sends a reply using send_reply().

The reply will then be sent to the client being handled and handle will return.

CGI

class tinyrpc.transports.cgi.CGIServerTransport

Bases: tinyrpc.transports.ServerTransport

CGI transport.

The CGIServerTransport adds CGI as a supported server protocol. It can be used with the regular HTTP client.

Reading stdin is blocking but, given that we’ve been called, something is waiting. The transport accepts only POST requests.

A POST request provides the entire JSON-RPC request in the body of the HTTP request.

receive_message()

Receive a message from the transport.

Blocks until a message has been received. May return a context opaque to clients that should be passed to send_reply() to identify the client later on.

Returns

A tuple consisting of (context, message).

send_reply(context, reply)

Sends a reply to a client.

The client is usually identified by passing context as returned from the original receive_message() call.

Messages must be bytes, it is up to the sender to convert the message beforehand. A non-bytes value raises a TypeError.

Parameters
  • context (any) – A context returned by receive_message().

  • reply (bytes) – A binary to send back as the reply.

Callback

class tinyrpc.transports.callback.CallbackServerTransport(reader, writer)

Bases: tinyrpc.transports.ServerTransport

Callback server transport.

The CallbackServerTransport uses the provided callbacks to implement communication with the counterpart.

Used when tinyrpc is part of a system where it cannot directly attach to a socket or stream. The methods receive_message() and send_reply() are implemented by callback functions that are set when constructed.

Parameters
  • reader (callable) –

    Called when the transport wants to receive a new request.

    returns

    The RPC request.

    rtype

    bytes

  • writer(reply) (callable) –

    Called to return the response to the client.

    param bytes reply

    The response to the request.

receive_message()

Receive a message from the transport.

Uses the callback function reader to obtain a bytes message. May return a context opaque to clients that should be passed on to send_reply() to identify the client later on.

Returns

A tuple consisting of (context, message).

send_reply(context, reply)

Sends a reply to a client.

The client is usually identified by passing context as returned from the original receive_message() call.

Uses the callback function writer to forward the reply.

Parameters
  • context (any) – A context returned by receive_message().

  • reply (bytes) – The reply.

WebSocket