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 Qt Client.

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.

asyncio Client

The asyncio client Context API is simllar to the thread Context, with the get, put, rpc methods become async.

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

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

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

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

  • unwrap (dict) – Legacy Automatic Value unwrapping.

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.

The “pva” provider understands the following keys:

  • EPICS_PVA_ADDR_LIST

  • EPICS_PVA_AUTO_ADDR_LIST

  • EPICS_PVA_SERVER_PORT

  • EPICS_PVA_BROADCAST_PORT

Timeout and Cancellation

All coroutines/Futures returned by Context methods can be cancelled. The methods of Context do not directly implement a timeout. Instead asyncio.wait_for() should be used. It is suggested perform one overall timeout at a high level rather than multiple timeouts on low-level operations.

@timesout()
async def dostuff(ctxt):
    await ctxt.put('msg', 'Working')
    A, B = await ctxt.get(['foo', 'bar'])
    await ctxt.put('bar', A+B, wait=True)
    await ctxt.put('msg', 'Done')

async def exec():
    with Context('pva') as ctxt:
        await dostuff(ctxt, timeout=5)
name
close()[source]
async get(name, request=None)[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.

Returns:

A p4p.Value, 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.

with Context('pva') as ctxt:
    V    = await ctxt.get('pv:name')
    A, B = await ctxt.get(['pv:1', 'pv:2'])
async put(name, values, request=None, 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.

  • 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.

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.

with Context('pva') as ctxt:
    await ctxt.put('pv:name', 5.0)
    await ctxt.put(['pv:1', 'pv:2'], [1.0, 2.0])
    await 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) Subscription[source]

Create a callback 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 called with instances of Exception. Specifically: Disconnected , RemoteError, or Cancelled

Returns:

a Subscription instance

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

async rpc(name, value, request=None)[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.

Returns:

A Value. Subject to Automatic Value unwrapping.

For example:

uri = NTURI(['A','B'])
with Context('pva') as ctxt:
    result = await ctxt.rpc('pv:name:add', uri.wrap('pv:name:add', 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 or Value, it is assumed to be a plain value and an attempt is made to store it in ‘.value’ field.

static providers()[source]
disconnect(name=None)[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]

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().

class p4p.client.Qt.Context(provider, conf=None, useenv=True)[source]

PyQt aware Context. Methods in the class give notification of completion/update through Qt signals.

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.

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

  • unwrap (dict) – Legacy Automatic Value unwrapping.

  • QObject (parent) – Parent for QObjects created through this Context.

name
close()[source]
put(name, value, slot=None, request=None, timeout=5.0, process=None, wait=None, get=True)[source]

Write a new value to a single PV.

Returns an Operation instance which will emit either a success and error signal. If the slot argument is provided, this will be connected in a race free way.

The slot function will receive a python object which is either None (Success) or an Exception.

Note that the returned Operation will also be stored internally by the Context. So the caller is not required to store it as well. This internal storage will only keep the most recent put() Operation for each PV name. A previous incomplete put() will be cancelled if/when put() is called again.

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.

  • slot – A callable object, such as a bound method, which can be passed to QObject.connect()

  • timeout (float) – Operation timeout in seconds

  • 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.

monitor(name, slot, request=None, limitHz=10.0)[source]

Request subscription to named PV

Request notification to the provided slot when a PV is updated. Subscriptions are managed by an internal cache, so than multiple calls to monitor() with the same PV name may be satisfied through a single subscription.

limitHz, which must be provided, puts an upper limit on the rate at which the update signal will be emitted. Some update will be dropped in the PV updates more frequently. Reduction is done by discarding the second to last update. eg. It is guaranteed that the last update (present value) in the burst will be delivered.

Parameters:
  • name (str) – PV name string

  • cb (callable) – Processing callback

  • slot – A callable object, such as a bound method, which can be passed to QObject.connect()

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

  • float (limitHz) – Maximum rate at which signals will be emitted. In signals per second.

Returns:

a MCache instance

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

Perform a Remote Procedure Call (RPC) operation

Returns an Operation instance which will emit either a success and error signal to the provided slot. This Operation instance must be stored by the caller or it will be implicitly cancelled.

The slot function will receive a python object which is either a Value or an Exception.

Parameters:
  • name (str) – PV name string

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

  • slot – A callable object, such as a bound method, which can be passed to QObject.connect()

  • 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:

An Operation

static providers()[source]
disconnect(name=None)[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]