idmtools-platform-comps 0.0.0.dev0__py3-none-any.whl → 0.0.2__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.
- idmtools_platform_comps/__init__.py +25 -8
- idmtools_platform_comps/cli/__init__.py +4 -0
- idmtools_platform_comps/cli/cli_functions.py +50 -0
- idmtools_platform_comps/cli/comps.py +492 -0
- idmtools_platform_comps/comps_cli.py +48 -0
- idmtools_platform_comps/comps_operations/__init__.py +6 -0
- idmtools_platform_comps/comps_operations/asset_collection_operations.py +263 -0
- idmtools_platform_comps/comps_operations/experiment_operations.py +569 -0
- idmtools_platform_comps/comps_operations/simulation_operations.py +678 -0
- idmtools_platform_comps/comps_operations/suite_operations.py +228 -0
- idmtools_platform_comps/comps_operations/workflow_item_operations.py +269 -0
- idmtools_platform_comps/comps_platform.py +309 -0
- idmtools_platform_comps/plugin_info.py +168 -0
- idmtools_platform_comps/ssmt_operations/__init__.py +6 -0
- idmtools_platform_comps/ssmt_operations/simulation_operations.py +77 -0
- idmtools_platform_comps/ssmt_operations/workflow_item_operations.py +73 -0
- idmtools_platform_comps/ssmt_platform.py +44 -0
- idmtools_platform_comps/ssmt_work_items/__init__.py +4 -0
- idmtools_platform_comps/ssmt_work_items/comps_work_order_task.py +29 -0
- idmtools_platform_comps/ssmt_work_items/comps_workitems.py +113 -0
- idmtools_platform_comps/ssmt_work_items/icomps_workflowitem.py +71 -0
- idmtools_platform_comps/ssmt_work_items/work_order.py +54 -0
- idmtools_platform_comps/utils/__init__.py +4 -0
- idmtools_platform_comps/utils/assetize_output/__init__.py +4 -0
- idmtools_platform_comps/utils/assetize_output/assetize_output.py +125 -0
- idmtools_platform_comps/utils/assetize_output/assetize_ssmt_script.py +144 -0
- idmtools_platform_comps/utils/base_singularity_work_order.json +6 -0
- idmtools_platform_comps/utils/download/__init__.py +4 -0
- idmtools_platform_comps/utils/download/download.py +178 -0
- idmtools_platform_comps/utils/download/download_ssmt.py +81 -0
- idmtools_platform_comps/utils/download_experiment.py +116 -0
- idmtools_platform_comps/utils/file_filter_workitem.py +519 -0
- idmtools_platform_comps/utils/general.py +358 -0
- idmtools_platform_comps/utils/linux_mounts.py +73 -0
- idmtools_platform_comps/utils/lookups.py +123 -0
- idmtools_platform_comps/utils/package_version.py +489 -0
- idmtools_platform_comps/utils/python_requirements_ac/__init__.py +4 -0
- idmtools_platform_comps/utils/python_requirements_ac/create_asset_collection.py +155 -0
- idmtools_platform_comps/utils/python_requirements_ac/install_requirements.py +109 -0
- idmtools_platform_comps/utils/python_requirements_ac/requirements_to_asset_collection.py +374 -0
- idmtools_platform_comps/utils/python_version.py +40 -0
- idmtools_platform_comps/utils/scheduling.py +154 -0
- idmtools_platform_comps/utils/singularity_build.py +491 -0
- idmtools_platform_comps/utils/spatial_output.py +76 -0
- idmtools_platform_comps/utils/ssmt_utils/__init__.py +6 -0
- idmtools_platform_comps/utils/ssmt_utils/common.py +70 -0
- idmtools_platform_comps/utils/ssmt_utils/file_filter.py +568 -0
- idmtools_platform_comps/utils/sweeping.py +162 -0
- idmtools_platform_comps-0.0.2.dist-info/METADATA +100 -0
- idmtools_platform_comps-0.0.2.dist-info/RECORD +62 -0
- idmtools_platform_comps-0.0.2.dist-info/entry_points.txt +9 -0
- idmtools_platform_comps-0.0.2.dist-info/licenses/LICENSE.TXT +3 -0
- {idmtools_platform_comps-0.0.0.dev0.dist-info → idmtools_platform_comps-0.0.2.dist-info}/top_level.txt +1 -0
- ssmt_image/Dockerfile +52 -0
- ssmt_image/Makefile +21 -0
- ssmt_image/__init__.py +6 -0
- ssmt_image/bootstrap.sh +30 -0
- ssmt_image/build_docker_image.py +161 -0
- ssmt_image/pip.conf +3 -0
- ssmt_image/push_docker_image.py +49 -0
- ssmt_image/requirements.txt +9 -0
- idmtools_platform_comps-0.0.0.dev0.dist-info/METADATA +0 -41
- idmtools_platform_comps-0.0.0.dev0.dist-info/RECORD +0 -5
- {idmtools_platform_comps-0.0.0.dev0.dist-info → idmtools_platform_comps-0.0.2.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"""idmtools comps suite operations.
|
|
2
|
+
|
|
3
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
4
|
+
"""
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Any, List, Dict, Tuple, Union, Type, TYPE_CHECKING, Optional
|
|
7
|
+
from uuid import UUID
|
|
8
|
+
from logging import getLogger
|
|
9
|
+
from COMPS.Data import Suite as COMPSSuite, QueryCriteria, Experiment as COMPSExperiment, WorkItem
|
|
10
|
+
from idmtools.core import ItemType
|
|
11
|
+
from idmtools.entities import Suite
|
|
12
|
+
from idmtools.entities.iplatform_ops.iplatform_suite_operations import IPlatformSuiteOperations
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
15
|
+
from idmtools_platform_comps.comps_platform import COMPSPlatform
|
|
16
|
+
|
|
17
|
+
logger = getLogger(__name__)
|
|
18
|
+
user_logger = getLogger('user')
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class CompsPlatformSuiteOperations(IPlatformSuiteOperations):
|
|
23
|
+
"""
|
|
24
|
+
Provides Suite operation to the COMPSPlatform.
|
|
25
|
+
"""
|
|
26
|
+
platform: 'COMPSPlatform' # noqa F821
|
|
27
|
+
platform_type: Type = field(default=COMPSSuite)
|
|
28
|
+
|
|
29
|
+
def get(self, suite_id: UUID, columns: Optional[List[str]] = None, load_children: Optional[List[str]] = None,
|
|
30
|
+
query_criteria: Optional[QueryCriteria] = None, **kwargs) -> COMPSSuite:
|
|
31
|
+
"""
|
|
32
|
+
Get COMPS Suite.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
suite_id: Suite id
|
|
36
|
+
columns: Optional list of columns. Defaults to id and name
|
|
37
|
+
load_children: Optional list of children to load. Defaults to "tags", "configuration"
|
|
38
|
+
query_criteria: Optional query criteria
|
|
39
|
+
**kwargs:
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
COMPSSuite
|
|
43
|
+
"""
|
|
44
|
+
columns = columns or ["id", "name"]
|
|
45
|
+
children = load_children if load_children is not None else ["tags", "configuration"]
|
|
46
|
+
# Comps doesn't like getting uuids for some reason
|
|
47
|
+
query_criteria = query_criteria or QueryCriteria().select(columns).select_children(children)
|
|
48
|
+
s = COMPSSuite.get(id=str(suite_id), query_criteria=query_criteria)
|
|
49
|
+
return s
|
|
50
|
+
|
|
51
|
+
def platform_create(self, suite: Suite, **kwargs) -> Tuple[COMPSSuite, UUID]:
|
|
52
|
+
"""
|
|
53
|
+
Create suite on COMPS.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
suite: Suite to create
|
|
57
|
+
**kwargs:
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
COMPS Suite object and a UUID
|
|
61
|
+
"""
|
|
62
|
+
self.platform._login()
|
|
63
|
+
|
|
64
|
+
# Create suite
|
|
65
|
+
comps_suite = COMPSSuite(name=suite.name, description=suite.description)
|
|
66
|
+
comps_suite.set_tags(suite.tags)
|
|
67
|
+
comps_suite.save()
|
|
68
|
+
|
|
69
|
+
# Update suite uid
|
|
70
|
+
suite.uid = comps_suite.id
|
|
71
|
+
return comps_suite, suite.uid
|
|
72
|
+
|
|
73
|
+
def get_parent(self, suite: COMPSSuite, **kwargs) -> Any:
|
|
74
|
+
"""
|
|
75
|
+
Get parent of suite. We always return None on COMPS.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
suite:Suite to get parent of
|
|
79
|
+
**kwargs:
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
None
|
|
83
|
+
"""
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
def get_children(self, suite: COMPSSuite, **kwargs) -> List[Union[COMPSExperiment, WorkItem]]:
|
|
87
|
+
"""
|
|
88
|
+
Get children for a suite.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
suite: Suite to get children for
|
|
92
|
+
**kwargs: Any arguments to pass on to loading functions
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
List of COMPS Experiments/Workitems that are part of the suite
|
|
96
|
+
"""
|
|
97
|
+
cols = kwargs.get("cols")
|
|
98
|
+
children = kwargs.get("children")
|
|
99
|
+
cols = cols or ["id", "name", "suite_id"]
|
|
100
|
+
children = children if children is not None else ["tags"]
|
|
101
|
+
|
|
102
|
+
children = suite.get_experiments(query_criteria=QueryCriteria().select(cols).select_children(children))
|
|
103
|
+
return children
|
|
104
|
+
|
|
105
|
+
def refresh_status(self, suite: Suite, **kwargs):
|
|
106
|
+
"""
|
|
107
|
+
Refresh the status of a suite. On comps, this is done by refreshing all experiments.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
suite: Suite to refresh status of
|
|
111
|
+
**kwargs:
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
None
|
|
115
|
+
"""
|
|
116
|
+
for experiment in suite.experiments:
|
|
117
|
+
self.platform.refresh_status(experiment)
|
|
118
|
+
|
|
119
|
+
def to_entity(self, suite: COMPSSuite, children: bool = True, **kwargs) -> Suite:
|
|
120
|
+
"""
|
|
121
|
+
Convert a COMPS Suite to an IDM Suite.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
suite: Suite to Convert
|
|
125
|
+
children: When true, load simulations, false otherwise
|
|
126
|
+
**kwargs:
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
IDM Suite
|
|
130
|
+
"""
|
|
131
|
+
# Creat a suite
|
|
132
|
+
obj = Suite()
|
|
133
|
+
|
|
134
|
+
# Set its correct attributes
|
|
135
|
+
obj.uid = suite.id
|
|
136
|
+
obj.name = suite.name
|
|
137
|
+
obj.description = suite.description
|
|
138
|
+
obj.tags = suite.tags
|
|
139
|
+
obj._platform_object = suite
|
|
140
|
+
|
|
141
|
+
# Convert all experiments
|
|
142
|
+
if children:
|
|
143
|
+
comps_exps = suite.get_experiments()
|
|
144
|
+
obj.experiments = []
|
|
145
|
+
for exp in comps_exps:
|
|
146
|
+
self.platform._experiments.to_entity(exp, parent=obj, **kwargs)
|
|
147
|
+
return obj
|
|
148
|
+
|
|
149
|
+
def create_sim_directory_map(self, suite_id: str) -> Dict:
|
|
150
|
+
"""
|
|
151
|
+
Build simulation working directory mapping.
|
|
152
|
+
Args:
|
|
153
|
+
suite_id: suite id
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
Dict of simulation id as key and working dir as value
|
|
157
|
+
"""
|
|
158
|
+
# s = Suite.get(suite_id)
|
|
159
|
+
comps_suite = self.platform.get_item(suite_id, ItemType.SUITE, raw=True, force=True)
|
|
160
|
+
comps_exps = comps_suite.get_experiments(QueryCriteria().select('id'))
|
|
161
|
+
sims_map = {}
|
|
162
|
+
for exp in comps_exps:
|
|
163
|
+
r = self.platform._experiments.create_sim_directory_map(exp.id)
|
|
164
|
+
sims_map = {**sims_map, **r}
|
|
165
|
+
return sims_map
|
|
166
|
+
|
|
167
|
+
def platform_delete(self, suite_id: str) -> None:
|
|
168
|
+
"""
|
|
169
|
+
Delete platform suite.
|
|
170
|
+
Args:
|
|
171
|
+
suite_id: platform suite id
|
|
172
|
+
Returns:
|
|
173
|
+
None
|
|
174
|
+
"""
|
|
175
|
+
try:
|
|
176
|
+
comps_suite = self.platform.get_item(suite_id, ItemType.SUITE, raw=True)
|
|
177
|
+
except RuntimeError:
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
comps_exps = comps_suite.get_experiments()
|
|
181
|
+
for comps_exp in comps_exps:
|
|
182
|
+
try:
|
|
183
|
+
comps_exp.delete()
|
|
184
|
+
except RuntimeError:
|
|
185
|
+
logger.info(f"Could not delete the associated experiment ({comps_exp.id})...")
|
|
186
|
+
return
|
|
187
|
+
try:
|
|
188
|
+
comps_suite.delete()
|
|
189
|
+
except RuntimeError:
|
|
190
|
+
logger.info(f"Could not delete suite ({suite_id})...")
|
|
191
|
+
return
|
|
192
|
+
|
|
193
|
+
def get_assets(self, suite: Suite, files: List[str], **kwargs) -> Dict[str, bytearray]:
|
|
194
|
+
"""
|
|
195
|
+
Fetch the files associated with a suite.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
suite (Suite): The suite object.
|
|
199
|
+
files (List[str]): List of filenames to download.
|
|
200
|
+
**kwargs: Additional keyword arguments for platform-specific options.
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
Dict[str, Dict[str, Dict[str, Dict[str, Union[str, bytearray]]]]]: A nested dictionary structured as::
|
|
204
|
+
|
|
205
|
+
{
|
|
206
|
+
"suite_id": {
|
|
207
|
+
"experiment_id": {
|
|
208
|
+
"simulation_id": {
|
|
209
|
+
"filename": file_content,
|
|
210
|
+
...
|
|
211
|
+
},
|
|
212
|
+
...
|
|
213
|
+
},
|
|
214
|
+
...
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
File content may be returned as either a decoded string or a bytearray.
|
|
219
|
+
"""
|
|
220
|
+
ret = dict()
|
|
221
|
+
if isinstance(suite, COMPSSuite):
|
|
222
|
+
comps_suite = suite
|
|
223
|
+
else:
|
|
224
|
+
comps_suite = suite.get_platform_object()
|
|
225
|
+
children = self.platform._get_children_for_platform_item(comps_suite)
|
|
226
|
+
for child in children:
|
|
227
|
+
ret[child.id] = self.platform._experiments.get_assets(child, files, **kwargs)
|
|
228
|
+
return ret
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"""idmtools comps workflow item operations.
|
|
2
|
+
|
|
3
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
4
|
+
"""
|
|
5
|
+
import json
|
|
6
|
+
import typing
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from logging import getLogger, DEBUG
|
|
9
|
+
from typing import Any, Dict, List, Tuple, Type, Optional
|
|
10
|
+
from uuid import UUID
|
|
11
|
+
from COMPS.Data import QueryCriteria, WorkItem as COMPSWorkItem, WorkItemFile
|
|
12
|
+
from COMPS.Data.WorkItem import RelationType, WorkerOrPluginKey
|
|
13
|
+
from idmtools import IdmConfigParser
|
|
14
|
+
from idmtools.assets import AssetCollection
|
|
15
|
+
from idmtools.core import ItemType
|
|
16
|
+
from idmtools.core.interfaces.ientity import IEntity
|
|
17
|
+
from idmtools.entities.generic_workitem import GenericWorkItem
|
|
18
|
+
from idmtools.entities.iplatform_ops.iplatform_workflowitem_operations import IPlatformWorkflowItemOperations
|
|
19
|
+
from idmtools.entities.iworkflow_item import IWorkflowItem
|
|
20
|
+
from idmtools_platform_comps.utils.general import convert_comps_workitem_status
|
|
21
|
+
|
|
22
|
+
if typing.TYPE_CHECKING:
|
|
23
|
+
from idmtools_platform_comps.comps_platform import COMPSPlatform
|
|
24
|
+
|
|
25
|
+
logger = getLogger(__name__)
|
|
26
|
+
user_logger = getLogger('user')
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class CompsPlatformWorkflowItemOperations(IPlatformWorkflowItemOperations):
|
|
31
|
+
"""Provides IWorkflowItem COMPSPlatform."""
|
|
32
|
+
platform: 'COMPSPlatform' # noqa F821
|
|
33
|
+
platform_type: Type = field(default=COMPSWorkItem)
|
|
34
|
+
|
|
35
|
+
def get(self, workflow_item_id: UUID, columns: Optional[List[str]] = None, load_children: Optional[List[str]] = None,
|
|
36
|
+
query_criteria: Optional[QueryCriteria] = None, **kwargs) -> \
|
|
37
|
+
COMPSWorkItem:
|
|
38
|
+
"""
|
|
39
|
+
Get COMPSWorkItem.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
workflow_item_id: Item id
|
|
43
|
+
columns: Optional columns to load. Defaults to "id", "name", "state"
|
|
44
|
+
load_children: Optional list of COMPS Children objects to load. Defaults to "Tags"
|
|
45
|
+
query_criteria: Optional QueryCriteria
|
|
46
|
+
**kwargs:
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
COMPSWorkItem
|
|
50
|
+
"""
|
|
51
|
+
columns = columns or ["id", "name", "state", "environment_name"]
|
|
52
|
+
load_children = load_children if load_children is not None else ["tags"]
|
|
53
|
+
query_criteria = query_criteria or QueryCriteria().select(columns).select_children(load_children)
|
|
54
|
+
return COMPSWorkItem.get(workflow_item_id, query_criteria=query_criteria)
|
|
55
|
+
|
|
56
|
+
def platform_create(self, work_item: IWorkflowItem, **kwargs) -> Tuple[Any]:
|
|
57
|
+
"""
|
|
58
|
+
Creates an workflow_item from an IDMTools work_item object.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
work_item: WorkflowItem to create
|
|
62
|
+
**kwargs: Optional arguments mainly for extensibility
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
Created platform item and the UUID of said item
|
|
66
|
+
"""
|
|
67
|
+
self.send_assets(work_item)
|
|
68
|
+
|
|
69
|
+
if logger.isEnabledFor(DEBUG):
|
|
70
|
+
logger.debug(f"Creating workitem {work_item.name} of type {work_item.work_item_type}, "
|
|
71
|
+
f"{work_item.plugin_key} in {self.platform.environment}")
|
|
72
|
+
# Create a WorkItem
|
|
73
|
+
wi = COMPSWorkItem(name=work_item.name,
|
|
74
|
+
worker=WorkerOrPluginKey(work_item.work_item_type, work_item.plugin_key),
|
|
75
|
+
environment_name=self.platform.environment,
|
|
76
|
+
asset_collection_id=work_item.assets.id if len(work_item.assets) else None)
|
|
77
|
+
|
|
78
|
+
# Set tags
|
|
79
|
+
wi.set_tags({})
|
|
80
|
+
if work_item.tags:
|
|
81
|
+
wi.set_tags(work_item.tags)
|
|
82
|
+
|
|
83
|
+
# Update tags
|
|
84
|
+
wi.tags.update({'WorkItem_Type': work_item.work_item_type})
|
|
85
|
+
|
|
86
|
+
# Add work order file
|
|
87
|
+
wo = work_item.get_base_work_order()
|
|
88
|
+
wo.update(work_item.work_order)
|
|
89
|
+
wi.add_work_order(data=json.dumps(wo).encode('utf-8'))
|
|
90
|
+
|
|
91
|
+
# Add additional files
|
|
92
|
+
for af in work_item.transient_assets:
|
|
93
|
+
wi_file = WorkItemFile(af.filename, "input")
|
|
94
|
+
# Either the file has an absolute path or content
|
|
95
|
+
if af.absolute_path:
|
|
96
|
+
wi.add_file(wi_file, af.absolute_path)
|
|
97
|
+
else:
|
|
98
|
+
wi.add_file(wi_file, data=af.bytes)
|
|
99
|
+
|
|
100
|
+
if logger.isEnabledFor(DEBUG):
|
|
101
|
+
logger.debug("Sending workitem to COMPS")
|
|
102
|
+
# Save the work-item to the server
|
|
103
|
+
wi.save()
|
|
104
|
+
wi.refresh()
|
|
105
|
+
|
|
106
|
+
if logger.isEnabledFor(DEBUG):
|
|
107
|
+
logger.debug("Set the relationships")
|
|
108
|
+
|
|
109
|
+
# Ensure any items that are objects are converted to ids
|
|
110
|
+
for attr_name in ['related_experiments', 'related_simulations', 'related_work_items', 'related_asset_collections']:
|
|
111
|
+
if getattr(work_item, attr_name):
|
|
112
|
+
for item in getattr(work_item, attr_name):
|
|
113
|
+
getattr(wi, f'add_{attr_name[:-1]}')(item.id if isinstance(item, IEntity) else item, RelationType.DependsOn)
|
|
114
|
+
|
|
115
|
+
wi.save()
|
|
116
|
+
|
|
117
|
+
# Set the ID back in the object
|
|
118
|
+
work_item.uid = wi.id
|
|
119
|
+
|
|
120
|
+
return work_item
|
|
121
|
+
|
|
122
|
+
def platform_run_item(self, work_item: IWorkflowItem, **kwargs):
|
|
123
|
+
"""
|
|
124
|
+
Start to rum COMPS WorkItem created from work_item.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
work_item: workflow item
|
|
128
|
+
|
|
129
|
+
Returns: None
|
|
130
|
+
"""
|
|
131
|
+
work_item.get_platform_object().commission()
|
|
132
|
+
if IdmConfigParser.is_output_enabled():
|
|
133
|
+
user_logger.info(
|
|
134
|
+
f"\nThe running WorkItem can be viewed at {self.platform.get_workitem_link(work_item)}\n"
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
def get_parent(self, work_item: IWorkflowItem, **kwargs) -> Any:
|
|
138
|
+
"""
|
|
139
|
+
Returns the parent of item. If the platform doesn't support parents, you should throw a TopLevelItem error.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
work_item: COMPS WorkItem
|
|
143
|
+
**kwargs: Optional arguments mainly for extensibility
|
|
144
|
+
|
|
145
|
+
Returns: item parent
|
|
146
|
+
|
|
147
|
+
Raise:
|
|
148
|
+
TopLevelItem
|
|
149
|
+
"""
|
|
150
|
+
return None
|
|
151
|
+
|
|
152
|
+
def get_children(self, work_item: IWorkflowItem, **kwargs) -> List[Any]:
|
|
153
|
+
"""
|
|
154
|
+
Returns the children of an workflow_item object.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
work_item: WorkflowItem object
|
|
158
|
+
**kwargs: Optional arguments mainly for extensibility
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
Children of work_item object
|
|
162
|
+
"""
|
|
163
|
+
return None
|
|
164
|
+
|
|
165
|
+
def refresh_status(self, workflow_item: IWorkflowItem, **kwargs):
|
|
166
|
+
"""
|
|
167
|
+
Refresh status for workflow item.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
work_item: Item to refresh status for
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
None
|
|
174
|
+
"""
|
|
175
|
+
wi = self.get(workflow_item.uid, columns=["id", "state"], load_children=[])
|
|
176
|
+
workflow_item.status = convert_comps_workitem_status(wi.state) # convert_COMPS_status(wi.state)
|
|
177
|
+
|
|
178
|
+
def send_assets(self, workflow_item: IWorkflowItem, **kwargs):
|
|
179
|
+
"""
|
|
180
|
+
Add asset as WorkItemFile.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
workflow_item: workflow item
|
|
184
|
+
|
|
185
|
+
Returns: None
|
|
186
|
+
"""
|
|
187
|
+
# Collect asset files
|
|
188
|
+
if workflow_item.assets and len(workflow_item.assets):
|
|
189
|
+
if logger.isEnabledFor(DEBUG):
|
|
190
|
+
logger.debug("Uploading assets for Workitem")
|
|
191
|
+
self.platform._assets.create(workflow_item.assets)
|
|
192
|
+
|
|
193
|
+
def list_assets(self, workflow_item: IWorkflowItem, **kwargs) -> List[str]:
|
|
194
|
+
"""
|
|
195
|
+
Get list of asset files.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
workflow_item: workflow item
|
|
199
|
+
**kwargs: Optional arguments mainly for extensibility
|
|
200
|
+
|
|
201
|
+
Returns: list of assets associated with WorkItem
|
|
202
|
+
"""
|
|
203
|
+
wi: COMPSWorkItem = workflow_item.get_platform_object()
|
|
204
|
+
return wi.files
|
|
205
|
+
|
|
206
|
+
def get_assets(self, workflow_item: IWorkflowItem, files: List[str], **kwargs) -> Dict[str, bytearray]:
|
|
207
|
+
"""
|
|
208
|
+
Retrieve files association with WorkItem.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
workflow_item: workflow item
|
|
212
|
+
files: list of file paths
|
|
213
|
+
**kwargs: Optional arguments mainly for extensibility
|
|
214
|
+
|
|
215
|
+
Returns: dict with key/value: file_path/file_content
|
|
216
|
+
"""
|
|
217
|
+
byte_arrs = workflow_item.retrieve_output_files(files)
|
|
218
|
+
return dict(zip(files, byte_arrs))
|
|
219
|
+
|
|
220
|
+
def to_entity(self, work_item: COMPSWorkItem, **kwargs) -> IWorkflowItem:
|
|
221
|
+
"""
|
|
222
|
+
Converts the platform representation of workflow_item to idmtools representation.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
work_item:Platform workflow_item object
|
|
226
|
+
kwargs: optional arguments mainly for extensibility
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
IDMTools workflow item
|
|
230
|
+
"""
|
|
231
|
+
# Creat a workflow item
|
|
232
|
+
# Eventually it would be nice to put the actual command here, but this requires fetching the work-order which is a bit to much overhead
|
|
233
|
+
obj = GenericWorkItem(name=work_item.name, command="")
|
|
234
|
+
|
|
235
|
+
# Set its correct attributes
|
|
236
|
+
obj.platform = self.platform
|
|
237
|
+
obj._platform_object = work_item
|
|
238
|
+
obj.uid = work_item.id
|
|
239
|
+
if work_item.asset_collection_id:
|
|
240
|
+
obj.assets = AssetCollection.from_id(work_item.asset_collection_id, platform=self.platform)
|
|
241
|
+
if work_item.files:
|
|
242
|
+
obj.transient_assets = self.platform._assets.to_entity(work_item.files)
|
|
243
|
+
obj.tags = work_item.tags
|
|
244
|
+
obj.status = convert_comps_workitem_status(work_item.state)
|
|
245
|
+
return obj
|
|
246
|
+
|
|
247
|
+
# def platform_run_item(self, workflow_item: IWorkflowItem, **kwargs):
|
|
248
|
+
# raise NotImplementedError("Running workflow items is not supported")
|
|
249
|
+
|
|
250
|
+
def get_related_items(self, item: IWorkflowItem, relation_type: RelationType) -> Dict[str, List[Dict[str, str]]]:
|
|
251
|
+
"""
|
|
252
|
+
Get related WorkItems, Suites, Experiments, Simulations and AssetCollections.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
item: workflow item
|
|
256
|
+
relation_type: RelationType
|
|
257
|
+
|
|
258
|
+
Returns: Dict
|
|
259
|
+
"""
|
|
260
|
+
wi = self.platform.get_item(item.uid, ItemType.WORKFLOW_ITEM, raw=True)
|
|
261
|
+
|
|
262
|
+
ret = {}
|
|
263
|
+
ret['work_item'] = wi.get_related_work_items(relation_type)
|
|
264
|
+
ret['suite'] = wi.get_related_suites(relation_type)
|
|
265
|
+
ret['experiment'] = wi.get_related_experiments(relation_type)
|
|
266
|
+
ret['simulation'] = wi.get_related_simulations(relation_type)
|
|
267
|
+
ret['asset_collection'] = wi.get_related_asset_collections(relation_type)
|
|
268
|
+
|
|
269
|
+
return ret
|