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
- 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.
A p4p.Value (Subject to Automatic Value unwrapping)
A sub-class of Exception (Disconnected , RemoteError, or Cancelled)
- 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.
- class p4p.client.thread.Subscription(ctxt, name, cb, notify_disconnect=False, queue=None)[source]¶
An active subscription.
Returned by
Context.monitor
.
- 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().