idmtools 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/__init__.py +27 -8
- idmtools/analysis/__init__.py +5 -0
- idmtools/analysis/add_analyzer.py +89 -0
- idmtools/analysis/analyze_manager.py +490 -0
- idmtools/analysis/csv_analyzer.py +103 -0
- idmtools/analysis/download_analyzer.py +96 -0
- idmtools/analysis/map_worker_entry.py +100 -0
- idmtools/analysis/platform_analysis_bootstrap.py +94 -0
- idmtools/analysis/platform_anaylsis.py +291 -0
- idmtools/analysis/tags_analyzer.py +93 -0
- idmtools/assets/__init__.py +9 -0
- idmtools/assets/asset.py +453 -0
- idmtools/assets/asset_collection.py +514 -0
- idmtools/assets/content_handlers.py +19 -0
- idmtools/assets/errors.py +23 -0
- idmtools/assets/file_list.py +191 -0
- idmtools/builders/__init__.py +11 -0
- idmtools/builders/arm_simulation_builder.py +152 -0
- idmtools/builders/csv_simulation_builder.py +76 -0
- idmtools/builders/simulation_builder.py +348 -0
- idmtools/builders/sweep_arm.py +109 -0
- idmtools/builders/yaml_simulation_builder.py +82 -0
- idmtools/config/__init__.py +7 -0
- idmtools/config/idm_config_parser.py +486 -0
- idmtools/core/__init__.py +10 -0
- idmtools/core/cache_enabled.py +114 -0
- idmtools/core/context.py +68 -0
- idmtools/core/docker_task.py +207 -0
- idmtools/core/enums.py +51 -0
- idmtools/core/exceptions.py +91 -0
- idmtools/core/experiment_factory.py +71 -0
- idmtools/core/id_file.py +70 -0
- idmtools/core/interfaces/__init__.py +5 -0
- idmtools/core/interfaces/entity_container.py +64 -0
- idmtools/core/interfaces/iassets_enabled.py +58 -0
- idmtools/core/interfaces/ientity.py +331 -0
- idmtools/core/interfaces/iitem.py +206 -0
- idmtools/core/interfaces/imetadata_operations.py +89 -0
- idmtools/core/interfaces/inamed_entity.py +17 -0
- idmtools/core/interfaces/irunnable_entity.py +159 -0
- idmtools/core/logging.py +387 -0
- idmtools/core/platform_factory.py +316 -0
- idmtools/core/system_information.py +104 -0
- idmtools/core/task_factory.py +145 -0
- idmtools/entities/__init__.py +10 -0
- idmtools/entities/command_line.py +229 -0
- idmtools/entities/command_task.py +155 -0
- idmtools/entities/experiment.py +787 -0
- idmtools/entities/generic_workitem.py +43 -0
- idmtools/entities/ianalyzer.py +163 -0
- idmtools/entities/iplatform.py +1106 -0
- idmtools/entities/iplatform_default.py +39 -0
- idmtools/entities/iplatform_ops/__init__.py +5 -0
- idmtools/entities/iplatform_ops/iplatform_asset_collection_operations.py +148 -0
- idmtools/entities/iplatform_ops/iplatform_experiment_operations.py +415 -0
- idmtools/entities/iplatform_ops/iplatform_simulation_operations.py +315 -0
- idmtools/entities/iplatform_ops/iplatform_suite_operations.py +322 -0
- idmtools/entities/iplatform_ops/iplatform_workflowitem_operations.py +301 -0
- idmtools/entities/iplatform_ops/utils.py +185 -0
- idmtools/entities/itask.py +316 -0
- idmtools/entities/iworkflow_item.py +167 -0
- idmtools/entities/platform_requirements.py +20 -0
- idmtools/entities/relation_type.py +14 -0
- idmtools/entities/simulation.py +255 -0
- idmtools/entities/suite.py +188 -0
- idmtools/entities/task_proxy.py +37 -0
- idmtools/entities/templated_simulation.py +325 -0
- idmtools/frozen/frozen_dict.py +71 -0
- idmtools/frozen/frozen_list.py +66 -0
- idmtools/frozen/frozen_set.py +86 -0
- idmtools/frozen/frozen_tuple.py +18 -0
- idmtools/frozen/frozen_utils.py +179 -0
- idmtools/frozen/ifrozen.py +66 -0
- idmtools/plugins/__init__.py +5 -0
- idmtools/plugins/git_commit.py +117 -0
- idmtools/registry/__init__.py +4 -0
- idmtools/registry/experiment_specification.py +105 -0
- idmtools/registry/functions.py +28 -0
- idmtools/registry/hook_specs.py +132 -0
- idmtools/registry/master_plugin_registry.py +51 -0
- idmtools/registry/platform_specification.py +138 -0
- idmtools/registry/plugin_specification.py +129 -0
- idmtools/registry/task_specification.py +104 -0
- idmtools/registry/utils.py +119 -0
- idmtools/services/__init__.py +5 -0
- idmtools/services/ipersistance_service.py +135 -0
- idmtools/services/platforms.py +13 -0
- idmtools/utils/__init__.py +5 -0
- idmtools/utils/caller.py +24 -0
- idmtools/utils/collections.py +246 -0
- idmtools/utils/command_line.py +45 -0
- idmtools/utils/decorators.py +300 -0
- idmtools/utils/display/__init__.py +22 -0
- idmtools/utils/display/displays.py +181 -0
- idmtools/utils/display/settings.py +25 -0
- idmtools/utils/dropbox_location.py +30 -0
- idmtools/utils/entities.py +127 -0
- idmtools/utils/file.py +72 -0
- idmtools/utils/file_parser.py +151 -0
- idmtools/utils/filter_simulations.py +182 -0
- idmtools/utils/filters/__init__.py +5 -0
- idmtools/utils/filters/asset_filters.py +88 -0
- idmtools/utils/general.py +286 -0
- idmtools/utils/gitrepo.py +336 -0
- idmtools/utils/hashing.py +239 -0
- idmtools/utils/info.py +124 -0
- idmtools/utils/json.py +82 -0
- idmtools/utils/language.py +107 -0
- idmtools/utils/local_os.py +40 -0
- idmtools/utils/time.py +22 -0
- idmtools-0.0.2.dist-info/METADATA +120 -0
- idmtools-0.0.2.dist-info/RECORD +116 -0
- idmtools-0.0.2.dist-info/entry_points.txt +9 -0
- idmtools-0.0.2.dist-info/licenses/LICENSE.TXT +3 -0
- idmtools-0.0.0.dev0.dist-info/METADATA +0 -41
- idmtools-0.0.0.dev0.dist-info/RECORD +0 -5
- {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.2.dist-info}/WHEEL +0 -0
- {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"""
|
|
2
|
+
frozen_utils provided utilities for a read-only objects.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from idmtools.frozen.frozen_dict import ImDict
|
|
8
|
+
from idmtools.frozen.frozen_list import ImList
|
|
9
|
+
from idmtools.frozen.frozen_set import ImSet
|
|
10
|
+
from idmtools.frozen.frozen_tuple import ImTuple
|
|
11
|
+
from idmtools.frozen.ifrozen import IFrozen
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_frozen_item(obj):
|
|
15
|
+
"""
|
|
16
|
+
Get frozen version of item.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
obj: object to be frozen
|
|
20
|
+
|
|
21
|
+
Returns: the transformed object
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
class FrozenDict(ImDict):
|
|
25
|
+
def __init__(self):
|
|
26
|
+
super().__init__()
|
|
27
|
+
for key, value in obj.items():
|
|
28
|
+
self.data[key] = frozen_transform(value)
|
|
29
|
+
|
|
30
|
+
# In case inherited from dict with customer fields
|
|
31
|
+
if hasattr(obj, '__dict__'):
|
|
32
|
+
for key, value in obj.__dict__.items():
|
|
33
|
+
setattr(self, key, frozen_transform(value))
|
|
34
|
+
|
|
35
|
+
self._frozen = True
|
|
36
|
+
|
|
37
|
+
class FrozenList(ImList):
|
|
38
|
+
def __init__(self):
|
|
39
|
+
super().__init__()
|
|
40
|
+
for value in obj:
|
|
41
|
+
self.data.append(frozen_transform(value))
|
|
42
|
+
|
|
43
|
+
# In case inherited from list with customer fields
|
|
44
|
+
if hasattr(obj, '__dict__'):
|
|
45
|
+
for key, value in obj.__dict__.items():
|
|
46
|
+
setattr(self, key, frozen_transform(value))
|
|
47
|
+
|
|
48
|
+
self._frozen = True
|
|
49
|
+
|
|
50
|
+
class FrozenSet(ImSet):
|
|
51
|
+
def __init__(self):
|
|
52
|
+
super().__init__()
|
|
53
|
+
for value in obj:
|
|
54
|
+
self.add(frozen_transform(value))
|
|
55
|
+
|
|
56
|
+
# In case inherited from set with customer fields
|
|
57
|
+
if hasattr(obj, '__dict__'):
|
|
58
|
+
for key, value in obj.__dict__.items():
|
|
59
|
+
setattr(self, key, frozen_transform(value))
|
|
60
|
+
|
|
61
|
+
self._frozen = True
|
|
62
|
+
|
|
63
|
+
class FrozenTuple(ImTuple):
|
|
64
|
+
def __new__(cls):
|
|
65
|
+
o = ImTuple(obj)
|
|
66
|
+
|
|
67
|
+
# In case inherited from tuple with customer fields
|
|
68
|
+
if hasattr(obj, '__dict__'):
|
|
69
|
+
for key, value in obj.__dict__.items():
|
|
70
|
+
setattr(o, key, frozen_transform(value))
|
|
71
|
+
|
|
72
|
+
return ImTuple(obj)
|
|
73
|
+
|
|
74
|
+
class FrozenObject(IFrozen, obj.__class__):
|
|
75
|
+
__metaclass__ = obj.__class__
|
|
76
|
+
|
|
77
|
+
def __init__(self):
|
|
78
|
+
for key, value in obj.__dict__.items():
|
|
79
|
+
setattr(self, key, frozen_transform(value))
|
|
80
|
+
|
|
81
|
+
if isinstance(obj, dict):
|
|
82
|
+
return FrozenDict()
|
|
83
|
+
|
|
84
|
+
if isinstance(obj, list):
|
|
85
|
+
return FrozenList()
|
|
86
|
+
|
|
87
|
+
if isinstance(obj, (set, frozenset)):
|
|
88
|
+
return FrozenSet()
|
|
89
|
+
|
|
90
|
+
if isinstance(obj, tuple):
|
|
91
|
+
return FrozenTuple()
|
|
92
|
+
|
|
93
|
+
return FrozenObject()
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def is_builtins_single_object(obj):
|
|
97
|
+
"""
|
|
98
|
+
Is builtins single object?
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
obj: Object
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
True if single object
|
|
105
|
+
"""
|
|
106
|
+
# Handle special cases
|
|
107
|
+
if isinstance(obj, (Enum, range)):
|
|
108
|
+
return True
|
|
109
|
+
|
|
110
|
+
return type(obj).__module__ == 'builtins' and not is_builtins_collection(obj)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def is_builtins_collection(obj):
|
|
114
|
+
"""
|
|
115
|
+
Is object a builtin collection?
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
obj: Object
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
True if a built in collection
|
|
122
|
+
"""
|
|
123
|
+
from collections.abc import Collection
|
|
124
|
+
return isinstance(obj, Collection) and not isinstance(obj, (str, bytes, bytearray)) # range, generator, etc,...
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def is_user_defined_object(obj):
|
|
128
|
+
"""
|
|
129
|
+
Is user defined object.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
obj: Object to check
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
True if item is not a builtin type
|
|
136
|
+
"""
|
|
137
|
+
return type(obj).__module__ != 'builtins'
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def frozen_transform(obj=None):
|
|
141
|
+
"""
|
|
142
|
+
Transform item to frozen version.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
obj:Obj to transform
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
Frozen version of object
|
|
149
|
+
"""
|
|
150
|
+
if isinstance(obj, IFrozen):
|
|
151
|
+
obj.freeze()
|
|
152
|
+
return obj
|
|
153
|
+
|
|
154
|
+
if is_builtins_single_object(obj):
|
|
155
|
+
return obj
|
|
156
|
+
|
|
157
|
+
if isinstance(obj, dict):
|
|
158
|
+
imdict = get_frozen_item(obj)
|
|
159
|
+
return imdict
|
|
160
|
+
|
|
161
|
+
if isinstance(obj, list):
|
|
162
|
+
imlist = get_frozen_item(obj)
|
|
163
|
+
return imlist
|
|
164
|
+
|
|
165
|
+
if isinstance(obj, (set, frozenset)):
|
|
166
|
+
imset = get_frozen_item(obj)
|
|
167
|
+
return imset
|
|
168
|
+
|
|
169
|
+
if isinstance(obj, tuple):
|
|
170
|
+
imtuple = get_frozen_item(obj)
|
|
171
|
+
return imtuple
|
|
172
|
+
|
|
173
|
+
if not hasattr(obj, '__dict__'): # say, iterator, zip, file, function, method, etc
|
|
174
|
+
return obj
|
|
175
|
+
|
|
176
|
+
obj_new = get_frozen_item(obj)
|
|
177
|
+
obj_new._frozen = True
|
|
178
|
+
|
|
179
|
+
return obj_new
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""
|
|
2
|
+
IFrozen provided utilities for a read-only objects.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class IFrozen:
|
|
9
|
+
"""
|
|
10
|
+
Allows for frozen(read-only) items.
|
|
11
|
+
"""
|
|
12
|
+
_frozen = False
|
|
13
|
+
|
|
14
|
+
def freeze(self):
|
|
15
|
+
"""
|
|
16
|
+
Freeze the object.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
None
|
|
20
|
+
"""
|
|
21
|
+
from idmtools.frozen.frozen_utils import frozen_transform
|
|
22
|
+
|
|
23
|
+
# Make sure don't do it twice
|
|
24
|
+
if self._frozen:
|
|
25
|
+
return
|
|
26
|
+
|
|
27
|
+
if hasattr(self, '__dict__'):
|
|
28
|
+
for key, value in self.__dict__.items():
|
|
29
|
+
setattr(self, key, frozen_transform(value))
|
|
30
|
+
|
|
31
|
+
self._frozen = True
|
|
32
|
+
|
|
33
|
+
def __setattr__(self, key, value):
|
|
34
|
+
"""
|
|
35
|
+
Attempt to set attr. For frozen objects, this throws an error.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
key:
|
|
39
|
+
value:
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
None
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
ValueError - If item is frozen
|
|
46
|
+
"""
|
|
47
|
+
if self._frozen:
|
|
48
|
+
raise ValueError('Frozen')
|
|
49
|
+
super().__setattr__(key, value)
|
|
50
|
+
|
|
51
|
+
def __delattr__(self, item):
|
|
52
|
+
"""
|
|
53
|
+
Delete attr replace. Frozen doesn't allow deletes.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
item: Item to delete
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
None
|
|
60
|
+
|
|
61
|
+
Raises:
|
|
62
|
+
ValueError - Frozen
|
|
63
|
+
"""
|
|
64
|
+
if self._frozen:
|
|
65
|
+
raise ValueError('Frozen')
|
|
66
|
+
super().__delattr__(item)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Git plugin to add git repo details to items.
|
|
3
|
+
"""
|
|
4
|
+
import functools
|
|
5
|
+
import os
|
|
6
|
+
from contextlib import suppress
|
|
7
|
+
from logging import getLogger
|
|
8
|
+
from typing import TYPE_CHECKING, Dict
|
|
9
|
+
from idmtools import IdmConfigParser
|
|
10
|
+
from idmtools.assets import AssetCollection
|
|
11
|
+
from idmtools.core import TRUTHY_VALUES
|
|
12
|
+
from idmtools.registry.hook_specs import function_hook_impl
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from idmtools.core.interfaces.ientity import IEntity
|
|
16
|
+
|
|
17
|
+
logger = getLogger(__name__)
|
|
18
|
+
user_logger = getLogger('user')
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@function_hook_impl
|
|
22
|
+
def idmtools_platform_pre_create_item(item: 'IEntity', kwargs):
|
|
23
|
+
"""
|
|
24
|
+
Adds git information from local repo as tags to items on creation.
|
|
25
|
+
|
|
26
|
+
There following options are valid kwargs and configuration options:
|
|
27
|
+
* add_git_tags_to_all - Add git tags to everything
|
|
28
|
+
* add_to_experiments - Add git tags to experiments
|
|
29
|
+
* add_git_tags_to_simulations - Add git tags to simulations
|
|
30
|
+
* add_git_tags_to_workitems - Add git tags to workitems
|
|
31
|
+
* add_git_tags_to_suite - Add git tags to suites
|
|
32
|
+
* add_git_tags_to_asset_collection - Add git tags to asset collections
|
|
33
|
+
|
|
34
|
+
Every option expects a truthy value, meaning "True, False, t, f, 1, 0, yes, or no. Any positive value, True, yes, 1, t, y will enable the option.
|
|
35
|
+
|
|
36
|
+
When defined in the idmtools.ini, these should be added under the "git_tag" section without the "git_tags" portion. For example
|
|
37
|
+
|
|
38
|
+
[git_tag]
|
|
39
|
+
add_to_experiments = y
|
|
40
|
+
|
|
41
|
+
Also, you can do this through environment variables using IDMTOOLS_GIT_TAG_<option>. For example, experiments would be
|
|
42
|
+
|
|
43
|
+
IDMTOOLS_GIT_TAG_ADD_TO_EXPERIMENTS
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
item: Item to add tags two
|
|
47
|
+
kwargs: Optional kwargs
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
None
|
|
51
|
+
"""
|
|
52
|
+
from idmtools.entities.experiment import Experiment
|
|
53
|
+
from idmtools.entities.simulation import Simulation
|
|
54
|
+
from idmtools.entities.iworkflow_item import IWorkflowItem
|
|
55
|
+
from idmtools.entities.suite import Suite
|
|
56
|
+
add_to_all_default = kwargs.get('add_git_tags_to_all', 'f')
|
|
57
|
+
add_to_simulations_default = kwargs.get('add_git_tags_to_simulations', 'f')
|
|
58
|
+
add_to_experiments_default = kwargs.get('add_git_tags_to_experiments', 'f')
|
|
59
|
+
add_to_workitems_default = kwargs.get('add_git_tags_to_workitems', 'f')
|
|
60
|
+
add_to_suite_default = kwargs.get('add_git_tags_to_suite', 'f')
|
|
61
|
+
add_to_asset_collection_default = kwargs.get('add_git_tags_to_asset_collection', 'f')
|
|
62
|
+
if IdmConfigParser.get_option("git_tag", "add_to_all", add_to_all_default) in TRUTHY_VALUES or \
|
|
63
|
+
(isinstance(item, Experiment) and IdmConfigParser.get_option("git_tag", "add_to_experiments", add_to_experiments_default) in TRUTHY_VALUES) or \
|
|
64
|
+
(isinstance(item, Simulation) and IdmConfigParser.get_option("git_tag", "add_to_simulations", add_to_simulations_default) in TRUTHY_VALUES) or \
|
|
65
|
+
(isinstance(item, IWorkflowItem) and IdmConfigParser.get_option("git_tag", "add_to_workitems", add_to_workitems_default) in TRUTHY_VALUES) or \
|
|
66
|
+
(isinstance(item, Suite) and IdmConfigParser.get_option("git_tag", "add_to_suite", add_to_suite_default) in TRUTHY_VALUES) or \
|
|
67
|
+
(isinstance(item, AssetCollection) and IdmConfigParser.get_option("git_tag", "add_to_asset_collection", add_to_asset_collection_default) in TRUTHY_VALUES):
|
|
68
|
+
tags = add_details_using_gitpython()
|
|
69
|
+
if not tags:
|
|
70
|
+
tags = add_details_using_pygit()
|
|
71
|
+
user_logger.warning("You need gitpython or pygit2 installed to have this functionality")
|
|
72
|
+
item.tags.update(tags)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@functools.lru_cache(1)
|
|
76
|
+
def add_details_using_gitpython():
|
|
77
|
+
"""
|
|
78
|
+
Support gitpython if installed.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
Git tags
|
|
82
|
+
"""
|
|
83
|
+
result = dict()
|
|
84
|
+
with suppress(ImportError):
|
|
85
|
+
import git
|
|
86
|
+
repo = git.Repo(search_parent_directories=True)
|
|
87
|
+
if repo:
|
|
88
|
+
sha = repo.head.object.hexsha
|
|
89
|
+
result['git_hash'] = sha
|
|
90
|
+
if len(repo.remotes) > 0:
|
|
91
|
+
result['git_url'] = repo.remotes[0].url
|
|
92
|
+
if repo.head.ref.name:
|
|
93
|
+
result['git_branch'] = repo.head.ref.name
|
|
94
|
+
return result
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@functools.lru_cache(1)
|
|
98
|
+
def add_details_using_pygit() -> Dict[str, str]:
|
|
99
|
+
"""
|
|
100
|
+
Support pygit if installed.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Git tags
|
|
104
|
+
"""
|
|
105
|
+
result = dict()
|
|
106
|
+
with suppress(ImportError):
|
|
107
|
+
import pygit2
|
|
108
|
+
repo_base = pygit2.discover_repository(os.getcwd())
|
|
109
|
+
if repo_base:
|
|
110
|
+
repo = pygit2.Repository(repo_base)
|
|
111
|
+
sha = repo.head.target.hex
|
|
112
|
+
result['git_hash'] = sha
|
|
113
|
+
if len(repo.remotes) > 0:
|
|
114
|
+
result['git_url'] = repo.remotes[0].url
|
|
115
|
+
if repo.head.shorthand:
|
|
116
|
+
result['git_branch'] = repo.head.shorthand
|
|
117
|
+
return result
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ExperimentPluginSpecification provided definition for the experiment plugin specification, hooks, and plugin manager.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
# Define our model specific specifications
|
|
7
|
+
import typing
|
|
8
|
+
from abc import ABC
|
|
9
|
+
from logging import getLogger
|
|
10
|
+
|
|
11
|
+
import pluggy
|
|
12
|
+
|
|
13
|
+
from idmtools.registry import PluginSpecification
|
|
14
|
+
from idmtools.registry.plugin_specification import PLUGIN_REFERENCE_NAME
|
|
15
|
+
from idmtools.registry.utils import load_plugin_map
|
|
16
|
+
|
|
17
|
+
example_configuration_spec = pluggy.HookspecMarker(PLUGIN_REFERENCE_NAME)
|
|
18
|
+
get_model_spec = pluggy.HookspecMarker(PLUGIN_REFERENCE_NAME)
|
|
19
|
+
get_model_type_spec = pluggy.HookspecMarker(PLUGIN_REFERENCE_NAME)
|
|
20
|
+
example_configuration_impl = pluggy.HookimplMarker(PLUGIN_REFERENCE_NAME)
|
|
21
|
+
get_model_impl = pluggy.HookimplMarker(PLUGIN_REFERENCE_NAME)
|
|
22
|
+
get_model_type_impl = pluggy.HookimplMarker(PLUGIN_REFERENCE_NAME)
|
|
23
|
+
logger = getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ExperimentPluginSpecification(PluginSpecification, ABC):
|
|
27
|
+
"""
|
|
28
|
+
ExperimentPluginSpecification defines the specification for Experiment plugins.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
@classmethod
|
|
32
|
+
def get_name(cls, strip_all: bool = True) -> str:
|
|
33
|
+
"""
|
|
34
|
+
Get name of plugin. By default we remove the PlatformSpecification portion.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
strip_all: When true, ExperimentPluginSpecification and ExperimentPluginSpec is stripped from name.
|
|
38
|
+
When false only Specification and Spec is Stripped
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Name of plugin
|
|
42
|
+
"""
|
|
43
|
+
if strip_all:
|
|
44
|
+
ret = cls.__name__.replace('ExperimentPluginSpecification', '').replace('Specification', '')\
|
|
45
|
+
.replace("ExperimentPluginSpec", '').replace('Spec', '')
|
|
46
|
+
else:
|
|
47
|
+
ret = cls.__name__.replace('Specification', '').replace('Spec', '')
|
|
48
|
+
return ret
|
|
49
|
+
|
|
50
|
+
@get_model_spec
|
|
51
|
+
def get(self, configuration: dict) -> 'Experiment': # noqa: F821
|
|
52
|
+
"""
|
|
53
|
+
Return a new model using the passed in configuration.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
configuration: The INI configuration file to use.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
The new model.
|
|
60
|
+
"""
|
|
61
|
+
raise NotImplementedError("Plugin did not implement get")
|
|
62
|
+
|
|
63
|
+
@get_model_type_spec
|
|
64
|
+
def get_type(self) -> typing.Type['Experiment']: # noqa: F821
|
|
65
|
+
"""
|
|
66
|
+
Get Experiment type.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
Experiment type.
|
|
70
|
+
"""
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class ExperimentPlugins:
|
|
75
|
+
"""
|
|
76
|
+
ExperimentPlugins acts as registry for Experiment plugins.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
def __init__(self, strip_all: bool = True) -> None:
|
|
80
|
+
"""
|
|
81
|
+
Initialize the Experiment Registry. When strip all is false, the full plugin name will be used for names in map.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
strip_all: Whether to strip common parts of name from plugins in plugin map
|
|
85
|
+
"""
|
|
86
|
+
self._plugins = typing.cast(typing.Dict[str, ExperimentPluginSpecification],
|
|
87
|
+
load_plugin_map('idmtools_experiment', ExperimentPluginSpecification, strip_all))
|
|
88
|
+
|
|
89
|
+
def get_plugins(self) -> typing.Set[ExperimentPluginSpecification]:
|
|
90
|
+
"""
|
|
91
|
+
Get plugins.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
Experiment plugins.
|
|
95
|
+
"""
|
|
96
|
+
return set(self._plugins.values())
|
|
97
|
+
|
|
98
|
+
def get_plugin_map(self) -> typing.Dict[str, ExperimentPluginSpecification]:
|
|
99
|
+
"""
|
|
100
|
+
Get experiment plugin map.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Experiment plugin map.
|
|
104
|
+
"""
|
|
105
|
+
return self._plugins
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
FunctionPluginManager provided definition for the function plugin specification, hooks, and plugin manager.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
from logging import getLogger, DEBUG
|
|
7
|
+
|
|
8
|
+
from pluggy import PluginManager
|
|
9
|
+
import idmtools.registry.hook_specs as hookspecs
|
|
10
|
+
from idmtools.utils.decorators import SingletonMixin
|
|
11
|
+
|
|
12
|
+
logger = getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class FunctionPluginManager(PluginManager, SingletonMixin):
|
|
16
|
+
"""
|
|
17
|
+
FunctionPluginManager acts as registry for function based plugins.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self):
|
|
21
|
+
"""
|
|
22
|
+
Initialize function plugin manager.
|
|
23
|
+
"""
|
|
24
|
+
super(FunctionPluginManager, self).__init__(hookspecs.IDMTOOLS_HOOKS)
|
|
25
|
+
self.add_hookspecs(hookspecs)
|
|
26
|
+
self.load_setuptools_entrypoints(hookspecs.IDMTOOLS_HOOKS.lower())
|
|
27
|
+
if logger.isEnabledFor(DEBUG):
|
|
28
|
+
logger.debug(self.get_plugins())
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Define a list of function only hook specs. Useful for simple plugins.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
from logging import getLogger
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
from pluggy import HookspecMarker, HookimplMarker
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from idmtools.core.interfaces.ientity import IEntity
|
|
12
|
+
from idmtools.core.interfaces.irunnable_entity import IRunnableEntity
|
|
13
|
+
logger = getLogger(__name__)
|
|
14
|
+
user_logger = getLogger('user')
|
|
15
|
+
|
|
16
|
+
IDMTOOLS_HOOKS = 'IDMTOOLS_HOOKS'
|
|
17
|
+
|
|
18
|
+
function_hook_spec = HookspecMarker(IDMTOOLS_HOOKS)
|
|
19
|
+
function_hook_impl = HookimplMarker(IDMTOOLS_HOOKS)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@function_hook_spec
|
|
23
|
+
def idmtools_platform_pre_create_item(item: 'IEntity', kwargs) -> 'IEntity':
|
|
24
|
+
"""
|
|
25
|
+
This callback is called by the pre_create of each object type on a platform. An item can be a suite, workitem, simulation, asset collection or an experiment.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
item:
|
|
29
|
+
kwargs: extra args
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
None
|
|
33
|
+
"""
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@function_hook_spec
|
|
38
|
+
def idmtools_platform_post_create_item(item: 'IEntity', kwargs) -> 'IEntity':
|
|
39
|
+
"""
|
|
40
|
+
This callback is called by the post_create of each object type on a platform.
|
|
41
|
+
An item can be a suite, workitem, simulation, asset collection or an experiment.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
item:
|
|
45
|
+
kwargs: extra args
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
None
|
|
49
|
+
"""
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@function_hook_spec
|
|
54
|
+
def idmtools_platform_post_run(item: 'IEntity', kwargs) -> 'IEntity':
|
|
55
|
+
"""
|
|
56
|
+
This is called when item finishes calling the run on the server.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
item:
|
|
60
|
+
kwargs: extra args
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
None
|
|
64
|
+
"""
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@function_hook_spec
|
|
69
|
+
def idmtools_on_start():
|
|
70
|
+
"""
|
|
71
|
+
Execute on startup when idmtools is first imported.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
None
|
|
75
|
+
"""
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@function_hook_spec
|
|
80
|
+
def idmtools_generate_id(item: 'IEntity') -> str:
|
|
81
|
+
"""
|
|
82
|
+
Generates an id for an IItem.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
None
|
|
86
|
+
"""
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@function_hook_spec
|
|
91
|
+
def idmtools_runnable_on_done(item: 'IRunnableEntity', **kwargs):
|
|
92
|
+
"""
|
|
93
|
+
Called when a runnable item finishes when it was being monitored.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
item: Item that was running
|
|
97
|
+
**kwargs:
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
None
|
|
101
|
+
"""
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@function_hook_spec
|
|
106
|
+
def idmtools_runnable_on_succeeded(item: 'IRunnableEntity', **kwargs):
|
|
107
|
+
"""
|
|
108
|
+
Executed when a runnable item succeeds.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
item: Item that was running
|
|
112
|
+
**kwargs:
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
None
|
|
116
|
+
"""
|
|
117
|
+
pass
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@function_hook_spec
|
|
121
|
+
def idmtools_runnable_on_failure(item: 'IRunnableEntity', **kwargs):
|
|
122
|
+
"""
|
|
123
|
+
Executed when a runnable item fails.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
item: Item that was running
|
|
127
|
+
**kwargs:
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
None
|
|
131
|
+
"""
|
|
132
|
+
pass
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Registry to aggregate all plugins to one place.
|
|
3
|
+
|
|
4
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
from typing import Dict, Set
|
|
7
|
+
from idmtools.registry import PluginSpecification
|
|
8
|
+
from idmtools.registry.experiment_specification import ExperimentPlugins
|
|
9
|
+
from idmtools.utils.decorators import SingletonMixin
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MasterPluginRegistry(SingletonMixin):
|
|
13
|
+
"""
|
|
14
|
+
MasterPluginRegistry indexes all type of plugins into one class.
|
|
15
|
+
|
|
16
|
+
Notes:
|
|
17
|
+
TODO - Rename this class
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self) -> None:
|
|
21
|
+
"""
|
|
22
|
+
Initialize Master registry.
|
|
23
|
+
"""
|
|
24
|
+
from idmtools.registry.platform_specification import PlatformPlugins
|
|
25
|
+
from idmtools.registry.task_specification import TaskPlugins
|
|
26
|
+
self._plugin_map = PlatformPlugins(strip_all=False).get_plugin_map()
|
|
27
|
+
self._plugin_map.update(TaskPlugins(strip_all=False).get_plugin_map())
|
|
28
|
+
self._plugin_map.update(ExperimentPlugins(strip_all=False).get_plugin_map())
|
|
29
|
+
try:
|
|
30
|
+
from idmtools_cli.iplatform_cli import PlatformCLIPlugins
|
|
31
|
+
self._plugin_map.update(PlatformCLIPlugins(strip_all=False).get_plugin_map())
|
|
32
|
+
except ImportError:
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
def get_plugin_map(self) -> Dict[str, PluginSpecification]:
|
|
36
|
+
"""
|
|
37
|
+
Get plugin map.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Plugin map
|
|
41
|
+
"""
|
|
42
|
+
return self._plugin_map
|
|
43
|
+
|
|
44
|
+
def get_plugins(self) -> Set[PluginSpecification]:
|
|
45
|
+
"""
|
|
46
|
+
Get Plugins map.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
The full plugin map
|
|
50
|
+
"""
|
|
51
|
+
return set(self._plugin_map.values())
|