1import re
2
3from omegaml.backends.virtualobj import VirtualObjectBackend
4
5
[docs]
6class VirtualObjectMixin:
7 """
8 process virtual objects
9
10 This checks if an object is a VirtualObject and if so
11 retrieves the handler and processes it.
12 """
13
14 def __init__(self):
15 self._vobj_meta = None
16
17 def _isvirtual(self, name):
18 self._vobj_meta = self.metadata(name)
19 return self._vobj_meta is not None and self._vobj_meta.kind == VirtualObjectBackend.KIND
20
21 def _istool(self, name):
22 return VirtualObjectBackend._is_tool_virtualobj(lambda: None, name)
23
24 def _getvirtualobjfn(self, name, **kwargs):
25 virtualobjfn = super().get(name, **kwargs)
26 if isinstance(virtualobjfn, type):
27 virtualobjfn = virtualobjfn()
28 return virtualobjfn
29
30 def _resolve_realname(self, name, kwargs):
31 # parse names in the format name{a=b,c=d} to name and update kwargs
32 if isinstance(name, str) and all(c in name for c in '{}'):
33 rx = r"(\w*=\w*)*"
34 real_name, fn_kwargs = name.split('{', 1)
35 fn_kwargs = fn_kwargs.split('}')[0]
36 matches = (v.split('=') for v in re.findall(rx, fn_kwargs) if v)
37 fn_kwargs = {k: v for k, v in matches}
38 kwargs.update(fn_kwargs)
39 name = real_name
40 return name, kwargs
41
42 def metadata(self, name, **kwargs):
43 dsname, _ = self._resolve_realname(name, kwargs)
44 return super().metadata(dsname)
45
46 def get(self, name, **kwargs):
47 # pass along some options to other mixins
48 raw = kwargs.get('raw')
49 should_version = self._model_version_applies(name)
50 raw = raw if raw is not None else should_version
51 is_tool = VirtualObjectBackend._is_tool_virtualobj(lambda: None, name)
52 name, kwargs = self._resolve_realname(name, kwargs)
53 if not raw and self._isvirtual(name) and not is_tool:
54 handler = self._getvirtualobjfn(name)
55 result = handler(method='get', meta=self._vobj_meta, store=self, **kwargs)
56 else:
57 result = super().get(name, **kwargs)
58 return result
59
60 def put(self, obj, name, replace=False, attributes=None, **kwargs):
61 # pass along some options to other mixins
62 raw = kwargs.get('raw', False)
63 noversion = kwargs.get('noversion')
64 name, kwargs = self._resolve_realname(name, kwargs)
65 should_version = bool(noversion) if noversion is not None else self._model_version_applies(name)
66 raw = raw if raw is not None else should_version
67 if not should_version and not raw and not replace and self._isvirtual(name) and not self._istool(name):
68 result = self._getvirtualobjfn(name)(data=obj, method='put', meta=self._vobj_meta, store=self, **kwargs)
69 else:
70 result = super().put(obj, name, attributes=attributes, replace=replace, **kwargs)
71 return result
72
73 def drop(self, name, force=False, **kwargs):
74 version = kwargs.get('version')
75 should_version = version is not None or self._model_version_applies(name)
76 if not should_version and self._isvirtual(name):
77 try:
78 handler = self._getvirtualobjfn(name)
79 result = handler(method='drop', meta=self._vobj_meta, store=self, force=force)
80 except Exception:
81 if not force:
82 raise
83 else:
84 if not force:
85 return bool(result)
86 return super().drop(name, force=force, **kwargs)