Skip to content

Object creation

As BLISS is based on the Python language, objects can simply be created by instantiating the object class imported from a given module and by passing the correct arguments. This can be done directly in a BLISS session or in a script using BLISS as a python library.

Example

from bliss.controllers.foo import FooController
foo = FooController({'name':'foo', 'fooparam':69})

However, creating objects this way can be quickly tedious, unsafe and not user friendly. For this reasons BLISS provides tools to manage objects through YAML configuration files.

Object YAML declaration

In BLISS, users can declare named objects via a YAML configuration file.

Objects configuration files are hosted and served by a BEACON server.

Example of a YAML configuration file

- name: foo              # the object name
  class: FooController   # the object class
  module: foo_module     # the module where the object class can be found
  plugin: generic        # the plugin responsible to the instantiation of this kind of object
  fooparam: 69           # a parameter used by this object

Note

The name of an object must be unique among all the YAML configuration files served by one BEACON server.

Object instantiation

To instantiate an object declared in a YAML configuration file, use config.get(<object_name>) where <object_name> is the name of the object (string).

Example

from bliss.config.static import get_config
config = get_config()
foo = config.get("foo")

Note

  • In a BLISS shell config already exist and the two first lines in the example above can be omitted.
  • config.get('foo') creates the object only once. If already existing, it just returns the object instance.

Configuration plugins

Every object in the configuration is associated with a configuration plugin. The role of the configuration plugin is to instantiate the object from its YAML configuration. The plugin used by an object is defined by the plugin key found in the object’s configuration.

Example

name: foo
class: Foo
plugin: generic

BLISS implements the following plugins:

  • default: converts YAML configuration into a Python dictionary
  • session: designed for Session objects (handles measurement groups)
  • generic: designed for most objects (handles subitems)
  • bliss: transforms references into object attributes (does not handle subitems).

To instantiate an object from its YAML configuration, BLISS needs to find and import the class of that object. To do so, plugins are looking for special keys inside the object’s YAML configuration.

Key class

This special key indicates the name of the class that should be used for an object.

Key plugin

This special key indicates the plugin that should take care of the object instantiation.

If the plugin key is not found in the object’s configuration, BLISS looks for that key at upper levels in the configuration file or in the configuration tree. If no plugin key can be found the default plugin is used. A local definition of the plugin overrides others above.

Sharing plugin key among multiple objects

plugin: generic
controllers:
  - name: foo
    class: Foo
  - name: bar
    class: Bar
  - name: custom
    class: Custom
    plugin: bliss

foo and bar objects will use the generic plugin whereas custom will use the bliss plugin.

Key package & module

This special keys indicate where to find the object class definition (i.e. class module).

Plugins will look for these keys in that order:

  • If package key is found, it must provide the full path of the class module. It could be used to target a module outside BLISS itself.

    Providing the package key (import from <package_path>)

    - name: fox
      class: Foo
      plugin: generic
      package: idxx.mydevices.foomod
    

    Foo class will be imported from idxx.mydevices.foomod

  • If module key is found, it must provide a sub-module path starting from plugin’s base_path (each plugin has a default module base_path, like bliss.controllers for the generic plugin). BLISS will try to import the class from <base_path>.<module_path>.

    Providing the module key (import from <base_path>.<module_path>)

    - name: fox
      class: Foo
      plugin: generic
      module: custom.foomod
    

    Foo class will be imported from bliss.controllers.custom.foomod

  • Else it tries to import the class from <base_path>.<class_name> (using the lowered class name as module’s name).

    Default behavior if no keys are provided (import from <base_path>.<class_name>)

    - name: fox
      class: Foo
      plugin: generic
    

    Foo class will be imported from bliss.controllers.foo

Plugin generic

This plugin is dedicated for most objects and is able to handle subitems.

Default module base path is bliss.controllers.

Without subitems

YAML configuration example

name: foo
class: FooController
module: foo_controllers
plugin: generic

FooController class is expected to be found in bliss.controllers.foo_controllers module.

Object’s signature

class FooController():
    def __init__(self, config):

With config a ConfigNode object (or dictionary) corressponding to the YAML configuration.

With subitems

Objects that declare subitems must inherit from the ConfigItemContainer base class. While importing a subitem in a session, the plugin will ensure that the object declaring the subitem is created first and only once. The instantiation of the subitem is made by the object itself on plugin’s request.

YAML configuration example

name: foo
class: FooController
module: foo_controllers
plugin: generic
counters:
  - name: cnt1
    channel: 1
  - name: cnt2
    channel: 2

FooController class is expected to be found in bliss.controllers.foo_controllers module.

Object’s signature

from bliss.config.plugins.generic import ConfigItemContainer
class FooController(ConfigItemContainer):
    def __init__(self, config):
        super().__init__(config)

With config a ConfigNode object (or dictionary) corresponding to the YAML configuration.

Plugin emotion

This plugin is dedicated to motors. It uses the generic plugin but, the default module base path is bliss.controllers.motors.

Plugin regulation

This plugin is dedicated to regulation objects. It uses the generic plugin but, the default module base path is bliss.controllers.regulation and bliss.common.regulation.

Plugin diffractometer

This plugin is dedicated to diffractometers. It uses the generic plugin but, the default module base path is bliss.controllers.diffractometers.

Plugin bliss

This plugin transforms references into object attributes. It does not handle subitems.

Default module base path is bliss.controllers.

YAML configuration example

name: bar
class: BarController
module: bar_controllers
plugin: bliss
xprop: $foxy

This plugin will add the reference as attributes: bar.xprop will return foxy object.

Object’s signature

class BarController:
    def __init__(self, name, config):

With name the object name and config a ConfigNode object (or dictionary) corresponding to the YAML configuration.

Plugin session

This plugin is dedicated to Session objects and it handles measurement groups.

Default module base path is bliss.common.

Plugin default

This plugin just converts a YAML configuration into a Python dictionary.