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

list

create_device(device_cls, **kwargs)

Create a new device

Parameters
  • device_cls (HappiItem or name of class) – The Device HappiItem to instantiate

  • kwargs – 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 file

We 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

str

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

HappiItem

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

dict

Raises

SearchError: – If no document with the given information is found

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
  • key (str) – Database key to search

  • start (float, optional) – Minimum beamline position to include devices

  • end (float, optional) – Maximum beamline position to include devices

  • **kwargs – Information to filter through the database structured as key, value pairs for the desired pieces of EntryInfo

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]')
validate()

Validate all of the devices in the database by attempting to initialize them and asserting their mandatory information is present. Information is written to the logger

Returns

ids – List of device ids that have failed verification

Return type

list

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

happi.HappiItem

metadata

The HappiItem metadata

Type

dict

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
  • _id (str) – ID of device

  • post (dict) – Information to place in database

  • insert (bool, optional) – Whether or not this a new device to the database

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

happi.backends.mongo_db.MongoBackend([host, …])

Abstraction for MongoDB backend

happi.backends.json_db.JSONBackend(path[, …])

JSON database

happi.backends.qs_db.QSBackend(expname, *[, …])

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 to EntryInfo upon initialization. Pieces of information that are deemed mandatory by the class must be filled in before the device is loaded into the database. See mandatory_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.

entry_info

A list of all the EntryInfo associated with the device

Type

list

extraneous

Storage for information supplied during initialization that does not correspond to a specific EntryInfo

Type

dict

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

dict

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

class happi.OphydItem(**kwargs)
args

Arguments to pass to device_class

kwargs

Keyword arguments to pass to device_class

prefix

A base PV for all related records

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

Registry

class happi.containers.HappiRegistry(*args, **kwargs)