Client API

This module provides Context for use in interactive and/or multi-threaded environment. Most methods will block the calling thread until a return is available, or an error occurs.

Alternatives to p4p.client.thread.Context are provided p4p.client.cothread.Context, p4p.client.asyncio.Context, and p4p.client.Qt.Context. These differ in how blocking for I/O operation is performed, and the environment in which Monitor callbacks are run.

Note that p4p.client.Qt.Context behaves differently from the others in some respects. This is described in qtclient.

Usage

Start by creating a client Context.

>>> from p4p.client.thread import Context
>>> Context.providers()
['pva', ....]
>>> ctxt = Context('pva')

Note

The default network configuration taken from the process environment may be overridden by passing ‘conf=’ to the Context class constructor.

See What is PVAccess? for background on PVAccess protocol.

Get/Put

Get and Put operations can be performed on single PVs or a list of PVs.

>>> V = ctxt.get('pv:name')
>>> A, B = ctxt.get(['pv:1', 'pv:2'])
>>> ctxt.put('pv:name', 5)
>>> ctxt.put('pv:name', {'value': 5}) # equivalent to previous
>>> ctxt.put('pv:name', {'field_1.value': 5, 'field_2.value': 5}) # put to multiple fields

By default the values returned by Context.get() are subject to Automatic Value unwrapping.

Monitor

Unlike get/put/rpc, the Context.monitor() method does not block. Instead it accepts a callback function which is called with each new Value, or Exception.

def cb(V):
       print 'New value', V
sub = ctxt.monitor('pv:name', cb)
time.sleep(10) # arbitrary wait
sub.close()

The monitor method returns a Subscription which has a close method to end the subscription.

By default the values passed to monitor callbacks are subject to Automatic Value unwrapping.

p4p.client.thread.Context Runs callbacks in a worker thread pool.

p4p.client.cothread.Context Runs callbacks in a per-subscription cothread.

p4p.client.asyncio.Context Runs callbacks in a per-subscription coroutine.

In all cases it is safe for a callback to block/yield. Subsequent updates for a Subscription will not be delivered until the current callback has completed. However, updates for other Subscriptions may be delivered.

RPC

See RPC Server Helpers.

API Reference

class p4p.client.thread.Context(provider, conf=None, useenv=True)[source]
Parameters:
  • provider (str) – A Provider name. Try “pva” or run Context.providers() for a complete list.

  • conf (dict) – Configuration to pass to provider. Depends on provider selected.

  • useenv (bool) – Allow the provider to use configuration from the process environment.

  • workers (int) – Size of thread pool in which monitor callbacks are run. Default is 4

  • maxsize (int) – Size of internal work queue used for monitor callbacks. Default is unlimited

  • nt (dict) – Controls Automatic Value unwrapping. None uses defaults. Set False to disable

  • unwrap (dict) – Legacy Automatic Value unwrapping.

  • queue (WorkQueue) – A work queue through which monitor callbacks are dispatched.

The methods of this Context will block the calling thread until completion or timeout

The meaning, and allowed keys, of the configuration dictionary depend on the provider. conf= will override values taken from the process environment. Pass useenv=False to ensure that environment variables are completely ignored.

The “pva” provider understands the following keys:

  • EPICS_PVA_ADDR_LIST

  • EPICS_PVA_AUTO_ADDR_LIST

  • EPICS_PVA_SERVER_PORT

  • EPICS_PVA_BROADCAST_PORT

name = ''

Provider name string

close()[source]

Force close all Channels and cancel all Operations

get(name, request=None, timeout=5.0, throw=True)[source]

Fetch current value of some number of PVs.

Parameters:
  • name – A single name string or list of name strings

  • request – A p4p.Value or string to qualify this request, or None to use a default.

  • timeout (float) – Operation timeout in seconds

  • throw (bool) – When true, operation error throws an exception. If False then the Exception is returned instead of the Value

Returns:

A p4p.Value or Exception, or list of same. Subject to Automatic Value unwrapping.

When invoked with a single name then returns is a single value. When invoked with a list of name, then returns a list of values

>>> ctxt = Context('pva')
>>> V = ctxt.get('pv:name')
>>> A, B = ctxt.get(['pv:1', 'pv:2'])
>>>
put(name, values, request=None, timeout=5.0, throw=True, process=None, wait=None, get=True)[source]

Write a new value of some number of PVs.

Parameters:
  • name – A single name string or list of name strings

  • values – A single value, a list of values, a dict, a Value. May be modified by the constructor nt= argument.

  • request – A p4p.Value or string to qualify this request, or None to use a default.

  • timeout (float) – Operation timeout in seconds

  • throw (bool) – When true, operation error throws an exception. If False then the Exception is returned instead of the Value

  • process (str) – Control remote processing. May be ‘true’, ‘false’, ‘passive’, or None.

  • wait (bool) – Wait for all server processing to complete.

  • get (bool) – Whether to do a Get before the Put. If True then the value passed to the builder callable will be initialized with recent PV values. eg. use this with NTEnum to find the enumeration list.

Returns:

A None or Exception, or list of same

When invoked with a single name then returns is a single value. When invoked with a list of name, then returns a list of values

If ‘wait’ or ‘process’ is specified, then ‘request’ must be omitted or None.

>>> ctxt = Context('pva')
>>> ctxt.put('pv:name', 5.0)
>>> ctxt.put(['pv:1', 'pv:2'], [1.0, 2.0])
>>> ctxt.put('pv:name', {'value':5})
>>>

The provided value(s) will be automatically coerced to the target type. If this is not possible then an Exception is raised/returned.

Unless the provided value is a dict, it is assumed to be a plain value and an attempt is made to store it in ‘.value’ field.

monitor(name, cb, request=None, notify_disconnect=False, queue=None)[source]

Create a subscription.

Parameters:
  • name (str) – PV name string

  • cb (callable) – Processing callback

  • request – A p4p.Value or string to qualify this request, or None to use a default.

  • notify_disconnect (bool) – In additional to Values, the callback may also be call with instances of Exception. Specifically: Disconnected , RemoteError, or Cancelled

  • queue (WorkQueue) – A work queue through which monitor callbacks are dispatched.

Returns:

a Subscription instance

The callable will be invoked with one argument which is either.

rpc(name, value, request=None, timeout=5.0, throw=True)[source]

Perform a Remote Procedure Call (RPC) operation

Parameters:
  • name (str) – PV name string

  • value (Value) – Arguments. Must be Value instance

  • request – A p4p.Value or string to qualify this request, or None to use a default.

  • timeout (float) – Operation timeout in seconds

  • throw (bool) – When true, operation error throws an exception. If False then the Exception is returned instead of the Value

Returns:

A Value or Exception. Subject to Automatic Value unwrapping.

>>> ctxt = Context('pva')
>>> ctxt.rpc('pv:name:add', {'A':5, 'B'; 6})
>>>

The provided value(s) will be automatically coerced to the target type. If this is not possible then an Exception is raised/returned.

Unless the provided value is a dict, it is assumed to be a plain value and an attempt is made to store it in ‘.value’ field.

static providers()[source]
disconnect(*args, **kws)[source]

Clear internal Channel cache, allowing currently unused channels to be implictly closed.

Parameters:

name (str) – None, to clear the entire cache, or a name string to clear only a certain entry.

static set_debug(lvl)[source]
class p4p.client.thread.Subscription(ctxt, name, cb, notify_disconnect=False, queue=None)[source]

An active subscription.

Returned by Context.monitor.

close()[source]

Close subscription.

class p4p.client.thread.Disconnected(msg=None)

Channel becomes disconected.

class p4p.client.thread.RemoteError

Thrown with an error message which has been sent by a server to its remote client

class p4p.client.thread.Cancelled(msg=None)

Cancelled from client end.

class p4p.client.thread.Finished(msg=None)

Special case of Disconnected when a Subscription has received all updates it will ever receive.

class p4p.client.thread.TimeoutError

Timeout expired.

Qt Client

p4p.client.Qt.Context exists to bring the results of network operations into a Qt event loop. This is done through the native signals and slots mechanism.

Use requires the optional dependency qtpy package.

This dependency is expressed as an extras_require= of “qt”. It may be depended upon accordingly as “p4p[qt]”.

p4p.client.Qt.Context differs from the other Context classes in several respects.

  • Each Context attempts to minimize the number of subscriptions to each named PV. Multiple calls to monitor() will attempt to share this subscription if possible (subject to request argument).

  • All monitor() calls must express a desired maximum update rate limit through the limitHz argument.

  • As a convienence, the objects returned by put() and monitor() do not have to be stored by the caller. The internal references kept by the Context may be cleared through the disconnect() method. This cache extends to a single put and a single monitor subscription per PV. So eg. initiating a put() to a PV will implicitly cancel a previous in-progress put().