Beispiel #1
0
def test_beckoff_axis_device_class(mockqsbackend):
    c = Client(database=mockqsbackend)
    d = load_devices(*c.all_items).__dict__
    vh_y = d.get('vh_y')
    sam_x = d.get('sam_x')
    assert vh_y.__class__.__name__ == 'BeckhoffAxis'
    assert sam_x.__class__.__name__ == 'IMS'
Beispiel #2
0
def get_qs_objs(expname):
    """
    Gather user objects from the experiment questionnaire.

    Parameters
    ----------
    expname: ``str``
        The experiment's name from the elog

    Returns
    -------
    objs: ``dict``
        Mapping from questionnaire ``python name`` to loaded object.
    """
    logger.debug('get_qs_client(%s)', expname)
    with safe_load('questionnaire'):
        expname = expname.lower()
        qs_client = get_qs_client(expname)
        # Create namespace
        if not qs_client.all_devices:
            logger.warning("No devices found in PCDS Questionnaire for %s",
                           expname)
            return dict()
        dev_namespace = load_devices(*qs_client.all_devices, pprint=False)
        return dev_namespace.__dict__
    return {}
Beispiel #3
0
def test_qsbackend_with_acromag(mockqsbackend):
    c = Client(database=mockqsbackend)
    d = load_devices(*c.all_devices, pprint=False).__dict__
    ai1 = d.get('ai_7')
    ao1 = d.get('ao_6')
    assert ai1.__class__.__name__ == 'EpicsSignalRO'
    assert ao1.__class__.__name__ == 'EpicsSignal'
Beispiel #4
0
    def get_happi_devices(self):
        """
        Request devices from happi based on our designer attributes.

        This relied on the happi_cfg and happi_names properties being
        set appropriately.
        """
        if self.happi_names and happi_check():
            happi_client = Client.from_config(cfg=self.happi_cfg or None)
            items = []
            for name in self.happi_names:
                try:
                    search_result = happi_client.search(name=name)[0]
                except IndexError:
                    raise ValueError(
                        f'Did not find device with name {name} in happi. '
                        'Please check your spelling and your database.'
                    ) from None
                items.append(search_result.item)

            with no_device_lazy_load():
                device_namespace = load_devices(*items, threaded=True)

            return [
                getattr(device_namespace, name) for name in self.happi_names
            ]
        return []
Beispiel #5
0
def test_load_devices(threaded: bool, post_load: Any, include_load_time: bool):
    # Create a bunch of devices to load
    devs = [TimeDevice(name='test_1', prefix='Tst1:This', beamline='TST',
                       device_class='datetime.timedelta', args=list(), days=10,
                       kwargs={'days': '{{days}}', 'seconds': 30}),
            TimeDevice(name='test_2', prefix='Tst2:This', beamline='TST',
                       device_class='datetime.timedelta', args=list(), days=10,
                       kwargs={'days': '{{days}}', 'seconds': 30}),
            TimeDevice(name='test_3', prefix='Tst3:This', beamline='TST',
                       device_class='datetime.timedelta', args=list(), days=10,
                       kwargs={'days': '{{days}}', 'seconds': 30}),
            HappiItem(name='bad', prefix='Not:Here', beamline='BAD',
                      device_class='non.existant')]
    # Load our devices
    space = load_devices(
        *devs,
        pprint=True,
        use_cache=False,
        threaded=threaded,
        post_load=post_load,
        include_load_time=include_load_time,
    )
    # Check all our devices are there
    assert all([create_alias(dev.name) in space.__dict__ for dev in devs])
    # Devices were loading properly or exceptions were stored
    import datetime
    assert space.test_1 == datetime.timedelta(days=10, seconds=30)
    assert isinstance(space.bad, ImportError)
Beispiel #6
0
def get_happi_objs(db, hutch):
    """
    Get the relevant devices for ``hutch`` from ``db``.

    This depends on a JSON ``happi`` database stored somewhere in the file
    system and handles setting up the ``happi.Client`` and querying the data
    base for devices.

    Parameters
    ----------
    db: ``str``
        Path to database

    hutch: ``str``
        Name of hutch

    Returns
    -------
    objs: ``dict``
        A mapping from device name to device
    """
    # Load the happi Client
    client = happi.Client(path=db)
    containers = list()
    # Find upstream devices based on lightpath configuration
    beamline_conf = beamlines.get(hutch.upper())
    # Something strange is happening if there are no upstream devices
    if not beamline_conf:
        logger.warning("Unable to find lightpath for %s", hutch.upper())
        beamline_conf = {}
    # Add the complete hutch beamline
    beamline_conf[hutch.upper()] = {}
    # Base beamline
    for beamline, conf in beamline_conf.items():
        # Assume we want hutch devices that are active and in the bounds
        # determined by the beamline configuration
        reqs = dict(beamline=beamline,
                    active=True,
                    start=conf.get('start', 0),
                    end=conf.get('end', None))
        results = client.search_range(key='z', **reqs)
        blc = [res.device for res in results]
        # Add the beamline containers to the complete list
        if blc:
            containers.extend(blc)
        else:
            logger.warning("No devices found in database for %s",
                           beamline.upper())
    # Instantiate the devices needed
    dev_namespace = load_devices(*containers, pprint=False)
    return dev_namespace.__dict__
Beispiel #7
0
def test_load_devices():
    # Create a bunch of devices to load
    devs = [
        TimeDevice(name='Test 1',
                   prefix='Tst1:This',
                   beamline='TST',
                   device_class='datetime.timedelta',
                   args=list(),
                   days=10,
                   kwargs={
                       'days': '{{days}}',
                       'seconds': 30
                   }),
        TimeDevice(name='Test 2',
                   prefix='Tst2:This',
                   beamline='TST',
                   device_class='datetime.timedelta',
                   args=list(),
                   days=10,
                   kwargs={
                       'days': '{{days}}',
                       'seconds': 30
                   }),
        TimeDevice(name='Test 3',
                   prefix='Tst3:This',
                   beamline='TST',
                   device_class='datetime.timedelta',
                   args=list(),
                   days=10,
                   kwargs={
                       'days': '{{days}}',
                       'seconds': 30
                   }),
        Device(name='Bad',
               prefix='Not:Here',
               beamline='BAD',
               device_class='non.existant')
    ]
    # Load our devices
    space = load_devices(*devs, pprint=True)
    # Check all our devices are there
    assert all([create_alias(dev.name) in space.__dict__ for dev in devs])
    # Devices were loading properly or exceptions were stored
    import datetime
    assert space.test_1 == datetime.timedelta(days=10, seconds=30)
    assert isinstance(space.bad, ImportError)
Beispiel #8
0
def get_qs_objs(expname):
    """
    Gather user objects from the experiment questionnaire.

    Connects to the questionnaire webservice via the ``happi`` ``QSBackend``
    using ``psdm_qs_cli`` to collect well-defined devices.

    There are two possible methods of authentication to the
    ``QuestionnaireClient``, ``Kerberos`` and ``WS-Auth``. The first is simpler
    but is not possible for all users, we therefore search for a configuration
    file named ``web.cfg``, either hidden in the current directory or the users
    home directory. This should contain the username and password needed to
    authenticate into the ``QuestionnaireClient``. The format of this
    configuration file is the standard ``.ini`` structure and should define the
    username and password like:

    .. code:: ini

        [DEFAULT]
        user = MY_USERNAME
        pw = MY_PASSWORD

    Parameters
    ----------
    expname: ``str``
        The experiment's name from the elog

    Returns
    -------
    objs: ``dict``
        Mapping from questionnaire ``python name`` to loaded object.
    """
    logger.debug('get_qs_objs(%s)', expname)
    with safe_load('questionnaire'):
        expname = expname.lower()
        # Determine which method of authentication we are going to use.
        # Search for a configuration file, either in the current directory
        # or hidden in the users home directory. If not found, attempt to
        # launch the client via Kerberos
        cfg = ConfigParser()
        cfgs = cfg.read(['qs.cfg', '.qs.cfg',
                         os.path.expanduser('~/.qs.cfg'),
                         'web.cfg', '.web.cfg',
                         os.path.expanduser('~/.web.cfg')])
        # Ws-auth
        if cfgs:
            user = cfg.get('DEFAULT', 'user', fallback=None)
            try:
                pw = cfg.get('DEFAULT', 'pw')
            except NoOptionError as exc:
                raise ValueError("Must specify password as 'pw' in "
                                 "configuration file") from exc
            qs_client = happi.Client(database=QSBackend(expname,
                                                        use_kerberos=False,
                                                        user=user, pw=pw))
        # Kerberos
        else:
            qs_client = happi.Client(database=QSBackend(expname,
                                                        use_kerberos=True))
        # Create namespace
        if not qs_client.all_devices:
            logger.warning("No devices found in PCDS Questionnaire for %s",
                           expname)
            return dict()
        dev_namespace = load_devices(*qs_client.all_devices, pprint=False)
        return dev_namespace.__dict__
    return {}