Пример #1
0
class ContextualDataReference(metaclass=abc.ABCMeta):
    '''
        Base class for autoloaded Contextual data references in Arjuna.

        Arguments:
            path: Path of the contextual data reference file.

        Note:
            It behaves like a Python dictionary. So, you get items by names/keys and loop over it.
    '''
    def __init__(self, path):
        self.__path = path
        self.__name = _get_file_name(path)
        self.__map = CIStringDict()
        self._populate()
        self.__iter = None

    def __iter__(self):
        self.__iter = iter(self.__map)
        return self

    def __next__(self):
        return next(self.__iter)

    def __len__(self):
        return len(self.__map)

    def __getitem__(self, context):
        return self._record_for(context)

    def keys(self):
        '''
        Names of contexts/keys in this reference.
        '''
        return self.__map.keys()

    def items(self):
        '''
        Items iterator for this reference.
        '''
        return self.__map.items()

    @property
    def _map(self):
        return self.__map

    @property
    def path(self):
        '''
        Path of this reference file.
        '''
        return self.__path

    @property
    def name(self):
        '''
        Name of this reference.
        '''
        return self.__name

    def _update(self, data_reference):
        for context, record in data_reference.map.items():
            if context not in self.map:
                self.__map[context] = CIStringDict()
            self.__map[context].update(record.named_values)

    def _update_from_dict(self, context, map):
        if context not in self.map:
            self.__map[context] = dict()
        self.__map[context].update(map)

    def _add_record(self, context, record):
        self.__map[context] = DataRecord(context="Ref-{}[{}]".format(
            self.name, context),
                                         **record)

    def _record_for(self, context):
        try:
            return self.__map[context]
        except:
            raise Exception("{} at {} does not contain {} context key.".format(
                self.__class__.__name__, self.path, context))

    def __str__(self):
        return str({k: str(v) for k, v in self.__map.items()})

    def enumerate(self):
        '''
        Print all items in this data reference.
        '''
        for k, v in self.__map.items():
            print(k, "::", type(v), str(v))

    @abc.abstractmethod
    def _populate(self):
        pass

    def as_json(self):
        from arjuna import Json, Http
        return Json.from_str(Http.content.json(self.named_values).content)
Пример #2
0
class Yaml:
    def __init__(self, *, name, pydict, file_path=None):
        self.__name = name
        self.__ydict = pydict is not None and pydict or dict()
        self.__sections = tuple(self.__ydict.keys())
        self.__ydict = CIStringDict(self.__ydict)
        self.__file_path = file_path

    @property
    def name(self):
        return self.__name

    @property
    def file_path(self):
        return self.__file_path

    def is_empty(self):
        return not self.__ydict

    def get_section(self, name, *, strict=True):
        val = self.get_value(name, strict=strict)
        if val is not None and type(val) is not dict:
            raise YamlError(
                f"Section content must be a dictionary. Found content >>{val}<< in {name} section."
            )
        return Yaml(name=name, pydict=val, file_path=self.file_path)

    def get_value(self, name, *, strict=True, as_yaml_str=False):
        if self.has_section(name):
            if as_yaml_str:
                return yaml.dump(self.__ydict[name])
            else:
                return self.__ydict[name]
        else:
            if strict:
                raise YamlUndefinedSectionError(
                    f"Yaml object does not have a section with the name: {name}"
                )
            else:
                return None

    def as_map(self):
        return self.__ydict

    def has_section(self, name):
        return name in self.__ydict

    @property
    def section_names(self):
        return self.__ydict.keys()

    def validate_sections_present(*section_names, atleast_one=False):
        absent_sections = []
        present_section_names = self.section_names
        for section_name in section_names:
            if section_name not in present_section_names:
                absent_sections.append(section_name)

        if len(absent_sections) == section_names or (
                len(absent_sections) < len(section_names) and not atleast_one):
            raise YamlUndefinedSectionError(
                f"Yaml object does not contains mandatory sections: {absent_sections}"
            )

    @classmethod
    def from_file(cls, *, file_path):
        yaml_name = os.path.basename(file_path).split(".yaml")[0]
        f = open(file_path, "r")
        ydict = yaml.load(f, Loader=yaml.SafeLoader)
        f.close()
        return Yaml(name=yaml_name, pydict=ydict, file_path=file_path)

    @classmethod
    def from_str(cls, *, name, contents):
        return Yaml(name=name, pydict=yaml.safe_load(contents))

    def as_str(self):
        return yaml.dump(self.__ydict)