Low level client API (client)

Clients for the KAT device control language.

class katcp.client.AsyncClient(host, port, tb_limit=20, timeout=5.0, logger=<logging.Logger object>, auto_reconnect=True)

Bases: katcp.client.DeviceClient

Implement async and callback-based requests on top of DeviceClient.

This client will use message IDs if the server supports them.

Parameters:

host : string

Host to connect to.

port : int

Port to connect to.

tb_limit : int, optional

Maximum number of stack frames to send in error traceback.

logger : object, optional

Python Logger object to log to. Default is a logger named ‘katcp’.

auto_reconnect : bool, optional

Whether to automatically reconnect if the connection dies.

timeout : float in seconds, optional

Default number of seconds to wait before a callback callback_request times out. Can be overridden in individual calls to callback_request.

Examples

>>> def reply_cb(msg):
...     print "Reply:", msg
...
>>> def inform_cb(msg):
...     print "Inform:", msg
...
>>> c = AsyncClient('localhost', 10000)
>>> c.start()
>>> c.ioloop.add_callback(
...     c.callback_request,
...     katcp.Message.request('myreq'),
...     reply_cb=reply_cb,
...     inform_cb=inform_cb,
... )
...
>>> # expect reply to be printed here
>>> # stop the client once we're finished with it
>>> c.stop()
>>> c.join()

Methods

AsyncClient.blocking_request(msg[, timeout, …]) Send a request message and wait for its reply.
AsyncClient.callback_request(msg[, …]) Send a request message.
AsyncClient.convert_seconds(time_seconds) Convert a time in seconds to the device timestamp units.
AsyncClient.disconnect() Force client connection to close, reconnect if auto-connect set.
AsyncClient.enable_thread_safety() Enable thread-safety features.
AsyncClient.future_request(msg[, timeout, …]) Send a request message, with future replies.
AsyncClient.handle_inform(msg) Handle inform messages related to any current requests.
AsyncClient.handle_message(msg) Handle a message from the server.
AsyncClient.handle_reply(msg) Handle a reply message related to the current request.
AsyncClient.handle_request(msg) Dispatch a request message to the appropriate method.
AsyncClient.inform_build_state(msg) Handle katcp v4 and below build-state inform.
AsyncClient.inform_version(msg) Handle katcp v4 and below version inform.
AsyncClient.inform_version_connect(msg) Process a #version-connect message.
AsyncClient.is_connected() Check if the socket is currently connected.
AsyncClient.join([timeout]) Rejoin the client thread.
AsyncClient.next()
AsyncClient.notify_connected(connected) Event handler that is called whenever the connection status changes.
AsyncClient.preset_protocol_flags(protocol_flags) Preset server protocol flags.
AsyncClient.request(msg[, use_mid]) Send a request message, with automatic message ID assignment.
AsyncClient.running() Whether the client is running.
AsyncClient.send_message(msg) Send any kind of message.
AsyncClient.send_request(msg) Send a request message.
AsyncClient.set_ioloop([ioloop]) Set the tornado.ioloop.IOLoop instance to use.
AsyncClient.start([timeout]) Start the client in a new thread.
AsyncClient.stop(*args, **kwargs) Stop a running client.
AsyncClient.unhandled_inform(msg) Fallback method for inform messages without a registered handler.
AsyncClient.unhandled_reply(msg) Fallback method for reply messages without a registered handler.
AsyncClient.unhandled_request(msg) Fallback method for requests without a registered handler.
AsyncClient.until_connected(**kwargs) Return future that resolves when the client is connected.
AsyncClient.until_protocol(**kwargs) Return future that resolves after receipt of katcp protocol info.
AsyncClient.until_running([timeout]) Return future that resolves when the client is running.
AsyncClient.until_stopped([timeout]) Return future that resolves when the client has stopped.
AsyncClient.wait_connected([timeout]) Wait until the client is connected.
AsyncClient.wait_disconnected([timeout]) Wait until the client is disconnected.
AsyncClient.wait_protocol([timeout]) Wait until katcp protocol information has been received from server.
AsyncClient.wait_running([timeout]) Wait until the client is running.
blocking_request(msg, timeout=None, use_mid=None)

Send a request message and wait for its reply.

Parameters:

msg : Message object

The request Message to send.

timeout : float in seconds

How long to wait for a reply. The default is the the timeout set when creating the AsyncClient.

use_mid : boolean, optional

Whether to use message IDs. Default is to use message IDs if the server supports them.

Returns:

reply : Message object

The reply message received.

informs : list of Message objects

A list of the inform messages received.

callback_request(msg, reply_cb=None, inform_cb=None, user_data=None, timeout=None, use_mid=None)

Send a request message.

Parameters:

msg : Message object

The request message to send.

reply_cb : function

The reply callback with signature reply_cb(msg) or reply_cb(msg, *user_data)

inform_cb : function

The inform callback with signature inform_cb(msg) or inform_cb(msg, *user_data)

user_data : tuple

Optional user data to send to the reply and inform callbacks.

timeout : float in seconds

How long to wait for a reply. The default is the the timeout set when creating the AsyncClient.

use_mid : boolean, optional

Whether to use message IDs. Default is to use message IDs if the server supports them.

future_request(msg, timeout=None, use_mid=None)

Send a request message, with future replies.

Parameters:

msg : Message object

The request Message to send.

timeout : float in seconds

How long to wait for a reply. The default is the the timeout set when creating the AsyncClient.

use_mid : boolean, optional

Whether to use message IDs. Default is to use message IDs if the server supports them.

Returns:

A tornado.concurrent.Future that resolves with: :

reply : Message object

The reply message received.

informs : list of Message objects

A list of the inform messages received.

handle_inform(msg)

Handle inform messages related to any current requests.

Inform messages not related to the current request go up to the base class method.

Parameters:

msg : Message object

The inform message to dispatch.

handle_reply(msg)

Handle a reply message related to the current request.

Reply messages not related to the current request go up to the base class method.

Parameters:

msg : Message object

The reply message to dispatch.

stop(*args, **kwargs)

Stop a running client.

If using a managed ioloop, this must be called from a different thread to the ioloop’s. This method only returns once the client’s main coroutine, _install(), has completed.

If using an unmanaged ioloop, this can be called from the same thread as the ioloop. The until_stopped() method can be used to wait on completion of the main coroutine, _install().

Parameters:

timeout : float in seconds

Seconds to wait for both client thread to have started, and for stopping.

class katcp.client.BlockingClient(host, port, tb_limit=20, timeout=5.0, logger=<logging.Logger object>, auto_reconnect=True)

Bases: katcp.client.CallbackClient

Methods

BlockingClient.blocking_request(msg[, …]) Send a request message and wait for its reply.
BlockingClient.callback_request(msg[, …]) Send a request message.
BlockingClient.convert_seconds(time_seconds) Convert a time in seconds to the device timestamp units.
BlockingClient.disconnect() Force client connection to close, reconnect if auto-connect set.
BlockingClient.enable_thread_safety() Enable thread-safety features.
BlockingClient.future_request(msg[, …]) Send a request message, with future replies.
BlockingClient.handle_inform(msg) Handle inform messages related to any current requests.
BlockingClient.handle_message(msg) Handle a message from the server.
BlockingClient.handle_reply(msg) Handle a reply message related to the current request.
BlockingClient.handle_request(msg) Dispatch a request message to the appropriate method.
BlockingClient.inform_build_state(msg) Handle katcp v4 and below build-state inform.
BlockingClient.inform_version(msg) Handle katcp v4 and below version inform.
BlockingClient.inform_version_connect(msg) Process a #version-connect message.
BlockingClient.is_connected() Check if the socket is currently connected.
BlockingClient.join([timeout]) Rejoin the client thread.
BlockingClient.next()
BlockingClient.notify_connected(connected) Event handler that is called whenever the connection status changes.
BlockingClient.preset_protocol_flags(…) Preset server protocol flags.
BlockingClient.request(msg[, use_mid]) Send a request message, with automatic message ID assignment.
BlockingClient.running() Whether the client is running.
BlockingClient.send_message(msg) Send any kind of message.
BlockingClient.send_request(msg) Send a request message.
BlockingClient.setDaemon(daemonic) Set daemonic state of the managed ioloop thread to True / False
BlockingClient.set_ioloop([ioloop]) Set the tornado.ioloop.IOLoop instance to use.
BlockingClient.start([timeout]) Start the client in a new thread.
BlockingClient.stop(*args, **kwargs) Stop a running client.
BlockingClient.unhandled_inform(msg) Fallback method for inform messages without a registered handler.
BlockingClient.unhandled_reply(msg) Fallback method for reply messages without a registered handler.
BlockingClient.unhandled_request(msg) Fallback method for requests without a registered handler.
BlockingClient.until_connected(**kwargs) Return future that resolves when the client is connected.
BlockingClient.until_protocol(**kwargs) Return future that resolves after receipt of katcp protocol info.
BlockingClient.until_running([timeout]) Return future that resolves when the client is running.
BlockingClient.until_stopped([timeout]) Return future that resolves when the client has stopped.
BlockingClient.wait_connected([timeout]) Wait until the client is connected.
BlockingClient.wait_disconnected([timeout]) Wait until the client is disconnected.
BlockingClient.wait_protocol([timeout]) Wait until katcp protocol information has been received from server.
BlockingClient.wait_running([timeout]) Wait until the client is running.
class katcp.client.CallbackClient(host, port, tb_limit=20, timeout=5.0, logger=<logging.Logger object>, auto_reconnect=True)

Bases: katcp.client.AsyncClient

Methods

CallbackClient.blocking_request(msg[, …]) Send a request message and wait for its reply.
CallbackClient.callback_request(msg[, …]) Send a request message.
CallbackClient.convert_seconds(time_seconds) Convert a time in seconds to the device timestamp units.
CallbackClient.disconnect() Force client connection to close, reconnect if auto-connect set.
CallbackClient.enable_thread_safety() Enable thread-safety features.
CallbackClient.future_request(msg[, …]) Send a request message, with future replies.
CallbackClient.handle_inform(msg) Handle inform messages related to any current requests.
CallbackClient.handle_message(msg) Handle a message from the server.
CallbackClient.handle_reply(msg) Handle a reply message related to the current request.
CallbackClient.handle_request(msg) Dispatch a request message to the appropriate method.
CallbackClient.inform_build_state(msg) Handle katcp v4 and below build-state inform.
CallbackClient.inform_version(msg) Handle katcp v4 and below version inform.
CallbackClient.inform_version_connect(msg) Process a #version-connect message.
CallbackClient.is_connected() Check if the socket is currently connected.
CallbackClient.join([timeout]) Rejoin the client thread.
CallbackClient.next()
CallbackClient.notify_connected(connected) Event handler that is called whenever the connection status changes.
CallbackClient.preset_protocol_flags(…) Preset server protocol flags.
CallbackClient.request(msg[, use_mid]) Send a request message, with automatic message ID assignment.
CallbackClient.running() Whether the client is running.
CallbackClient.send_message(msg) Send any kind of message.
CallbackClient.send_request(msg) Send a request message.
CallbackClient.setDaemon(daemonic) Set daemonic state of the managed ioloop thread to True / False
CallbackClient.set_ioloop([ioloop]) Set the tornado.ioloop.IOLoop instance to use.
CallbackClient.start([timeout]) Start the client in a new thread.
CallbackClient.stop(*args, **kwargs) Stop a running client.
CallbackClient.unhandled_inform(msg) Fallback method for inform messages without a registered handler.
CallbackClient.unhandled_reply(msg) Fallback method for reply messages without a registered handler.
CallbackClient.unhandled_request(msg) Fallback method for requests without a registered handler.
CallbackClient.until_connected(**kwargs) Return future that resolves when the client is connected.
CallbackClient.until_protocol(**kwargs) Return future that resolves after receipt of katcp protocol info.
CallbackClient.until_running([timeout]) Return future that resolves when the client is running.
CallbackClient.until_stopped([timeout]) Return future that resolves when the client has stopped.
CallbackClient.wait_connected([timeout]) Wait until the client is connected.
CallbackClient.wait_disconnected([timeout]) Wait until the client is disconnected.
CallbackClient.wait_protocol([timeout]) Wait until katcp protocol information has been received from server.
CallbackClient.wait_running([timeout]) Wait until the client is running.
setDaemon(daemonic)

Set daemonic state of the managed ioloop thread to True / False

Calling this method for a non-managed ioloop has no effect. Must be called before start(), or it will also have no effect

class katcp.client.DeviceClient(host, port, tb_limit=20, logger=<logging.Logger object>, auto_reconnect=True)

Bases: future.types.newobject.newobject

Device client proxy.

Subclasses should implement .reply_*, .inform_* and send_request_* methods to take actions when messages arrive, and implement unhandled_inform, unhandled_reply and unhandled_request to provide fallbacks for messages for which there is no handler.

Request messages can be sent by calling .send_request().

Parameters:

host : string

Host to connect to.

port : int

Port to connect to.

tb_limit : int

Maximum number of stack frames to send in error traceback.

logger : object

Python Logger object to log to.

auto_reconnect : bool

Whether to automatically reconnect if the connection dies.

Notes

The client may block its ioloop if the default blocking tornado DNS resolver is used. When an ioloop is shared, it would make sense to configure one of the non-blocking resolver classes, see http://tornado.readthedocs.org/en/latest/netutil.html

Examples

>>> MyClient(DeviceClient):
...     def reply_myreq(self, msg):
...         print str(msg)
...
>>> c = MyClient('localhost', 10000)
>>> c.start()
>>> c.send_request(katcp.Message.request('myreq'))
>>> # expect reply to be printed here
>>> # stop the client once we're finished with it
>>> c.stop()
>>> c.join()

Methods

DeviceClient.convert_seconds(time_seconds) Convert a time in seconds to the device timestamp units.
DeviceClient.disconnect() Force client connection to close, reconnect if auto-connect set.
DeviceClient.enable_thread_safety() Enable thread-safety features.
DeviceClient.handle_inform(msg) Dispatch an inform message to the appropriate method.
DeviceClient.handle_message(msg) Handle a message from the server.
DeviceClient.handle_reply(msg) Dispatch a reply message to the appropriate method.
DeviceClient.handle_request(msg) Dispatch a request message to the appropriate method.
DeviceClient.inform_build_state(msg) Handle katcp v4 and below build-state inform.
DeviceClient.inform_version(msg) Handle katcp v4 and below version inform.
DeviceClient.inform_version_connect(msg) Process a #version-connect message.
DeviceClient.is_connected() Check if the socket is currently connected.
DeviceClient.join([timeout]) Rejoin the client thread.
DeviceClient.next()
DeviceClient.notify_connected(connected) Event handler that is called whenever the connection status changes.
DeviceClient.preset_protocol_flags(…) Preset server protocol flags.
DeviceClient.request(msg[, use_mid]) Send a request message, with automatic message ID assignment.
DeviceClient.running() Whether the client is running.
DeviceClient.send_message(msg) Send any kind of message.
DeviceClient.send_request(msg) Send a request message.
DeviceClient.set_ioloop([ioloop]) Set the tornado.ioloop.IOLoop instance to use.
DeviceClient.start([timeout]) Start the client in a new thread.
DeviceClient.stop([timeout]) Stop a running client.
DeviceClient.unhandled_inform(msg) Fallback method for inform messages without a registered handler.
DeviceClient.unhandled_reply(msg) Fallback method for reply messages without a registered handler.
DeviceClient.unhandled_request(msg) Fallback method for requests without a registered handler.
DeviceClient.until_connected(**kwargs) Return future that resolves when the client is connected.
DeviceClient.until_protocol(**kwargs) Return future that resolves after receipt of katcp protocol info.
DeviceClient.until_running([timeout]) Return future that resolves when the client is running.
DeviceClient.until_stopped([timeout]) Return future that resolves when the client has stopped.
DeviceClient.wait_connected([timeout]) Wait until the client is connected.
DeviceClient.wait_disconnected([timeout]) Wait until the client is disconnected.
DeviceClient.wait_protocol([timeout]) Wait until katcp protocol information has been received from server.
DeviceClient.wait_running([timeout]) Wait until the client is running.
MAX_LOOP_LATENCY = 0.03

Do not spend more than this many seconds reading pipelined socket data

IOStream inline-reading can result in ioloop starvation (see https://groups.google.com/forum/#!topic/python-tornado/yJrDAwDR_kA).

MAX_MSG_SIZE = 2097152

Maximum message size that can be received in bytes.

If more than MAX_MSG_SIZE bytes are read from the socket without encountering a message terminator (i.e. newline), the connection is closed.

MAX_WRITE_BUFFER_SIZE = 4194304

Maximum outstanding bytes to be buffered by the server process.

If more than MAX_WRITE_BUFFER_SIZE bytes are outstanding, the connection is closed. Note that the OS also buffers socket writes, so more than MAX_WRITE_BUFFER_SIZE bytes may be untransmitted in total.

bind_address

(host, port) where the client is connecting

convert_seconds(time_seconds)

Convert a time in seconds to the device timestamp units.

KATCP v4 and earlier, specified all timestamps in milliseconds. Since KATCP v5, all timestamps are in seconds. If the device KATCP version has been detected, this method converts a value in seconds to the appropriate (seconds or milliseconds) quantity. For version smaller than V4, the time value will be truncated to the nearest millisecond.

disconnect()

Force client connection to close, reconnect if auto-connect set.

enable_thread_safety()

Enable thread-safety features.

Must be called before start().

handle_inform(msg)

Dispatch an inform message to the appropriate method.

Parameters:

msg : Message object

The inform message to dispatch.

handle_message(msg)

Handle a message from the server.

Parameters:

msg : Message object

The Message to dispatch to the handler methods.

handle_reply(msg)

Dispatch a reply message to the appropriate method.

Parameters:

msg : Message object

The reply message to dispatch.

handle_request(msg)

Dispatch a request message to the appropriate method.

Parameters:

msg : Message object

The request message to dispatch.

inform_build_state(msg)

Handle katcp v4 and below build-state inform.

inform_version(msg)

Handle katcp v4 and below version inform.

inform_version_connect(msg)

Process a #version-connect message.

is_connected()

Check if the socket is currently connected.

Returns:

connected : bool

Whether the client is connected.

join(timeout=None)

Rejoin the client thread.

Parameters:

timeout : float in seconds

Seconds to wait for thread to finish.

Notes

Does nothing if the ioloop is not managed. Use until_stopped() instead.

notify_connected(connected)

Event handler that is called whenever the connection status changes.

Override in derived class for desired behaviour.

Note

This function should never block. Doing so will cause the client to cease processing data from the server until notify_connected completes.

Parameters:

connected : bool

Whether the client has just connected (True) or just disconnected (False).

preset_protocol_flags(protocol_flags)

Preset server protocol flags.

Sets the assumed server protocol flags and disables automatic server version detection.

Parameters:protocol_flags : katcp.core.ProtocolFlags instance
request(msg, use_mid=None)

Send a request message, with automatic message ID assignment.

Parameters:

msg : katcp.Message request message

use_mid : bool or None, default=None

Returns:

mid : string or None

The message id, or None if no msg id is used

If use_mid is None and the server supports msg ids, or if use_mid is :

True a message ID will automatically be assigned msg.mid is None. :

if msg.mid has a value, and the server supports msg ids, that value :

will be used. If the server does not support msg ids, KatcpVersionError :

will be raised. :

running()

Whether the client is running.

Returns:

running : bool

Whether the client is running.

send_message(msg)

Send any kind of message.

Parameters:

msg : Message object

The message to send.

send_request(msg)

Send a request message.

Parameters:

msg : Message object

The request Message to send.

set_ioloop(ioloop=None)

Set the tornado.ioloop.IOLoop instance to use.

This defaults to IOLoop.current(). If set_ioloop() is never called the IOLoop is managed: started in a new thread, and will be stopped if self.stop() is called.

Notes

Must be called before start() is called

start(timeout=None)

Start the client in a new thread.

Parameters:

timeout : float in seconds

Seconds to wait for client thread to start. Do not specify a timeout if start() is being called from the same ioloop that this client will be installed on, since it will block the ioloop without progressing.

stop(timeout=None)

Stop a running client.

If using a managed ioloop, this must be called from a different thread to the ioloop’s. This method only returns once the client’s main coroutine, _install(), has completed.

If using an unmanaged ioloop, this can be called from the same thread as the ioloop. The until_stopped() method can be used to wait on completion of the main coroutine, _install().

Parameters:

timeout : float in seconds

Seconds to wait for both client thread to have started, and for stopping.

unhandled_inform(msg)

Fallback method for inform messages without a registered handler.

Parameters:

msg : Message object

The inform message that wasn’t processed by any handlers.

unhandled_reply(msg)

Fallback method for reply messages without a registered handler.

Parameters:

msg : Message object

The reply message that wasn’t processed by any handlers.

unhandled_request(msg)

Fallback method for requests without a registered handler.

Parameters:

msg : Message object

The request message that wasn’t processed by any handlers.

until_connected(**kwargs)

Return future that resolves when the client is connected.

until_protocol(**kwargs)

Return future that resolves after receipt of katcp protocol info.

If the returned future resolves, the server’s protocol information is available in the ProtocolFlags instance self.protocol_flags.

until_running(timeout=None)

Return future that resolves when the client is running.

Notes

Must be called from the same ioloop as the client.

until_stopped(timeout=None)

Return future that resolves when the client has stopped.

Parameters:

timeout : float in seconds

Seconds to wait for the client to stop.

Notes

If already running, stop() must be called before this.

Must be called from the same ioloop as the client. If using a different thread, or a managed ioloop, this method should not be used. Use join() instead.

Also note that stopped != not running. Stopped means the main coroutine has ended, or was never started. When stopping, the running flag is cleared some time before stopped is set.

wait_connected(timeout=None)

Wait until the client is connected.

Parameters:

timeout : float in seconds

Seconds to wait for the client to connect.

Returns:

connected : bool

Whether the client is connected.

Notes

Do not call this from the ioloop, use until_connected().

wait_disconnected(timeout=None)

Wait until the client is disconnected.

Parameters:

timeout : float in seconds

Seconds to wait for the client to disconnect.

Returns:

disconnected : bool

Whether the client is disconnected.

Notes

Do not call this from the ioloop, use until_disconnected().

wait_protocol(timeout=None)

Wait until katcp protocol information has been received from server.

Parameters:

timeout : float in seconds

Seconds to wait for the client to connect.

Returns:

received : bool

Whether protocol information was received

If this method returns True, the server’s protocol information is :

available in the ProtocolFlags instance self.protocol_flags. :

Notes

Do not call this from the ioloop, use until_protocol().

wait_running(timeout=None)

Wait until the client is running.

Parameters:

timeout : float in seconds

Seconds to wait for the client to start running.

Returns:

running : bool

Whether the client is running

Notes

Do not call this from the ioloop, use until_running().

katcp.client.make_threadsafe(meth)

Decorator for a DeviceClient method that should always run in ioloop.

Used with DeviceClient.enable_thread_safety(). If not called the method will be unprotected and it is the user’s responsibility to ensure that these methods are only called from the ioloop, otherwise the decorated methods are wrapped. Should only be used for functions that have no return value.

katcp.client.make_threadsafe_blocking(meth)

Decorator for a DeviceClient method that will block.

Used with DeviceClient.enable_thread_safety(). Used to provide blocking calls that can be made from other threads. If called in ioloop context, calls the original method directly to prevent deadlocks. Will route return value to caller. Add timeout keyword argument to limit blocking time. If meth returns a future, its result will be returned, otherwise its result will be passed back directly.

katcp.client.request_check(client, exception, *msg_parms, **kwargs)

Make blocking request to client and raise exception if reply is not ok.

Parameters:

client : DeviceClient instance

exception: Exception class to raise :

*msg_parms : Message parameters sent to the Message.request() call

**kwargs : Keyword arguments

Forwards kwargs[‘timeout’] to client.blocking_request(). Forwards kwargs[‘mid’] to Message.request().

Returns:

reply, informs : as returned by client.blocking_request

Raises:

*exception* passed as parameter is raised if reply.reply_ok() is False :

Notes

A typical use-case for this function is to use functools.partial() to bind a particular client and exception. The resulting function can then be used instead of direct client.blocking_request() calls to automate error handling.