Concrete High-level KATCP Client API (resource_client)

class katcp.resource_client.ClientGroup(name, clients)

Bases: future.types.newobject.newobject

Create a group of similar clients.

Parameters:

name : str

Name of the group of clients.

clients : list of KATCPResource objects

Clients to put into the group.

Methods

ClientGroup.client_updated(client) Called to notify this group that a client has been updated.
ClientGroup.is_connected() Indication of the connection state of all clients in the group
ClientGroup.next()
ClientGroup.set_sampling_strategies(*args, ...) Set sampling strategy for the sensors of all the group’s clients.
ClientGroup.set_sampling_strategy(*args, ...) Set sampling strategy for the sensors of all the group’s clients.
ClientGroup.wait(*args, **kwargs) Wait for sensor present on all group clients to satisfy a condition.
client_updated(client)

Called to notify this group that a client has been updated.

is_connected()

Indication of the connection state of all clients in the group

set_sampling_strategies(*args, **kwargs)

Set sampling strategy for the sensors of all the group’s clients.

Only sensors that match the specified filter are considered. See the KATCPResource.set_sampling_strategies docstring for parameter definitions and more info.

Returns:

sensors_strategies : tornado Future

Resolves with a dict with client names as keys and with the value as another dict. The value dict is similar to the return value described in the KATCPResource.set_sampling_strategies docstring.

set_sampling_strategy(*args, **kwargs)

Set sampling strategy for the sensors of all the group’s clients.

Only sensors that match the specified filter are considered. See the KATCPResource.set_sampling_strategies docstring for parameter definitions and more info.

Returns:

sensors_strategies : tornado Future

Resolves with a dict with client names as keys and with the value as another dict. The value dict is similar to the return value described in the KATCPResource.set_sampling_strategies docstring.

wait(*args, **kwargs)

Wait for sensor present on all group clients to satisfy a condition.

Parameters:

sensor_name : string

The name of the sensor to check

condition_or_value : obj or callable, or seq of objs or callables

If obj, sensor.value is compared with obj. If callable, condition_or_value(reading) is called, and must return True if its condition is satisfied. Since the reading is passed in, the value, status, timestamp or received_timestamp attributes can all be used in the check.

timeout : float or None

The total timeout in seconds (None means wait forever)

quorum : None or int or float

The number of clients that are required to satisfy the condition, as either an explicit integer or a float between 0 and 1 indicating a fraction of the total number of clients, rounded up. If None, this means that all clients are required (the default). Be warned that a value of 1.0 (float) indicates all clients while a value of 1 (int) indicates a single client...

max_grace_period : float or None

After a quorum or initial timeout is reached, wait up to this long in an attempt to get the rest of the clients to satisfy condition as well (achieving effectively a full quorum if all clients behave)

Returns:

This command returns a tornado Future that resolves with True when a :

quorum of clients satisfy the sensor condition, or False if a quorum :

is not reached after a given timeout period (including a grace period). :

Raises:

:class:`KATCPSensorError` :

If any of the sensors do not have a strategy set, or if the named sensor is not present

class katcp.resource_client.GroupRequest(group, name, description)

Bases: future.types.newobject.newobject

Couroutine wrapper around a specific KATCP request for a group of clients.

Each available KATCP request supported by group has an associated GroupRequest object in the hierarchy. This wrapper is mainly for interactive convenience. It provides the KATCP request help string as a docstring accessible via IPython’s question mark operator.

Methods

GroupRequest.next()
class katcp.resource_client.GroupResults

Bases: dict

The result of a group request.

This has a dictionary interface, with the client names as keys and the corresponding replies from each client as values. The replies are stored as KATCPReply objects, or are None for clients that did not support the request.

The result will evalue to a truthy value if all the requests succeeded, i.e.

if result:
    handle_success()
else:
    handle_failure()

should work as expected.

Methods

GroupResults.clear(...)
GroupResults.copy(() -> a shallow copy of D)
GroupResults.fromkeys(...) v defaults to None.
GroupResults.get((k[,d]) -> D[k] if k in D, ...)
GroupResults.has_key(...)
GroupResults.items(() -> list of D’s (key, ...)
GroupResults.iteritems(...)
GroupResults.iterkeys(...)
GroupResults.itervalues(...)
GroupResults.keys(() -> list of D’s keys)
GroupResults.pop((k[,d]) -> v, ...) If key is not found, d is returned if given, otherwise KeyError is raised
GroupResults.popitem(() -> (k, v), ...) 2-tuple; but raise KeyError if D is empty.
GroupResults.setdefault(...)
GroupResults.update(([E, ...) If E present and has a .keys() method, does: for k in E: D[k] = E[k]
GroupResults.values(() -> list of D’s values)
GroupResults.viewitems(...)
GroupResults.viewkeys(...)
GroupResults.viewvalues(...)
succeeded

True if katcp request succeeded on all clients.

class katcp.resource_client.KATCPClientResource(resource_spec, parent=None, logger=<logging.Logger object>)

Bases: katcp.resource.KATCPResource

Class managing a client connection to a single KATCP resource

Inspects the KATCP interface of the resources, exposing sensors and requests as per the katcp.resource.KATCPResource API. Can also operate without exposin

Methods

KATCPClientResource.inspecting_client_factory(...) Return an instance of ReplyWrappedInspectingClientAsync or similar
KATCPClientResource.is_active()
KATCPClientResource.is_connected() Indication of the connection state
KATCPClientResource.list_sensors([filter, ...]) List sensors available on this resource matching certain criteria.
KATCPClientResource.set_active(active)
KATCPClientResource.set_ioloop([ioloop]) Set the tornado ioloop to use
KATCPClientResource.set_sampling_strategies(...) Set a strategy for all sensors matching the filter, including unseen sensors The strategy should persist across sensor disconnect/reconnect.
KATCPClientResource.set_sampling_strategy(...) Set a strategy for a sensor even if it is not yet known.
KATCPClientResource.set_sensor_listener(...) Set a sensor listener for a sensor even if it is not yet known The listener registration should persist across sensor disconnect/reconnect.
KATCPClientResource.start() Start the client and connect
KATCPClientResource.stop()
KATCPClientResource.until_not_synced([timeout]) Convenience method to wait (with Future) until client is not synced
KATCPClientResource.until_state(state[, timeout]) Future that resolves when a certain client state is attained
KATCPClientResource.until_synced([timeout]) Convenience method to wait (with Future) until client is synced
KATCPClientResource.wait(*args, **kwargs) Wait for a sensor in this resource to satisfy a condition.
KATCPClientResource.wait_connected([timeout]) Future that resolves when the state is not ‘disconnected’.
MAX_LOOP_LATENCY = 0.03

When doing potentially tight loops in coroutines yield tornado.gen.moment after this much time. This is a suggestion for methods to use.

inspecting_client_factory(host, port, ioloop_set_to)

Return an instance of ReplyWrappedInspectingClientAsync or similar

Provided to ease testing. Dynamically overriding this method after instantiation but before start() is called allows for deep brain surgery. See katcp.fake_clients.fake_inspecting_client_factory

is_connected()

Indication of the connection state

Returns True if state is not “disconnected”, i.e “syncing” or “synced”

list_sensors(filter='', strategy=False, status='', use_python_identifiers=True, tuple=False, refresh=False)

List sensors available on this resource matching certain criteria.

Parameters:

filter : string, optional

Filter each returned sensor’s name against this regexp if specified. To ease the dichotomy between Python identifier names and actual sensor names, the default is to search on Python identifier names rather than KATCP sensor names, unless use_python_identifiers below is set to False. Note that the sensors of subordinate KATCPResource instances may have inconsistent names and Python identifiers, better to always search on Python identifiers in this case.

strategy : {False, True}, optional

Only list sensors with a set strategy if True

status : string, optional

Filter each returned sensor’s status against this regexp if given

use_python_identifiers : {True, False}, optional

Match on python identfiers even the the KATCP name is available.

tuple : {True, False}, optional, Default: False

Return backwards compatible tuple instead of SensorResultTuples

refresh : {True, False}, optional, Default: False

If set the sensor values will be refreshed with get_value before returning the results.

Returns:

sensors : list of SensorResultTuples, or list of tuples

List of matching sensors presented as named tuples. The object field is the KATCPSensor object associated with the sensor. Note that the name of the object may not match name if it originates from a subordinate device.

set_ioloop(ioloop=None)

Set the tornado ioloop to use

Defaults to tornado.ioloop.IOLoop.current() if set_ioloop() is not called or if ioloop=None. Must be called before start()

set_sampling_strategies(*args, **kwargs)

Set a strategy for all sensors matching the filter, including unseen sensors The strategy should persist across sensor disconnect/reconnect.

filter : str
Filter for sensor names
strategy_and_params : seq of str or str
As tuple contains (<strat_name>, [<strat_parm1>, ...]) where the strategy names and parameters are as defined by the KATCP spec. As str contains the same elements in space-separated form.
Returns:

done : tornado Future

Resolves when done

set_sampling_strategy(*args, **kwargs)

Set a strategy for a sensor even if it is not yet known. The strategy should persist across sensor disconnect/reconnect.

sensor_name : str
Name of the sensor
strategy_and_params : seq of str or str
As tuple contains (<strat_name>, [<strat_parm1>, ...]) where the strategy names and parameters are as defined by the KATCP spec. As str contains the same elements in space-separated form.
Returns:

done : tornado Future

Resolves when done

set_sensor_listener(*args, **kwargs)

Set a sensor listener for a sensor even if it is not yet known The listener registration should persist across sensor disconnect/reconnect.

sensor_name : str
Name of the sensor
listener : callable
Listening callable that will be registered on the named sensor when it becomes available. Callable as for KATCPSensor.register_listener()
start()

Start the client and connect

until_not_synced(timeout=None)

Convenience method to wait (with Future) until client is not synced

until_state(state, timeout=None)

Future that resolves when a certain client state is attained

Parameters:

state : str

Desired state, one of (“disconnected”, “syncing”, “synced”)

timeout: float :

Timeout for operation in seconds.

until_synced(timeout=None)

Convenience method to wait (with Future) until client is synced

wait_connected(timeout=None)

Future that resolves when the state is not ‘disconnected’.

class katcp.resource_client.KATCPClientResourceContainer(resources_spec, logger=<logging.Logger object>)

Bases: katcp.resource.KATCPResource

Class for containing multiple KATCPClientResource instances

Provides aggregate sensor and req attributes containing the union of all the sensors in requests in the contained resources. Names are prefixed with <resname>_, where <resname> is the name of the resource to which the sensor / request belongs except for aggregate sensors that starts with ‘agg_‘.

Methods

KATCPClientResourceContainer.add_child_resource_client(...) Add a resource client to the container and start the resource connection
KATCPClientResourceContainer.add_group(...) Add a new ClientGroup to container groups member.
KATCPClientResourceContainer.client_resource_factory(...) Return an instance of KATCPClientResource or similar
KATCPClientResourceContainer.is_active()
KATCPClientResourceContainer.is_connected() Indication of the connection state of all children
KATCPClientResourceContainer.list_sensors([...]) List sensors available on this resource matching certain criteria.
KATCPClientResourceContainer.set_active(active)
KATCPClientResourceContainer.set_ioloop([ioloop]) Set the tornado ioloop to use
KATCPClientResourceContainer.set_sampling_strategies(...) Set sampling strategies for filtered sensors - these sensors have to exsist
KATCPClientResourceContainer.set_sampling_strategy(...) Set sampling strategies for the specific sensor - this sensor has to exist
KATCPClientResourceContainer.set_sensor_listener(...) Set listener for the specific sensor - this sensor has to exsist
KATCPClientResourceContainer.start() Start and connect all the subordinate clients
KATCPClientResourceContainer.stop() Stop all child resources
KATCPClientResourceContainer.until_all_children_in_state(...) Return a tornado Future; resolves when all clients are in specified state
KATCPClientResourceContainer.until_any_child_in_state(state) Return a tornado Future; resolves when any client is in specified state
KATCPClientResourceContainer.until_not_synced(...) Return a tornado Future; resolves when any subordinate client is not synced
KATCPClientResourceContainer.until_synced(...) Return a tornado Future; resolves when all subordinate clients are synced
KATCPClientResourceContainer.wait(...[, timeout]) Wait for a sensor in this resource to satisfy a condition.
add_child_resource_client(res_name, res_spec)

Add a resource client to the container and start the resource connection

add_group(group_name, group_client_names)

Add a new ClientGroup to container groups member.

Add the group named group_name with sequence of client names to the container groups member. From there it will be wrapped appropriately in the higher-level thread-safe container.

client_resource_factory(res_spec, parent, logger)

Return an instance of KATCPClientResource or similar

Provided to ease testing. Overriding this method allows deep brain surgery. See katcp.fake_clients.fake_KATCP_client_resource_factory()

is_connected()

Indication of the connection state of all children

list_sensors(filter='', strategy=False, status='', use_python_identifiers=True, tuple=False, refresh=False)

List sensors available on this resource matching certain criteria.

Parameters:

filter : string, optional

Filter each returned sensor’s name against this regexp if specified. To ease the dichotomy between Python identifier names and actual sensor names, the default is to search on Python identifier names rather than KATCP sensor names, unless use_python_identifiers below is set to False. Note that the sensors of subordinate KATCPResource instances may have inconsistent names and Python identifiers, better to always search on Python identifiers in this case.

strategy : {False, True}, optional

Only list sensors with a set strategy if True

status : string, optional

Filter each returned sensor’s status against this regexp if given

use_python_identifiers : {True, False}, optional

Match on python identfiers even the the KATCP name is available.

tuple : {True, False}, optional, Default: False

Return backwards compatible tuple instead of SensorResultTuples

refresh : {True, False}, optional, Default: False

If set the sensor values will be refreshed with get_value before returning the results.

Returns:

sensors : list of SensorResultTuples, or list of tuples

List of matching sensors presented as named tuples. The object field is the KATCPSensor object associated with the sensor. Note that the name of the object may not match name if it originates from a subordinate device.

set_ioloop(ioloop=None)

Set the tornado ioloop to use

Defaults to tornado.ioloop.IOLoop.current() if set_ioloop() is not called or if ioloop=None. Must be called before start()

set_sampling_strategies(*args, **kwargs)

Set sampling strategies for filtered sensors - these sensors have to exsist

set_sampling_strategy(*args, **kwargs)

Set sampling strategies for the specific sensor - this sensor has to exist

set_sensor_listener(*args, **kwargs)

Set listener for the specific sensor - this sensor has to exsist

start()

Start and connect all the subordinate clients

stop()

Stop all child resources

until_all_children_in_state(*args, **kwargs)

Return a tornado Future; resolves when all clients are in specified state

until_any_child_in_state(state, timeout=None)

Return a tornado Future; resolves when any client is in specified state

until_not_synced(*args, **kwargs)

Return a tornado Future; resolves when any subordinate client is not synced

until_synced(*args, **kwargs)

Return a tornado Future; resolves when all subordinate clients are synced

wait(sensor_name, condition_or_value, timeout=5)

Wait for a sensor in this resource to satisfy a condition.

Parameters:

sensor_name : string

The name of the sensor to check

condition_or_value : obj or callable, or seq of objs or callables

If obj, sensor.value is compared with obj. If callable, condition_or_value(reading) is called, and must return True if its condition is satisfied. Since the reading is passed in, the value, status, timestamp or received_timestamp attributes can all be used in the check.

timeout : float or None

The timeout in seconds (None means wait forever)

Returns:

This command returns a tornado Future that resolves with True when the :

sensor value satisfies the condition, or False if the condition is :

still not satisfied after a given timeout period. :

Raises:

:class:`KATCPSensorError` :

If the sensor does not have a strategy set, or if the named sensor is not present

class katcp.resource_client.KATCPClientResourceRequest(request_description, client, is_active=<function <lambda>>)

Bases: katcp.resource.KATCPRequest

Callable wrapper around a KATCP request

Methods

KATCPClientResourceRequest.is_active() True if resource for this request is active
KATCPClientResourceRequest.issue_request(...) Issue the wrapped request to the server.
issue_request(*args, **kwargs)

Issue the wrapped request to the server.

Parameters:

*args : list of objects

Arguments to pass on to the request.

Keyword Arguments:
 

timeout : float or None, optional

Timeout after this amount of seconds (keyword argument).

mid : None or int, optional

Message identifier to use for the request message. If None, use either auto-incrementing value or no mid depending on the KATCP protocol version (mid’s were only introduced with KATCP v5) and the value of the use_mid argument. Defaults to None.

use_mid : bool

Use a mid for the request if True.

Returns:

future object that resolves with an :class:`katcp.resource.KATCPReply` :

instance :

class katcp.resource_client.KATCPClientResourceSensorsManager(inspecting_client, resource_name, logger=<logging.Logger object>)

Bases: future.types.newobject.newobject

Implementation of KATSensorsManager ABC for a directly-connected client

Assumes that all methods are called from the same ioloop context

Methods

KATCPClientResourceSensorsManager.get_sampling_strategy(...) Get the current sampling strategy for the named sensor
KATCPClientResourceSensorsManager.next()
KATCPClientResourceSensorsManager.poll_sensor(...) Poll sensor and arrange for sensor object to be updated
KATCPClientResourceSensorsManager.reapply_sampling_strategies(...) Reapply all sensor strategies using cached values
KATCPClientResourceSensorsManager.sensor_factory(...)
KATCPClientResourceSensorsManager.set_sampling_strategy(...) Set the sampling strategy for the named sensor
get_sampling_strategy(sensor_name)

Get the current sampling strategy for the named sensor

Parameters:

sensor_name : str

Name of the sensor

Returns:

strategy : tuple of str

contains (<strat_name>, [<strat_parm1>, ...]) where the strategy names and parameters are as defined by the KATCP spec

poll_sensor(*args, **kwargs)

Poll sensor and arrange for sensor object to be updated

reapply_sampling_strategies(*args, **kwargs)

Reapply all sensor strategies using cached values

set_sampling_strategy(*args, **kwargs)

Set the sampling strategy for the named sensor

Parameters:

sensor_name : str

Name of the sensor

strategy_and_params : seq of str or str

As tuple contains (<strat_name>, [<strat_parm1>, ...]) where the strategy names and parameters are as defined by the KATCP spec. As str contains the same elements in space-separated form.

Returns:

sensor_strategy : tuple

(success, info) with

success : bool

True if setting succeeded for this sensor, else False

info : tuple

Normalibed sensor strategy and parameters as tuple if success == True else, sys.exc_info() tuple for the error that occured.

class katcp.resource_client.ReplyWrappedInspectingClientAsync(host, port, ioloop=None, initial_inspection=None, auto_reconnect=True, logger=<logging.Logger object>)

Bases: katcp.inspecting_client.InspectingClientAsync

Adds wrapped_request() method that wraps reply in a KATCPReply

Methods

ReplyWrappedInspectingClientAsync.close()
ReplyWrappedInspectingClientAsync.connect(...) Connect to KATCP interface, starting what is needed
ReplyWrappedInspectingClientAsync.future_check_request(...) Check if the request exists.
ReplyWrappedInspectingClientAsync.future_check_sensor(...) Check if the sensor exists.
ReplyWrappedInspectingClientAsync.future_get_request(...) Get the request object.
ReplyWrappedInspectingClientAsync.future_get_sensor(...) Get the sensor object.
ReplyWrappedInspectingClientAsync.handle_sensor_value() Handle #sensor-value informs just like #sensor-status informs
ReplyWrappedInspectingClientAsync.inform_hook_client_factory(...) Return an instance of _InformHookDeviceClient or similar
ReplyWrappedInspectingClientAsync.inspect(...) Inspect device requests and sensors, update model
ReplyWrappedInspectingClientAsync.inspect_requests(...) Inspect all or one requests on the device.
ReplyWrappedInspectingClientAsync.inspect_sensors(...) Inspect all or one sensor on the device.
ReplyWrappedInspectingClientAsync.is_connected() Connection status.
ReplyWrappedInspectingClientAsync.join([timeout])
ReplyWrappedInspectingClientAsync.preset_protocol_flags(...) Preset server protocol flags.
ReplyWrappedInspectingClientAsync.reply_wrapper(x)
ReplyWrappedInspectingClientAsync.request_factory alias of Request
ReplyWrappedInspectingClientAsync.sensor_factory alias of Sensor
ReplyWrappedInspectingClientAsync.set_ioloop(ioloop)
ReplyWrappedInspectingClientAsync.set_state_callback(cb) Set user callback for state changes
ReplyWrappedInspectingClientAsync.simple_request(...) Create and send a request to the server.
ReplyWrappedInspectingClientAsync.start([...]) Note: always call stop() when you are done with the container to make sure the container cleans up correctly.
ReplyWrappedInspectingClientAsync.stop([timeout])
ReplyWrappedInspectingClientAsync.until_connected([...])
ReplyWrappedInspectingClientAsync.until_data_synced([...])
ReplyWrappedInspectingClientAsync.until_not_synced([...])
ReplyWrappedInspectingClientAsync.until_state(...) Wait until state is desired_state, InspectingClientStateType instance
ReplyWrappedInspectingClientAsync.until_synced([...])
ReplyWrappedInspectingClientAsync.update_sensor(...)
ReplyWrappedInspectingClientAsync.wrapped_request(...) Create and send a request to the server.
wrapped_request(request, *args, **kwargs)

Create and send a request to the server.

This method implements a very small subset of the options possible to send an request. It is provided as a shortcut to sending a simple wrapped request.

Parameters:

request : str

The request to call.

*args : list of objects

Arguments to pass on to the request.

Keyword Arguments:
 

timeout : float or None, optional

Timeout after this amount of seconds (keyword argument).

mid : None or int, optional

Message identifier to use for the request message. If None, use either auto-incrementing value or no mid depending on the KATCP protocol version (mid’s were only introduced with KATCP v5) and the value of the use_mid argument. Defaults to None.

use_mid : bool

Use a mid for the request if True.

Returns:

future object that resolves with the :

:meth:`katcp.client.DeviceClient.future_request` response wrapped in :

self.reply_wrapper :

class katcp.resource_client.ThreadSafeKATCPClientGroupWrapper(subject, ioloop_wrapper)

Bases: katcp.ioloop_manager.ThreadSafeMethodAttrWrapper

Thread safe wrapper for ClientGroup

Methods

ThreadSafeKATCPClientGroupWrapper.next()
class katcp.resource_client.ThreadSafeKATCPClientResourceWrapper(subject, ioloop_wrapper)

Bases: katcp.ioloop_manager.ThreadSafeMethodAttrWrapper

Should work with both KATCPClientResource or KATCPClientResourceContainer

Methods

ThreadSafeKATCPClientResourceWrapper.next()
katcp.resource_client.list_sensors(*args, **kwargs)

Helper for implementing katcp.resource.KATCPResource.list_sensors()

Parameters:

sensor_items : tuple of sensor-item tuples

As would be returned the items() method of a dict containing KATCPSensor objects keyed by Python-identifiers.

parent_class: KATCPClientResource or KATCPClientResourceContainer :

Is used for prefix calculation

Rest of parameters as for :meth:`katcp.resource.KATCPResource.list_sensors` :

katcp.resource_client.monitor_resource_sync_state(*args, **kwargs)

Coroutine that monitors a KATCPResource’s sync state.

Calls callback(True/False) whenever the resource becomes synced or unsynced. Will always do an initial callback(False) call. Exits without calling callback() if exit_event is set

katcp.resource_client.transform_future(transformation, future)

Returns a new future that will resolve with a transformed value

Takes the resolution value of future and applies transformation(*future.result()) to it before setting the result of the new future with the transformed value. If future() resolves with an exception, it is passed through to the new future.

Assumes future is a tornado Future.