API¶
Client¶
-
class
happi.
Client
(database=None, **kwargs)¶ The client to control the contents of the Happi Database
- Parameters
database (happi.backends.Backend) – A already instantiated backend
kwargs – Passed to the db_type backend
- Raises
DatabaseError: – Raised if the Client fails to instantiate the Database
-
add_device
(device)¶ Add a new device into the database
- Parameters
device (
HappiItem
) – The device to store in the database- Raises
EntryError: – If all of the mandatory information for the device has not been specified or there is already a device with that
id
in the database
-
property
all_devices
¶ A list of all contained devices
-
property
all_items
¶ A list of all contained devices
-
choices_for_field
(field)¶ List all choices for a given field
- Parameters
field (string) – search field to list all possible choices for i.e ‘beamline’, ‘name’, ‘z’, ‘prefix’, etc.
- Raises
SearchError – If no devices in the database have an entry for the given field
- Returns
field_choices – list of choices for a given field that are in the database
- Return type
-
create_device
(device_cls, **kwargs)¶ Create a new device
- Parameters
device_cls (
HappiItem
or name of class) – The Device HappiItem to instantiatekwargs – Information to pass through to the device, upon initialization
- Returns
An instantiated version of the device
- Return type
device
- Raises
TypeError: – If the provided class is not a subclass of
HappiItem
Example
device = client.create_device(Device, name='my_device' ...) device = client.create_device('Device', name='my_device',...)
-
export
(path=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, sep='\t', attrs=None)¶ Export the contents of the database into a text file
- Parameters
path (File Handle) – File-like object to save text file
sep (str) – Separator to place inbetween columns of information
attrs (iterable) – Attributes to include, these will be a list of values
-
static
find_config
()¶ Search for a
happi
configuration fileWe first query the environment variable
$HAPPI_CFG
to see if this points to a specific configuration file. If this is not present, the variable set by$XDG_CONFIG_HOME
or if that is not set~/.config
- Returns
path – Absolute path to configuration file
- Return type
- Raises
EnvironmentError: – If no configuration file can be found by the methodology detailed above
-
find_device
(**post)¶ Used to query the database for an individual HappiItem
If multiple devices are found, only the first is returned
- Parameters
post – Information to pertinent to the device
- Raises
SearchError – If no match for the given information is found
- Returns
device – A device that matches the characteristics given
- Return type
-
find_document
(**kwargs)¶ Load a device document from the database
If multiple matches are found, a single document will be returned to the user. How the database will choose to select this device is based on each individual implementation
- Parameters
kwargs – Add information to locate the device in keyword pairs
- Returns
document – A dict that matches the specified information.
- Return type
- Raises
SearchError: – If no document with the given information is found
See also
-
classmethod
from_config
(cfg=None)¶ Create a client from a configuration file specification
Configuration files looking something along the lines of:
[DEFAULT] path=path/to/my/db.json
All key value pairs will be passed directly into backend construction with the exception of the key
backend
which can be used to specify a specific type of backend if this differs from the configured default.- Parameters
cfg (str, optional) – Path to a configuration file. If not entered,
find_config()
will be use.
-
load_device
(use_cache=True, **post)¶ Find a device in the database and instantiate it
Essentially a shortcut for:
container = client.find_device(name='...') device = from_container(container)
- Parameters
post – Passed to
Client.find_device()
use_cache (bool, optional) – Choice to use a cached device. See
from_container()
for more information
- Returns
Instantiated object
- Return type
obj
-
remove_device
(device)¶ Remove a device from the database
- Parameters
device (
HappiItem
) – HappiItem to be removed from the database
-
search
(**kwargs)¶ Search the database for a device or devices
- Parameters
**kwargs – Information to filter through the database structured as key, value pairs for the desired pieces of EntryInfo
- Returns
res – The search results
- Return type
list of SearchResult
Example
gate_valves = client.search(type='Valve') hxr_valves = client.search(type='Valve', beamline='HXR')
-
search_range
(key, start, end=None, **kwargs)¶ Search the database for a device or devices
- Parameters
- Returns
- Return type
Either a list of devices or dictionaries
Example
gate_valves = client.search_range('z', 0, 100, type='Valve') hxr_valves = client.search_range('z', 0, 100, type='Valve', beamline='HXR')
-
search_regex
(flags=<RegexFlag.IGNORECASE: 2>, **kwargs)¶ Search the database for a device or devices
- Parameters
flags (int, optional) – Defaulting to
re.IGNORECASE
, these flags are used for the regular expressions passed in.**kwargs – Information to filter through the database structured as key, value pairs for the desired pieces of EntryInfo. Every value is allowed to contain a Python regular expression.
- Returns
- Return type
Either a list of devices or dictionaries
Example
gate_valves = client.search_regex(beamline='Valve.*') three_valves = client.search_regex(_id='VALVE[123]')
-
class
happi.
SearchResult
(client, device)¶ A single search result from
Client.search
- This result can be keyed for metadata as in::
result[‘name’]
- The HappiItem can be readily retrieved::
result.item
- Or the object may be instantiated::
result.get()
-
item
¶ The container
- Type
-
get
(k[, d]) → D[k] if k in D, else d. d defaults to None.¶
Backends¶
-
class
happi.backends.core.
_Backend
¶ Base class for backend database
-
property
all_devices
¶ List of all device sub-dictionaries
-
delete
(_id)¶ Delete a device instance from the database
- Parameters
_id (str) – ID of device
- Raises
PermissionError: – If the write operation fails due to issues with permissions
-
find
(multiples=False, **kwargs)¶ Find an instance or instances that matches the search criteria
- Parameters
multiples (bool) – Find a single result or all results matching the provided information
kwargs – Requested information
-
save
(_id, post, insert=True)¶ Save information to the database
- Parameters
- Raises
DuplicateError: – If insert is True, but there is already a device with the provided _id
SearchError: – If insert is False, but there is no device with the provided _id
PermissionError: – If the write operation fails due to issues with permissions
-
property
|
Abstraction for MongoDB backend |
|
JSON database |
|
Questionniare Backend |
Containers¶
Built-ins¶
-
class
happi.
HappiItem
(**kwargs)¶ The smallest description of an object that can be entered in
happi
The class does not need to be intialized with any specific piece of information except a name, but all of the attributes listed by
HappiItem.info_names
can be used to assign values toEntryInfo
upon initialization. Pieces of information that are deemed mandatory by the class must be filled in before the device is loaded into the database. Seemandatory_info
to see which attributes are neccesary.Additional metadata can be given to the device in the form of keywords on initialization, this information is kept in the
extraneous
attribute, and will be saved in to the database as long as it does not clash with an existing piece of metadata that the client uses to organize devices.-
extraneous
¶ Storage for information supplied during initialization that does not correspond to a specific EntryInfo
- Type
- Raises
EntryError: – If a piece of information supplied at startup is of the incorrect type
ContainerError: – If one of the pieces of
EntryInfo
has a default value of the incorrect type
Example
d = HappiItem(name = 'my_device', # Alias name for device note = 'Example', # Piece of arbitrary metadata )
-
active
¶ Whether the instance is actively deployed
-
args
¶ Arguments to pass to device_class
-
device_class
¶ Python class that represents the instance
-
documentation
¶ Relevant documentation for the instance
-
kwargs
¶ Keyword arguments to pass to device_class
-
name
¶ Shorthand Python-valid name for the Python instance
-
post
()¶ Create a document to be loaded into the happi database
- Returns
post – Dictionary of all contained information
- Return type
-
save
()¶ Overwritten when the device instance is loaded from the client
-
show_info
(handle=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>)¶ Show the device instance information in a PrettyTable
- Parameters
handle (file-like, optional) – Option to write to a file-like object
-
Loading¶
-
happi.
from_container
(device, attach_md=True, use_cache=True, threaded=False)¶ Load an object (or “device”) from a happi container.
The container is queried for the device_class, args and kwargs. Then if the associated package is not already loaded it is imported. The specified class is then instantiated with the given args and kwargs provided.
This function does not attempt to catch exceptions either during module imports or device creation. If you would like a series of independent devices to be loaded use
load_devices()
.By default, the instantiated object has the original container added on as
.md
. This allows applications to utilize additional metadata information that may not be included in the basic class constructor. On later calls, the container you request is checked against this stored metadata. If a discrepancy is found the object is forced to reload, not retrieved from the cache.- Parameters
device (happi.Device) –
attach_md (bool, optional) – Attach the container to the instantiated object as md
use_cache (bool, optional) – When devices are loaded they are stored in the
happi.cache
dictionary. This means that repeated attempts to load the device will return the same object. This prevents unnecessary EPICS connections from being initialized in the same process. If a new object is needed, set use_cache to False and a new object will be created, overriding the current cached object. An object with matching name and differing metadata will always return a new instantiation of the device.threaded (bool, optional) – Set this to True when calling inside a thread.
- Returns
obj
- Return type
happi.Device.device_class
-
happi.
load_devices
(*devices, pprint=False, namespace=None, use_cache=True, threaded=False, post_load=None, **kwargs)¶ Load a series of devices into a namespace
- Parameters
*devices – List of happi containers to load
pprint (bool, optional) – Print results of device loads
namespace (object, optional) – Namespace to collect loaded devices in. By default this will be a
types.SimpleNamespace
use_cache (bool, optional) – If set to
False
, we’ll ignore the cache and always make new devices.threaded (bool, optional) – Set to True to create each device in a background thread. Note that this assumes that no two devices provided are the same. You are not guaranteed to load from the cache correctly if you ask for the same device to be loaded twice in the same threaded load.
post_load (function, optional) – Function of one argument to run on each device after instantiation. This is your opportunity to check for good device health during the threaded load.
kwargs – Are passed to
from_container()