i2mint / py2store

Tools to create simple and consistent interfaces to complicated and varied data sources.
MIT License
11 stars 2 forks source link

Malls: Building multi-store objects #45

Open thorwhalen opened 4 years ago

thorwhalen commented 4 years ago

Example:

# TODO: Local file system assumed: Decouple
class Mall:
    def __init__(self, rootdir, store_spec):
        assert_dir_exists(rootdir)  # decouple
        pjoin = lambda path: os.path.join(rootdir, path)
        self._attrs = list()
        for attr, specs in store_spec.items():
            self._attrs.append(attr)
            func = specs['func']
            args = specs.get('args', [])
            kwargs = specs.get('kwargs', {})
            fullpath = pjoin(attr)
            mk_dir_if_does_not_exist(fullpath)  # decouple
            setattr(self, attr, func(pjoin(attr), *args, **kwargs))

    def __repr__(self):
        attr_lens = list()
        for attr in self._attrs:
            attr_lens.append(f"{attr}: {len(getattr(self, attr))}")
        s = ', '.join(attr_lens)
        return s

DFLT_MALL_FACTORY = Mall

DFLT_MALL_SPEC = imdict({
    'raw_data': {'func': DfStore},
    'xy_data': {'func': PickleStore},
    'learners': {'func': PickleStore},
    'models': {'func': PickleStore}
})

class MallAccess:
    _p_valid_mall_name = re.compile(r'^\w.*')

    def __init__(self, rootdir, mall_spec=DFLT_MALL_SPEC, mk_mall=DFLT_MALL_FACTORY):
        assert_dir_exists(rootdir)  # decouple
        self.mk_mall = mk_mall
        self.rootdir = rootdir
        self.mall_spec = mall_spec
        self.pjoin = lambda path: os.path.join(rootdir, path)

    def get_mall(self, name):
        space_root = self.pjoin(name)
        mk_dir_if_does_not_exist(space_root)
        return self.mk_mall(space_root, self.mall_spec)

    @classmethod
    def is_valid_mall_name(cls, name: str) -> bool:
        return bool(cls._p_valid_mall_name.match(name))

    def __call__(self, name: str):
        if self.is_valid_mall_name(name):
            return self.get_mall(name)
        else:
            raise err.InvalidMallName(f"Invalid Mall name: {name}")