balderhub-data 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- balderhub/data/__init__.py +17 -0
- balderhub/data/_version.py +24 -0
- balderhub/data/contrib/__init__.py +0 -0
- balderhub/data/contrib/auth/setup_features/__init__.py +6 -0
- balderhub/data/contrib/auth/setup_features/data_item_param_provider.py +71 -0
- balderhub/data/contrib/auth/setup_features/factories/__init__.py +6 -0
- balderhub/data/contrib/auth/setup_features/factories/auto_data_param_provider_factory.py +41 -0
- balderhub/data/contrib/auth/utils/__init__.py +5 -0
- balderhub/data/contrib/auth/utils/resource_for_specific_data_item.py +59 -0
- balderhub/data/lib/__init__.py +6 -0
- balderhub/data/lib/scenario_features/__init__.py +14 -0
- balderhub/data/lib/scenario_features/abstract_data_item_related_feature.py +84 -0
- balderhub/data/lib/scenario_features/accessible_initial_data_config.py +15 -0
- balderhub/data/lib/scenario_features/data_environment_feature.py +89 -0
- balderhub/data/lib/scenario_features/factories/__init__.py +7 -0
- balderhub/data/lib/scenario_features/factories/auto_accessible_initial_data_config_factory.py +25 -0
- balderhub/data/lib/scenario_features/factories/auto_initial_data_config_factory.py +24 -0
- balderhub/data/lib/scenario_features/initial_data_config.py +15 -0
- balderhub/data/lib/setup_features/__init__.py +6 -0
- balderhub/data/lib/setup_features/factories/__init__.py +7 -0
- balderhub/data/lib/setup_features/factories/auto_accessible_initial_data_config_factory.py +50 -0
- balderhub/data/lib/setup_features/factories/auto_initial_data_config_factory.py +29 -0
- balderhub/data/lib/utils/__init__.py +18 -0
- balderhub/data/lib/utils/auto_feature_factory.py +56 -0
- balderhub/data/lib/utils/base_response_message.py +10 -0
- balderhub/data/lib/utils/decorator_register_for_data_item.py +44 -0
- balderhub/data/lib/utils/exceptions.py +12 -0
- balderhub/data/lib/utils/filter.py +23 -0
- balderhub/data/lib/utils/functions.py +137 -0
- balderhub/data/lib/utils/lookup_field_string.py +58 -0
- balderhub/data/lib/utils/not_definable.py +37 -0
- balderhub/data/lib/utils/response_message.py +35 -0
- balderhub/data/lib/utils/response_message_list.py +73 -0
- balderhub/data/lib/utils/single_data_item.py +619 -0
- balderhub/data/lib/utils/single_data_item_collection.py +236 -0
- balderhub_data-0.0.1.dist-info/METADATA +102 -0
- balderhub_data-0.0.1.dist-info/RECORD +42 -0
- balderhub_data-0.0.1.dist-info/WHEEL +5 -0
- balderhub_data-0.0.1.dist-info/licenses/LICENSE +21 -0
- balderhub_data-0.0.1.dist-info/scm_file_list.json +77 -0
- balderhub_data-0.0.1.dist-info/scm_version.json +8 -0
- balderhub_data-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from balderhub.data.lib.utils.decorator_register_for_data_item import register_for_data_item
|
|
2
|
+
|
|
3
|
+
__all__ = [
|
|
4
|
+
|
|
5
|
+
"register_for_data_item",
|
|
6
|
+
|
|
7
|
+
"__version__",
|
|
8
|
+
|
|
9
|
+
"__version_tuple__",
|
|
10
|
+
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
from ._version import __version__, __version_tuple__
|
|
15
|
+
except ImportError:
|
|
16
|
+
__version__ = ""
|
|
17
|
+
__version_tuple__ = tuple()
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '0.0.1'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 0, 1)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = None
|
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
|
|
3
|
+
import balder
|
|
4
|
+
|
|
5
|
+
import balderhub.data.lib.scenario_features
|
|
6
|
+
from balderhub.auth.lib.scenario_features.client import UnresolvedResourceParameterConfig
|
|
7
|
+
from balderhub.auth.lib.utils import ResourceRule
|
|
8
|
+
|
|
9
|
+
from ..utils import ResourceForSpecificDataItem
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DataItemParamProvider(UnresolvedResourceParameterConfig):
|
|
13
|
+
"""
|
|
14
|
+
Handles configuration and provides parameters for resolving resources for specific data items.
|
|
15
|
+
|
|
16
|
+
This is a setup-level feature implementation for the
|
|
17
|
+
:class:`balderhub.auth.lib.scenario_features.client.UnresolvedResourceParameterConfig`. It uses a
|
|
18
|
+
defined `ResolvingMode` to specify how parameters should be selected out of the remote server feature
|
|
19
|
+
:class:`balderhub.data.lib.scenario_features.InitialDataConfig`.
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
class ResolvingMode(enum.Enum):
|
|
23
|
+
"""
|
|
24
|
+
Defines modes for resolving entities.
|
|
25
|
+
|
|
26
|
+
This class provides an enumeration of possible resolving modes that dictate
|
|
27
|
+
how entities are retrieved or resolved.
|
|
28
|
+
"""
|
|
29
|
+
# this will return all existing
|
|
30
|
+
ALL = 'all'
|
|
31
|
+
# will return the first {ENFORCING_PARAMETERS} items (ENFORCING_PARAMETERS needs to be >0)
|
|
32
|
+
MINIMUM = 'minimum'
|
|
33
|
+
|
|
34
|
+
#: defines the mode used to resolve parameters. It can either return all existing parameters
|
|
35
|
+
# (``ResolvingMode.ALL``) or enforce a minimum required number of parameters (``ResolvingMode.MINIMUM``).
|
|
36
|
+
RESOLVING_MODE: ResolvingMode = ResolvingMode.ALL
|
|
37
|
+
#: specifies the minimum number of parameters to enforce when in ``ResolvingMode.MINIMUM``. Must be greater
|
|
38
|
+
#: than 0 for that mode.
|
|
39
|
+
ENFORCING_PARAMETERS = 0
|
|
40
|
+
|
|
41
|
+
class Server(balder.VDevice):
|
|
42
|
+
"""server vdevice holding the specified initial data configuration feature"""
|
|
43
|
+
all_data = balderhub.data.lib.scenario_features.InitialDataConfig()
|
|
44
|
+
|
|
45
|
+
def get_parameters_for(self, resource_rule: ResourceRule) -> list[ResourceForSpecificDataItem.Parameter]:
|
|
46
|
+
data = self.Server.all_data.data_list
|
|
47
|
+
|
|
48
|
+
parameters = [ResourceForSpecificDataItem.Parameter(elem) for elem in data]
|
|
49
|
+
|
|
50
|
+
if resource_rule.cb_rule is not None:
|
|
51
|
+
# filter parameters
|
|
52
|
+
parameters = [param for param in parameters if resource_rule.cb_rule(param)]
|
|
53
|
+
|
|
54
|
+
if self.RESOLVING_MODE == self.ResolvingMode.ALL:
|
|
55
|
+
# do nothing
|
|
56
|
+
pass
|
|
57
|
+
elif self.RESOLVING_MODE == self.ResolvingMode.MINIMUM:
|
|
58
|
+
if self.ENFORCING_PARAMETERS <= 0:
|
|
59
|
+
raise ValueError(
|
|
60
|
+
f'in resolving mode {self.ResolvingMode.MINIMUM} the ENFORCING_PARAMETERS needs to be >0'
|
|
61
|
+
)
|
|
62
|
+
parameters = parameters[:self.ENFORCING_PARAMETERS]
|
|
63
|
+
else:
|
|
64
|
+
raise ValueError(f'unexpected value for ResolvingMode {self.RESOLVING_MODE}')
|
|
65
|
+
|
|
66
|
+
if len(parameters) < self.ENFORCING_PARAMETERS:
|
|
67
|
+
raise ValueError(
|
|
68
|
+
f'{self.__class__.__name__}.ENFORCING_PARAMETERS requires at least {self.ENFORCING_PARAMETERS} '
|
|
69
|
+
f'parameters for every rule - but rule {resource_rule} only has {len(parameters)} possible parameters')
|
|
70
|
+
|
|
71
|
+
return parameters
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from balderhub.data.lib.scenario_features import AbstractDataItemRelatedFeature
|
|
2
|
+
import balderhub.data.lib.scenario_features.factories
|
|
3
|
+
from balderhub.data.lib.utils import SingleDataItem
|
|
4
|
+
from balderhub.data.lib.utils.auto_feature_factory import AutoFeatureFactory
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AutoDataParamProviderFactory(AutoFeatureFactory):
|
|
8
|
+
"""
|
|
9
|
+
Represents a factory for creating parameter providers related to data items for auto-generated features.
|
|
10
|
+
|
|
11
|
+
The `AutoDataParamProviderFactory` is responsible for defining and constructing data item parameter
|
|
12
|
+
providers dynamically for use with auto-generated features. It creates data item bounded setup-level features
|
|
13
|
+
of :class:`balderhub.auth.contrib.data.setup_features.DataItemParamProvider`.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def _define_class(cls, data_item_cls: type[SingleDataItem], **kwargs) -> type[AbstractDataItemRelatedFeature]:
|
|
18
|
+
# pylint: disable-next=import-outside-toplevel
|
|
19
|
+
from ..data_item_param_provider import DataItemParamProvider
|
|
20
|
+
|
|
21
|
+
resolving_mode = kwargs.pop('resolving_mode') if 'resolving_mode' in kwargs else \
|
|
22
|
+
DataItemParamProvider.ResolvingMode.ALL
|
|
23
|
+
|
|
24
|
+
enforcing_parameters = kwargs.pop('enforcing_parameters') if 'enforcing_parameters' in kwargs else 0
|
|
25
|
+
|
|
26
|
+
class AutoDataItemParamProvider(DataItemParamProvider):
|
|
27
|
+
"""
|
|
28
|
+
auto created data item bounded setup-level feature of
|
|
29
|
+
:class:`balderhub.auth.contrib.data.setup_features.DataItemParamProvider`
|
|
30
|
+
"""
|
|
31
|
+
RESOLVING_MODE = resolving_mode
|
|
32
|
+
ENFORCING_PARAMETERS = enforcing_parameters
|
|
33
|
+
class Server(DataItemParamProvider.Server):
|
|
34
|
+
"""
|
|
35
|
+
server vdevice with data-item bounded setup-level feature implementation of
|
|
36
|
+
:class:`balderhub.data.lib.scenario_features.InitialDataConfig`.
|
|
37
|
+
"""
|
|
38
|
+
all_data = \
|
|
39
|
+
balderhub.data.lib.scenario_features.factories.AutoInitialDataConfigFactory.get_for(data_item_cls)()
|
|
40
|
+
|
|
41
|
+
return AutoDataItemParamProvider
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Type
|
|
3
|
+
|
|
4
|
+
import dataclasses
|
|
5
|
+
from balderhub.data.lib.utils import SingleDataItem
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
from balderhub.auth.lib.utils import Resource
|
|
9
|
+
from balderhub.auth.lib.utils import UnresolvedResource
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ResourceForSpecificDataItem(UnresolvedResource, ABC):
|
|
13
|
+
"""
|
|
14
|
+
This class represents an unresolved resource that is specific for a certain data item type.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
@dataclasses.dataclass
|
|
18
|
+
class Parameter(UnresolvedResource.Parameter):
|
|
19
|
+
"""
|
|
20
|
+
The parameter class for the `ResourceForSpecificDataItem` class.
|
|
21
|
+
"""
|
|
22
|
+
data_item: SingleDataItem
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
data_item_type: Type[SingleDataItem],
|
|
27
|
+
**kwargs
|
|
28
|
+
):
|
|
29
|
+
"""
|
|
30
|
+
:param data_item_type: the type of the data item
|
|
31
|
+
:param kwargs: additional keyword arguments for the `UnresolvedResource` constructor
|
|
32
|
+
"""
|
|
33
|
+
super().__init__(**kwargs)
|
|
34
|
+
self._data_item_type = data_item_type
|
|
35
|
+
|
|
36
|
+
def __str__(self):
|
|
37
|
+
return f"{super().__str__()}({self._data_item_type.__name__})"
|
|
38
|
+
|
|
39
|
+
def __eq__(self, other):
|
|
40
|
+
if self.__class__ != other.__class__:
|
|
41
|
+
return False
|
|
42
|
+
return self.data_item_type == other.data_item_type
|
|
43
|
+
|
|
44
|
+
def __hash__(self):
|
|
45
|
+
return hash(self.__class__) + hash(self._data_item_type)
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def data_item_type(self) -> Type[SingleDataItem]:
|
|
49
|
+
"""returns the data item type of this resource"""
|
|
50
|
+
return self._data_item_type
|
|
51
|
+
|
|
52
|
+
@abstractmethod
|
|
53
|
+
def get_resolved_resource(self, param: Parameter) -> Resource:
|
|
54
|
+
"""
|
|
55
|
+
Resolves the resource with the given parameter.
|
|
56
|
+
|
|
57
|
+
:param param: the parameter for the unresolved resource
|
|
58
|
+
:return: the resolved resource
|
|
59
|
+
"""
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from . import factories
|
|
2
|
+
|
|
3
|
+
from .abstract_data_item_related_feature import AbstractDataItemRelatedFeature
|
|
4
|
+
from .accessible_initial_data_config import AccessibleInitialDataConfig
|
|
5
|
+
from .data_environment_feature import DataEnvironmentFeature
|
|
6
|
+
from .initial_data_config import InitialDataConfig
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
'AbstractDataItemRelatedFeature',
|
|
11
|
+
'AccessibleInitialDataConfig',
|
|
12
|
+
'DataEnvironmentFeature',
|
|
13
|
+
'InitialDataConfig',
|
|
14
|
+
]
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Type
|
|
3
|
+
import balder
|
|
4
|
+
|
|
5
|
+
from ..utils.single_data_item import SingleDataItem
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AbstractDataItemRelatedFeature(balder.Feature):
|
|
9
|
+
"""
|
|
10
|
+
Base factory usable feature. All Features that should be creatable by a factory class needs to be a subclass of
|
|
11
|
+
this feature class.
|
|
12
|
+
"""
|
|
13
|
+
#: static managing class property that stores parametrized feature class definitions per data item class
|
|
14
|
+
_features_by_data_item_type = {}
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def data_item_type(self) -> Type[SingleDataItem]:
|
|
18
|
+
"""
|
|
19
|
+
:return: returns the type of the data item, this feature belongs too
|
|
20
|
+
"""
|
|
21
|
+
if not hasattr(self.__class__, '_for_data_item_type'):
|
|
22
|
+
raise ValueError(
|
|
23
|
+
f'data item related feature `{self.__class__}` was not registered for a specific data item'
|
|
24
|
+
)
|
|
25
|
+
return getattr(self.__class__, '_for_data_item_type')
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
def set_data_item_type(cls, data_item_type: Type[SingleDataItem]) -> None:
|
|
29
|
+
"""
|
|
30
|
+
This class method sets the data-item type. This method is normally called by the decorator
|
|
31
|
+
`@register_for_data_item()`.
|
|
32
|
+
|
|
33
|
+
:param data_item_type: the data item type
|
|
34
|
+
"""
|
|
35
|
+
cls._for_data_item_type = data_item_type
|
|
36
|
+
cls.register_feature_with_data_item_type(feature_cls=cls, data_item_type=data_item_type)
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def register_feature_with_data_item_type(
|
|
40
|
+
cls,
|
|
41
|
+
feature_cls: type[AbstractDataItemRelatedFeature],
|
|
42
|
+
data_item_type: Type[SingleDataItem]
|
|
43
|
+
) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Internally used class for managing the correct assignment of data item type to that feature.
|
|
46
|
+
|
|
47
|
+
:param feature_cls: the feature class type that should be registered
|
|
48
|
+
:param data_item_type: the data item type that should be assigned to the provided `feature_cls`
|
|
49
|
+
"""
|
|
50
|
+
if cls not in AbstractDataItemRelatedFeature._features_by_data_item_type.keys():
|
|
51
|
+
AbstractDataItemRelatedFeature._features_by_data_item_type[cls] = {}
|
|
52
|
+
|
|
53
|
+
if data_item_type not in AbstractDataItemRelatedFeature._features_by_data_item_type[cls]:
|
|
54
|
+
AbstractDataItemRelatedFeature._features_by_data_item_type[cls][data_item_type] = []
|
|
55
|
+
|
|
56
|
+
#: only add it if it was not added before
|
|
57
|
+
if feature_cls not in AbstractDataItemRelatedFeature._features_by_data_item_type[cls][data_item_type]:
|
|
58
|
+
AbstractDataItemRelatedFeature._features_by_data_item_type[cls][data_item_type].append(feature_cls)
|
|
59
|
+
|
|
60
|
+
# now register that for all parent classes that are based on :class:`AbstractDataItemRelatedFeature` too
|
|
61
|
+
for cur_base in cls.__bases__:
|
|
62
|
+
if issubclass(cur_base, AbstractDataItemRelatedFeature):
|
|
63
|
+
cur_base.register_feature_with_data_item_type(feature_cls=feature_cls, data_item_type=data_item_type)
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def get_specific_feature_for(cls, data_item_type: Type[SingleDataItem], **vdevice_mapping):
|
|
67
|
+
"""
|
|
68
|
+
This method returns an instantiated feature object that was previously registered for the provided
|
|
69
|
+
`data_item_type`.
|
|
70
|
+
|
|
71
|
+
:param data_item_type: the data item type the new instance should be for
|
|
72
|
+
:param vdevice_mapping: optional a vdevice mapping for the feature # TODO do use dict here
|
|
73
|
+
:return: returns a feature object of this type that was defined for the provided `data_item_type`
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
available_feature_classes = \
|
|
77
|
+
AbstractDataItemRelatedFeature._features_by_data_item_type.get(cls, {}).get(data_item_type, [])
|
|
78
|
+
|
|
79
|
+
if len(available_feature_classes) == 0:
|
|
80
|
+
raise KeyError(f'can not find a registered feature for data item `{data_item_type}` in `{cls.__name__}`')
|
|
81
|
+
if len(available_feature_classes) > 1:
|
|
82
|
+
raise KeyError(f'found more than one possible features for data item `{data_item_type}` in '
|
|
83
|
+
f'`{cls.__name__}`')
|
|
84
|
+
return available_feature_classes[0](**vdevice_mapping)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from ..utils.single_data_item_collection import SingleDataItemCollection
|
|
2
|
+
from .initial_data_config import InitialDataConfig
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AccessibleInitialDataConfig(InitialDataConfig):
|
|
6
|
+
"""
|
|
7
|
+
This config feature returns a list of data item elements, that is accessible for the using device.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def data_list(self) -> SingleDataItemCollection:
|
|
12
|
+
"""
|
|
13
|
+
:return: returns the data item collection this config feature describes
|
|
14
|
+
"""
|
|
15
|
+
raise NotImplementedError()
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, List, Dict, Type
|
|
3
|
+
import balder
|
|
4
|
+
|
|
5
|
+
from balderhub.data.lib.utils import SingleDataItemCollection
|
|
6
|
+
from balderhub.data.lib.utils.single_data_item import SingleDataItem, SingleDataItemTypeT
|
|
7
|
+
from balderhub.data.lib.utils.exceptions import DuplicateDataObjectError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DataEnvironmentFeature(balder.Feature):
|
|
11
|
+
"""
|
|
12
|
+
The Data Environment Feature provides an interface for managing a big data set. It helps to configure your tests
|
|
13
|
+
depending on the selected data sets. You can use it to create a nested data-environment structure and define
|
|
14
|
+
different data sets for different setups.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
# TODO do we need a plausibility check after the `load_data` call, that makes sure, that references between all data
|
|
18
|
+
# exist?
|
|
19
|
+
# TODO make sure that `unique_identification` is unique everywhere
|
|
20
|
+
|
|
21
|
+
class DoesNotExist(Exception):
|
|
22
|
+
"""
|
|
23
|
+
error that is thrown if an element does that is requested by some methods does not exist in the environment
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, **kwargs):
|
|
27
|
+
super().__init__(**kwargs)
|
|
28
|
+
# holds the whole data
|
|
29
|
+
self._data: Dict[Type[SingleDataItemTypeT], Dict[Any, SingleDataItemTypeT]] = {}
|
|
30
|
+
|
|
31
|
+
self.load_data()
|
|
32
|
+
|
|
33
|
+
def load_data(self) -> None:
|
|
34
|
+
"""
|
|
35
|
+
This method will be executed to generate / load the data for this environment into the object. You need to
|
|
36
|
+
overwrite it in subclass to fill the data environment with data.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def get_all_for(self, data_obj_type: Type[SingleDataItemTypeT]) -> SingleDataItemCollection:
|
|
40
|
+
"""
|
|
41
|
+
This method returns all known data-items for a specific data item type.
|
|
42
|
+
:param data_obj_type: the data-item type
|
|
43
|
+
:return: a list of all known data-items
|
|
44
|
+
"""
|
|
45
|
+
if data_obj_type not in self._data.keys():
|
|
46
|
+
return SingleDataItemCollection([])
|
|
47
|
+
return SingleDataItemCollection(list(self._data[data_obj_type].values()))
|
|
48
|
+
|
|
49
|
+
def get(self, data_obj_type: Type[SingleDataItemTypeT], unique_identification: Any) -> SingleDataItemTypeT:
|
|
50
|
+
"""
|
|
51
|
+
This method returns exactly one element identified by the `unique_identification`.
|
|
52
|
+
It raises an exception if the requested element does not exist in the environment.
|
|
53
|
+
|
|
54
|
+
:param data_obj_type: the data-item type
|
|
55
|
+
:param unique_identification: the unique-identification value of the requested data-item type
|
|
56
|
+
:return: the specific data item
|
|
57
|
+
"""
|
|
58
|
+
if data_obj_type not in self._data.keys():
|
|
59
|
+
raise self.DoesNotExist(f'no items from type `{data_obj_type}` exist in the environment')
|
|
60
|
+
if unique_identification not in self._data[data_obj_type].keys():
|
|
61
|
+
raise self.DoesNotExist(f'no element with unique-identification `{unique_identification}` of '
|
|
62
|
+
f'type `{data_obj_type}` exist in the environment')
|
|
63
|
+
return self._data[data_obj_type][unique_identification]
|
|
64
|
+
|
|
65
|
+
def _add_data(self, data_objects: SingleDataItem | List[SingleDataItem]) -> None:
|
|
66
|
+
"""
|
|
67
|
+
Method to add a new data set to the internal data set storage.
|
|
68
|
+
|
|
69
|
+
:param data_objects: the data item object / objects that should be added
|
|
70
|
+
"""
|
|
71
|
+
if isinstance(data_objects, SingleDataItem):
|
|
72
|
+
data_objects = [data_objects]
|
|
73
|
+
for cur_data_object in data_objects:
|
|
74
|
+
if cur_data_object.__class__ not in self._data.keys():
|
|
75
|
+
self._data[cur_data_object.__class__] = {}
|
|
76
|
+
if cur_data_object.get_unique_identification() in self._data[cur_data_object.__class__].keys():
|
|
77
|
+
raise DuplicateDataObjectError(
|
|
78
|
+
'another data object with the same identifier already exists in environment data'
|
|
79
|
+
)
|
|
80
|
+
self._data[cur_data_object.__class__][cur_data_object.get_unique_identification()] = cur_data_object
|
|
81
|
+
|
|
82
|
+
def sync_environment(self) -> None:
|
|
83
|
+
"""
|
|
84
|
+
This method executes the transfer of the environment in the related system. It should handle the creation of
|
|
85
|
+
the stored data with the related system.
|
|
86
|
+
It is expected that after calling this method, the environment data and the data within the related system are
|
|
87
|
+
in sync.
|
|
88
|
+
"""
|
|
89
|
+
raise NotImplementedError
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from .auto_accessible_initial_data_config_factory import AutoAccessibleInitialDataConfigFactory
|
|
2
|
+
from .auto_initial_data_config_factory import AutoInitialDataConfigFactory
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
'AutoAccessibleInitialDataConfigFactory',
|
|
6
|
+
'AutoInitialDataConfigFactory',
|
|
7
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from typing import Type
|
|
2
|
+
|
|
3
|
+
from balderhub.data.lib.scenario_features.accessible_initial_data_config import AccessibleInitialDataConfig
|
|
4
|
+
|
|
5
|
+
from balderhub.data.lib.utils.auto_feature_factory import AutoFeatureFactory
|
|
6
|
+
from balderhub.data.lib.utils.single_data_item import SingleDataItem
|
|
7
|
+
from balderhub.data.lib.utils.single_data_item_collection import SingleDataItemCollection
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AutoAccessibleInitialDataConfigFactory(AutoFeatureFactory):
|
|
11
|
+
"""
|
|
12
|
+
Factory for creating data-item bounded scenario-based config-feature :class:`AccessibleInitialDataConfig`
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def _define_class(cls, data_item_cls: Type[SingleDataItem], **kwargs):
|
|
17
|
+
|
|
18
|
+
class AutoAccessibleInitialDataConfig(AccessibleInitialDataConfig):
|
|
19
|
+
"""inner factory-created feature class"""
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def data_list(self) -> SingleDataItemCollection:
|
|
23
|
+
raise NotImplementedError()
|
|
24
|
+
|
|
25
|
+
return AutoAccessibleInitialDataConfig
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from typing import Type
|
|
2
|
+
|
|
3
|
+
from balderhub.data.lib.utils import SingleDataItemCollection
|
|
4
|
+
from balderhub.data.lib.utils.auto_feature_factory import AutoFeatureFactory
|
|
5
|
+
from balderhub.data.lib.scenario_features.initial_data_config import InitialDataConfig
|
|
6
|
+
from balderhub.data.lib.utils.single_data_item import SingleDataItem
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AutoInitialDataConfigFactory(AutoFeatureFactory):
|
|
10
|
+
"""
|
|
11
|
+
Factory for creating data-item bounded scenario-based config-feature :class:`InitialDataConfig`
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
@classmethod
|
|
15
|
+
def _define_class(cls, data_item_cls: Type[SingleDataItem], **kwargs):
|
|
16
|
+
|
|
17
|
+
class AutoInitialDataConfig(InitialDataConfig):
|
|
18
|
+
"""inner factory-created feature class"""
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def data_list(self) -> SingleDataItemCollection:
|
|
22
|
+
raise NotImplementedError()
|
|
23
|
+
|
|
24
|
+
return AutoInitialDataConfig
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from .abstract_data_item_related_feature import AbstractDataItemRelatedFeature
|
|
2
|
+
from ..utils.single_data_item_collection import SingleDataItemCollection
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class InitialDataConfig(AbstractDataItemRelatedFeature):
|
|
6
|
+
"""
|
|
7
|
+
This config feature returns a list of data item elements.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def data_list(self) -> SingleDataItemCollection:
|
|
12
|
+
"""
|
|
13
|
+
:return: returns the data item collection this config feature describes
|
|
14
|
+
"""
|
|
15
|
+
raise NotImplementedError()
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from .auto_accessible_initial_data_config_factory import AutoAccessibleInitialDataConfigFactory
|
|
2
|
+
from .auto_initial_data_config_factory import AutoInitialDataConfigFactory
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
'AutoAccessibleInitialDataConfigFactory',
|
|
6
|
+
'AutoInitialDataConfigFactory',
|
|
7
|
+
]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from typing import Callable, Union
|
|
2
|
+
|
|
3
|
+
import balder
|
|
4
|
+
|
|
5
|
+
from balderhub.data.lib.utils.auto_feature_factory import AutoFeatureFactory
|
|
6
|
+
from balderhub.data.lib.utils import SingleDataItemCollection
|
|
7
|
+
from balderhub.data.lib.utils.single_data_item import SingleDataItem
|
|
8
|
+
from balderhub.data.lib import scenario_features
|
|
9
|
+
from balderhub.data.lib.utils.filter import Filter
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AutoAccessibleInitialDataConfigFactory(AutoFeatureFactory):
|
|
13
|
+
"""
|
|
14
|
+
Factory for creating data-item bounded scenario-based config-feature :class:`MultipleDataConfig` by using the
|
|
15
|
+
defined data within a :class:`DataEnvironmentFeature`.
|
|
16
|
+
"""
|
|
17
|
+
@classmethod
|
|
18
|
+
def get_for(
|
|
19
|
+
cls,
|
|
20
|
+
data_item_cls: type[SingleDataItem],
|
|
21
|
+
filter_func: Union[Callable[[SingleDataItem], bool], None] = None,
|
|
22
|
+
**kwargs
|
|
23
|
+
):
|
|
24
|
+
return super().get_for(data_item_cls, filter_func=filter_func)
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def _define_class(cls, data_item_cls: type[SingleDataItem], **kwargs):
|
|
28
|
+
filter_func = kwargs['filter_func']
|
|
29
|
+
|
|
30
|
+
class AutoAccessibleInitialDataConfig(
|
|
31
|
+
scenario_features.factories.AutoAccessibleInitialDataConfigFactory.get_for(data_item_cls)
|
|
32
|
+
):
|
|
33
|
+
"""inner factory-created feature class"""
|
|
34
|
+
class Master(balder.VDevice):
|
|
35
|
+
"""inner vdevice referencing the master device that provides the full initial data config"""
|
|
36
|
+
full_initial_config = scenario_features.factories.AutoInitialDataConfigFactory.get_for(data_item_cls)()
|
|
37
|
+
|
|
38
|
+
class Filter(Filter):
|
|
39
|
+
"""filter that filters the initial data"""
|
|
40
|
+
def apply(self, item: SingleDataItem) -> bool:
|
|
41
|
+
return filter_func(item)
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def data_list(self) -> SingleDataItemCollection:
|
|
45
|
+
"""returns the accessible data according to the provided filter"""
|
|
46
|
+
if filter_func is None:
|
|
47
|
+
return self.Master.full_initial_config.data_list
|
|
48
|
+
return self.Master.full_initial_config.data_list.filter(self.Filter())
|
|
49
|
+
|
|
50
|
+
return AutoAccessibleInitialDataConfig
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from typing import Type
|
|
2
|
+
|
|
3
|
+
from balderhub.data.lib.utils.auto_feature_factory import AutoFeatureFactory
|
|
4
|
+
from balderhub.data.lib.scenario_features import DataEnvironmentFeature
|
|
5
|
+
from balderhub.data.lib.utils.single_data_item import SingleDataItem
|
|
6
|
+
from balderhub.data.lib import scenario_features
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AutoInitialDataConfigFactory(AutoFeatureFactory):
|
|
10
|
+
"""
|
|
11
|
+
Factory for creating data-item bounded scenario-based config-feature :class:`MultipleDataConfig` by using the
|
|
12
|
+
defined data within a :class:`DataEnvironmentFeature`.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def _define_class(cls, data_item_cls: Type[SingleDataItem], **kwargs):
|
|
17
|
+
|
|
18
|
+
class AutoMultipleDataConfig(scenario_features.factories.AutoInitialDataConfigFactory.get_for(data_item_cls)):
|
|
19
|
+
"""inner factory-created feature class"""
|
|
20
|
+
env = DataEnvironmentFeature()
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def data_list(self):
|
|
24
|
+
"""
|
|
25
|
+
:return: returns the data item collection this config feature describes
|
|
26
|
+
"""
|
|
27
|
+
return self.env.get_all_for(data_item_cls)
|
|
28
|
+
|
|
29
|
+
return AutoMultipleDataConfig
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from .auto_feature_factory import AutoFeatureFactory
|
|
2
|
+
from .base_response_message import BaseResponseMessage
|
|
3
|
+
from .not_definable import NOT_DEFINABLE
|
|
4
|
+
from .lookup_field_string import LookupFieldString
|
|
5
|
+
from .response_message import ResponseMessage
|
|
6
|
+
from .response_message_list import ResponseMessageList
|
|
7
|
+
from .single_data_item import SingleDataItem
|
|
8
|
+
from .single_data_item_collection import SingleDataItemCollection
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
'NOT_DEFINABLE',
|
|
12
|
+
'BaseResponseMessage',
|
|
13
|
+
'LookupFieldString',
|
|
14
|
+
'ResponseMessage',
|
|
15
|
+
'ResponseMessageList',
|
|
16
|
+
'SingleDataItem',
|
|
17
|
+
'SingleDataItemCollection'
|
|
18
|
+
]
|