Beispiel #1
0
def from_yaml_to_current(yaml_str: str) -> current.RunDescriber:
    """
    Deserialize a YAML string into a RunDescriber of the current version
    """
    yaml = YAML()
    # yaml.load returns an OrderedDict, but we need a dict
    ser = cast(RunDescriberDicts, dict(yaml.load(yaml_str)))
    return from_dict_to_current(ser)
Beispiel #2
0
 def from_yaml(cls, yaml_str: str) -> 'RunDescriber':
     """
     Parse a yaml string (the return of `to_yaml`) into a RunDescriber
     object
     """
     yaml = YAML()
     # yaml.load returns an OrderedDict, but we need a dict
     ser = dict(yaml.load(yaml_str))
     return cls.deserialize(ser)
Beispiel #3
0
    def to_yaml(self) -> str:
        """
        Output the run description as a yaml string
        """
        yaml = YAML()
        with io.StringIO() as stream:
            yaml.dump(self.serialize(), stream=stream)
            output = stream.getvalue()

        return output
Beispiel #4
0
def to_yaml_for_storage(desc: current.RunDescriber) -> str:
    """
    Serialize the given RunDescriber to YAML as a RunDescriber of the
    version for storage
    """
    yaml = YAML()
    with io.StringIO() as stream:
        yaml.dump(to_dict_for_storage(desc), stream=stream)
        output = stream.getvalue()

    return output
Beispiel #5
0
def test_yaml_creation_and_loading(some_paramspecs):
    yaml = YAML()
    for group in some_paramspecs.values():
        paramspecs = group.values()
        idp = InterDependencies(*paramspecs)
        desc = RunDescriber(interdeps=idp)

        yaml_str = desc.to_yaml()
        assert isinstance(yaml_str, str)
        ydict = dict(yaml.load(yaml_str))
        assert list(ydict.keys()) == ['interdependencies']

        new_desc = RunDescriber.from_yaml(yaml_str)
        assert new_desc == desc
Beispiel #6
0
def test_yaml_creation_and_loading(some_interdeps):

    yaml = YAML()

    for idps in some_interdeps:
        desc = RunDescriber(interdeps=idps)

        yaml_str = serial.to_yaml_for_storage(desc)
        assert isinstance(yaml_str, str)
        ydict = dict(yaml.load(yaml_str))
        assert list(ydict.keys()) == ['version', 'interdependencies']
        assert ydict['version'] == serial.STORAGE_VERSION

        new_desc = serial.from_yaml_to_current(yaml_str)
        assert new_desc == desc
Beispiel #7
0
    def load_config(self, config: Union[str, IO[AnyStr]]) -> None:
        """
        Loads a configuration from a supplied string or file/stream handle.
        The string or file/stream is expected to be YAML formatted

        Loading of a configuration will update the snapshot of the station and
        make the instruments described in the config file available for
        instantiation with the :meth:`load_instrument` method.

        Additionally the shortcut methods ``load_<instrument_name>`` will be
        updated.
        """
        def update_station_configuration_snapshot() -> None:
            self.config = StationConfig(self._config)

        def update_load_instrument_methods() -> None:
            #  create shortcut methods to instantiate instruments via
            # `load_<instrument_name>()` so that autocompletion can be used
            # first remove methods that have been added by a previous
            # :meth:`load_config_file` call
            while len(self._added_methods):
                delattr(self, self._added_methods.pop())

            # add shortcut methods
            for instrument_name in self._instrument_config.keys():
                method_name = f'load_{instrument_name}'
                if method_name.isidentifier():
                    setattr(
                        self, method_name,
                        partial(self.load_instrument,
                                identifier=instrument_name))
                    self._added_methods.append(method_name)
                else:
                    log.warning(f'Invalid identifier: '
                                f'for the instrument {instrument_name} no '
                                f'lazy loading method {method_name} could '
                                'be created in the Station.')

        # Load template schema, and thereby don't fail on instruments that are
        # not included in the user schema.
        yaml = YAML().load(config)
        with open(SCHEMA_TEMPLATE_PATH) as f:
            schema = json.load(f)
        try:
            jsonschema.validate(yaml, schema)
        except jsonschema.exceptions.ValidationError as e:
            message = e.message + '\n config:\n'
            if isinstance(config, str):
                message += config
            else:
                config.seek(0)
                message += config.read()
            warnings.warn(message, ValidationWarning)

        self._config = yaml

        self._instrument_config = self._config['instruments']
        update_station_configuration_snapshot()
        update_load_instrument_methods()
Beispiel #8
0
def test_station_config_can_be_loaded_from_snapshot(example_station):
    assert station_config_has_been_loaded(example_station)
    # ensure that we can correctly dump config which is a subclass of UserDict
    configdump = json.dumps(example_station.config, cls=NumpyJSONEncoder)
    # as this is now a regular dict we can load it back
    loaded_config = json.loads(configdump)
    # now lets ensure that we can recreate the
    # station from the loaded config
    # first we need to get a yaml repr of the data
    yaml = YAML()
    with StringIO() as output:
        yaml.dump(loaded_config, output)
        yaml_repr = output.getvalue()
    # which we can then reload into the station
    new_station = Station(default=False)
    new_station.load_config(yaml_repr)
    assert example_station.config == new_station.config
Beispiel #9
0
    def load_config(self, config: Union[str, IO[AnyStr]]) -> None:
        """
        Loads a configuration from a supplied string or file/stream handle.

        Loading of a configuration will update the snapshot of the station and
        make the instruments described in the config file available for
        instantiation with the :meth:`load_instrument` method.

        Additionally the shortcut methods ``load_<instrument_name>`` will be
        updated.
        """
        def update_station_configuration_snapshot():
            class StationConfig(UserDict):
                def snapshot(self, update=True):
                    return self

            self.components['config'] = StationConfig(self._config)

        def update_load_instrument_methods():
            #  create shortcut methods to instantiate instruments via
            # `load_<instrument_name>()` so that autocompletion can be used
            # first remove methods that have been added by a previous
            # :meth:`load_config_file` call
            while len(self._added_methods):
                delattr(self, self._added_methods.pop())

            # add shortcut methods
            for instrument_name in self._instrument_config.keys():
                method_name = f'load_{instrument_name}'
                if method_name.isidentifier():
                    setattr(
                        self, method_name,
                        partial(self.load_instrument,
                                identifier=instrument_name))
                    self._added_methods.append(method_name)
                else:
                    log.warning(f'Invalid identifier: ' +
                                f'for the instrument {instrument_name} no ' +
                                f'lazy loading method {method_name} could ' +
                                'be created in the Station.')

        self._config = YAML().load(config)
        self._instrument_config = self._config['instruments']
        update_station_configuration_snapshot()
        update_load_instrument_methods()