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
andClientTransport
classes.-
receive_message
() → Tuple[Any, bytes] 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)
. Wherecontext
can be any valid Python type andmessage
must be abytes
object.
-
send_reply
(context: Any, reply: bytes) → None Sends a reply to a client.
The client is usually identified by passing
context
as returned from the originalreceive_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.
- context (any) – A context returned by
-
-
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
andClientTransport
classes.-
send_message
(message: bytes, expect_reply: bool = True) → bytes 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:
-
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: <sphinx.ext.autodoc.importer._MockObject object at 0x7f615bc0d790>) 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
() → Tuple[Any, bytes] 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)
. Wherecontext
can be any valid Python type andmessage
must be abytes
object.
-
send_reply
(context: Any, reply: bytes) → None Sends a reply to a client.
The client is usually identified by passing
context
as returned from the originalreceive_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.
- context (any) – A context returned by
-
classmethod
create
(zmq_context: <sphinx.ext.autodoc.importer._MockObject object at 0x7f615b9a1050>, endpoint: str) → tinyrpc.transports.zmq.ZmqServerTransport 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: <sphinx.ext.autodoc.importer._MockObject object at 0x7f615ba92e50>, timeout: float = None) Bases:
tinyrpc.transports.ClientTransport
Client transport based on a
zmq.REQ
socket.Parameters: - socket – A
zmq.REQ
socket instance, connected to the server socket. - timeout – An optional float. When set it defines the time period
in seconds to wait for a reply.
It will generate a
exc.TimeoutError
exception if no reply was received in time.
-
send_message
(message: bytes, expect_reply: bool = True) → bytes 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:
-
classmethod
create
(zmq_context: <sphinx.ext.autodoc.importer._MockObject object at 0x7f615b9a3250>, endpoint: str, timeout: float = None) → tinyrpc.transports.zmq.ZmqClientTransport 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.
- timeout – Optional period in seconds to wait for reply
- socket – A
HTTP¶
There is only an HTTP client, no server (use WSGI instead).
-
class
tinyrpc.transports.http.
HttpPostClientTransport
(endpoint: str, post_method: Callable = None, **kwargs) Bases:
tinyrpc.transports.ClientTransport
HTTP POST based client transport.
Requires
requests
. Submits messages to a server using the body of anHTTP
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: bytes, expect_reply: bool = 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:
- endpoint (str) – The URL to send
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: int = 4096, queue_class: queue.Queue = <class 'queue.Queue'>, allow_origin: str = '*') Bases:
tinyrpc.transports.ServerTransport
WSGI transport.
Requires
werkzeug
.Due to the nature of WSGI, this transport has a few peculiarities: 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 tosend_reply()
.The parameter
queue_class
must be used to supply a proper queue class for the chosen concurrency mechanism (i.e. when usinggevent
, set it togevent.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
() → Tuple[Any, bytes] 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)
. Wherecontext
can be any valid Python type andmessage
must be abytes
object.
-
send_reply
(context: Any, reply: bytes) Sends a reply to a client.
The client is usually identified by passing
context
as returned from the originalreceive_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.
- context (any) – A context returned by
-
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
() → Tuple[Any, bytes] 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: Any, reply: bytes) → None Sends a reply to a client.
The client is usually identified by passing
context
as returned from the originalreceive_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.
- context (any) – A context returned by
-
Callback¶
-
class
tinyrpc.transports.callback.
CallbackServerTransport
(reader: Callable[[], bytes], writer: Callable[[bytes], None]) 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()
andsend_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
() → Tuple[Any, bytes] Receive a message from the transport.
Uses the callback function
reader
to obtain abytes
message
. May return a context opaque to clients that should be passed on tosend_reply()
to identify the client later on.Returns: A tuple consisting of (context, message)
.
-
send_reply
(context: Any, reply: bytes) Sends a reply to a client.
The client is usually identified by passing
context
as returned from the originalreceive_message()
call.Uses the callback function
writer
to forward the reply.Parameters: - context (any) – A context returned by
receive_message()
. - reply (bytes) – The reply.
- context (any) – A context returned by
- reader (callable) –
RabbitMQ¶
-
class
tinyrpc.transports.rabbitmq.
RabbitMQServerTransport
(connection: <sphinx.ext.autodoc.importer._MockObject object at 0x7f615b8b6e90>, queue: str, exchange: str = '') Bases:
tinyrpc.transports.ServerTransport
Server transport based on a
pika.BlockingConnection
.The transport assumes a RabbitMQ topology has already been established.
Parameters: - connection – A
pika.BlockingConnection
instance. - queue – The RabbitMQ queue to consume messages from.
- exchange – The RabbitMQ exchange to use.
-
receive_message
() → Tuple[Any, bytes] 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)
. Wherecontext
can be any valid Python type andmessage
must be abytes
object.
-
send_reply
(context: Any, reply: bytes) → None Sends a reply to a client.
The client is usually identified by passing
context
as returned from the originalreceive_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.
- context (any) – A context returned by
-
classmethod
create
(host: str, queue: str, exchange: str = '') → tinyrpc.transports.rabbitmq.RabbitMQServerTransport Create new server transport.
Instead of creating the BlockingConnection yourself, you can call this function and pass in the host name, queue, and exchange.
Parameters: - host – The host clients will connect to.
- queue – The RabbitMQ queue to consume messages from.
- exchange – The RabbitMQ exchange to use.
- connection – A
-
class
tinyrpc.transports.rabbitmq.
RabbitMQClientTransport
(connection: <sphinx.ext.autodoc.importer._MockObject object at 0x7f615b8b70d0>, routing_key: str, exchange: str = '') Bases:
tinyrpc.transports.ClientTransport
Client transport based on a
pika.BlockingConnection
.The transport assumes a RabbitMQ topology has already been established.
Parameters: - connection – A
pika.BlockingConnection
instance. - routing_key – The RabbitMQ routing key to direct messages.
- exchange – The RabbitMQ exchange to use.
-
send_message
(message: bytes, expect_reply: bool = True) → bytes 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:
-
classmethod
create
(host: str, routing_key: str, exchange: str = '') → tinyrpc.transports.rabbitmq.RabbitMQClientTransport Create new client transport.
Instead of creating the BlockingConnection yourself, you can call this function and pass in the host name, routing key, and exchange.
Parameters: - host – The host clients will connect to.
- routing_key – The RabbitMQ routing key to direct messages.
- exchange – The RabbitMQ exchange to use.
- connection – A
WebSocket¶
-
class
tinyrpc.transports.websocket.
WSServerTransport
(queue_class: queue.Queue = <class 'queue.Queue'>, wsgi_handler: Callable[[], str] = None) Bases:
tinyrpc.transports.ServerTransport
Requires
geventwebsocket
.Due to the nature of WS, this transport has a few peculiarities: It must be run in a thread, greenlet or some other form of concurrent execution primitive.
This is due to
handle
which is ageventwebsocket.resource.Resource
that joins a wsgi handler for the / and a WebSocket handler for the /ws path. These resource is used in combination with ageventwebsocket.server.WebSocketServer
that blocks while waiting for a call tosend_reply()
.The parameter
queue_class
must be used to supply a proper queue class for the chosen concurrency mechanism (i.e. when usinggevent
, set it togevent.queue.Queue
).Parameters: - queue_class – The queue class to use.
- wsgi_handler – Can be used to change the standard response to a http request to the /
-
receive_message
() → Tuple[Any, bytes] 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)
. Wherecontext
can be any valid Python type andmessage
must be abytes
object.
-
send_reply
(context: Any, reply: bytes) → None Sends a reply to a client.
The client is usually identified by passing
context
as returned from the originalreceive_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.
- context (any) – A context returned by
-
class
tinyrpc.transports.websocket.
WSApplication
(*args, **kwargs) Bases:
sphinx.ext.autodoc.importer._MockObject
This class is the bridge between the WSServerTransport and the WebSocket protocol implemented by
geventwebsocket.resource.WebSocketApplication
-
class
tinyrpc.transports.websocketclient.
HttpWebSocketClientTransport
(endpoint: str, **kwargs) Bases:
tinyrpc.transports.ClientTransport
HTTP WebSocket based client transport.
Requires
websocket-python
. Submits messages to a server using the body of anHTTP
WebSocket
message. Replies are taken from the response of the websocket.The connection is establish on the
__init__
because the protocol is connection oriented, you need to close the connection calling the close method.Parameters: - endpoint – The URL to connect the websocket.
- kwargs – Additional parameters for
websocket.send()
.
-
send_message
(message: bytes, expect_reply: bool = True) → bytes 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:
-
close
() → None Terminate the connection.
Since WebSocket maintains an open connection over multiple calls it must be closed explicitly.