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.
Files changed (118) hide show
  1. idmtools/__init__.py +27 -8
  2. idmtools/analysis/__init__.py +5 -0
  3. idmtools/analysis/add_analyzer.py +89 -0
  4. idmtools/analysis/analyze_manager.py +490 -0
  5. idmtools/analysis/csv_analyzer.py +103 -0
  6. idmtools/analysis/download_analyzer.py +96 -0
  7. idmtools/analysis/map_worker_entry.py +100 -0
  8. idmtools/analysis/platform_analysis_bootstrap.py +94 -0
  9. idmtools/analysis/platform_anaylsis.py +291 -0
  10. idmtools/analysis/tags_analyzer.py +93 -0
  11. idmtools/assets/__init__.py +9 -0
  12. idmtools/assets/asset.py +453 -0
  13. idmtools/assets/asset_collection.py +514 -0
  14. idmtools/assets/content_handlers.py +19 -0
  15. idmtools/assets/errors.py +23 -0
  16. idmtools/assets/file_list.py +191 -0
  17. idmtools/builders/__init__.py +11 -0
  18. idmtools/builders/arm_simulation_builder.py +152 -0
  19. idmtools/builders/csv_simulation_builder.py +76 -0
  20. idmtools/builders/simulation_builder.py +348 -0
  21. idmtools/builders/sweep_arm.py +109 -0
  22. idmtools/builders/yaml_simulation_builder.py +82 -0
  23. idmtools/config/__init__.py +7 -0
  24. idmtools/config/idm_config_parser.py +486 -0
  25. idmtools/core/__init__.py +10 -0
  26. idmtools/core/cache_enabled.py +114 -0
  27. idmtools/core/context.py +68 -0
  28. idmtools/core/docker_task.py +207 -0
  29. idmtools/core/enums.py +51 -0
  30. idmtools/core/exceptions.py +91 -0
  31. idmtools/core/experiment_factory.py +71 -0
  32. idmtools/core/id_file.py +70 -0
  33. idmtools/core/interfaces/__init__.py +5 -0
  34. idmtools/core/interfaces/entity_container.py +64 -0
  35. idmtools/core/interfaces/iassets_enabled.py +58 -0
  36. idmtools/core/interfaces/ientity.py +331 -0
  37. idmtools/core/interfaces/iitem.py +206 -0
  38. idmtools/core/interfaces/imetadata_operations.py +89 -0
  39. idmtools/core/interfaces/inamed_entity.py +17 -0
  40. idmtools/core/interfaces/irunnable_entity.py +159 -0
  41. idmtools/core/logging.py +387 -0
  42. idmtools/core/platform_factory.py +316 -0
  43. idmtools/core/system_information.py +104 -0
  44. idmtools/core/task_factory.py +145 -0
  45. idmtools/entities/__init__.py +10 -0
  46. idmtools/entities/command_line.py +229 -0
  47. idmtools/entities/command_task.py +155 -0
  48. idmtools/entities/experiment.py +787 -0
  49. idmtools/entities/generic_workitem.py +43 -0
  50. idmtools/entities/ianalyzer.py +163 -0
  51. idmtools/entities/iplatform.py +1106 -0
  52. idmtools/entities/iplatform_default.py +39 -0
  53. idmtools/entities/iplatform_ops/__init__.py +5 -0
  54. idmtools/entities/iplatform_ops/iplatform_asset_collection_operations.py +148 -0
  55. idmtools/entities/iplatform_ops/iplatform_experiment_operations.py +415 -0
  56. idmtools/entities/iplatform_ops/iplatform_simulation_operations.py +315 -0
  57. idmtools/entities/iplatform_ops/iplatform_suite_operations.py +322 -0
  58. idmtools/entities/iplatform_ops/iplatform_workflowitem_operations.py +301 -0
  59. idmtools/entities/iplatform_ops/utils.py +185 -0
  60. idmtools/entities/itask.py +316 -0
  61. idmtools/entities/iworkflow_item.py +167 -0
  62. idmtools/entities/platform_requirements.py +20 -0
  63. idmtools/entities/relation_type.py +14 -0
  64. idmtools/entities/simulation.py +255 -0
  65. idmtools/entities/suite.py +188 -0
  66. idmtools/entities/task_proxy.py +37 -0
  67. idmtools/entities/templated_simulation.py +325 -0
  68. idmtools/frozen/frozen_dict.py +71 -0
  69. idmtools/frozen/frozen_list.py +66 -0
  70. idmtools/frozen/frozen_set.py +86 -0
  71. idmtools/frozen/frozen_tuple.py +18 -0
  72. idmtools/frozen/frozen_utils.py +179 -0
  73. idmtools/frozen/ifrozen.py +66 -0
  74. idmtools/plugins/__init__.py +5 -0
  75. idmtools/plugins/git_commit.py +117 -0
  76. idmtools/registry/__init__.py +4 -0
  77. idmtools/registry/experiment_specification.py +105 -0
  78. idmtools/registry/functions.py +28 -0
  79. idmtools/registry/hook_specs.py +132 -0
  80. idmtools/registry/master_plugin_registry.py +51 -0
  81. idmtools/registry/platform_specification.py +138 -0
  82. idmtools/registry/plugin_specification.py +129 -0
  83. idmtools/registry/task_specification.py +104 -0
  84. idmtools/registry/utils.py +119 -0
  85. idmtools/services/__init__.py +5 -0
  86. idmtools/services/ipersistance_service.py +135 -0
  87. idmtools/services/platforms.py +13 -0
  88. idmtools/utils/__init__.py +5 -0
  89. idmtools/utils/caller.py +24 -0
  90. idmtools/utils/collections.py +246 -0
  91. idmtools/utils/command_line.py +45 -0
  92. idmtools/utils/decorators.py +300 -0
  93. idmtools/utils/display/__init__.py +22 -0
  94. idmtools/utils/display/displays.py +181 -0
  95. idmtools/utils/display/settings.py +25 -0
  96. idmtools/utils/dropbox_location.py +30 -0
  97. idmtools/utils/entities.py +127 -0
  98. idmtools/utils/file.py +72 -0
  99. idmtools/utils/file_parser.py +151 -0
  100. idmtools/utils/filter_simulations.py +182 -0
  101. idmtools/utils/filters/__init__.py +5 -0
  102. idmtools/utils/filters/asset_filters.py +88 -0
  103. idmtools/utils/general.py +286 -0
  104. idmtools/utils/gitrepo.py +336 -0
  105. idmtools/utils/hashing.py +239 -0
  106. idmtools/utils/info.py +124 -0
  107. idmtools/utils/json.py +82 -0
  108. idmtools/utils/language.py +107 -0
  109. idmtools/utils/local_os.py +40 -0
  110. idmtools/utils/time.py +22 -0
  111. idmtools-0.0.2.dist-info/METADATA +120 -0
  112. idmtools-0.0.2.dist-info/RECORD +116 -0
  113. idmtools-0.0.2.dist-info/entry_points.txt +9 -0
  114. idmtools-0.0.2.dist-info/licenses/LICENSE.TXT +3 -0
  115. idmtools-0.0.0.dev0.dist-info/METADATA +0 -41
  116. idmtools-0.0.0.dev0.dist-info/RECORD +0 -5
  117. {idmtools-0.0.0.dev0.dist-info → idmtools-0.0.2.dist-info}/WHEEL +0 -0
  118. {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,5 @@
1
+ """
2
+ idmtools plugins.
3
+
4
+ Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
5
+ """
@@ -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,4 @@
1
+ # flake8: noqa F821
2
+ from idmtools.registry.plugin_specification import PluginSpecification
3
+
4
+
@@ -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())