easylink 0.1.4__py3-none-any.whl → 0.1.6__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.
- easylink/_version.py +1 -1
- easylink/configuration.py +1 -1
- easylink/pipeline_schema_constants/__init__.py +5 -4
- easylink/pipeline_schema_constants/{tests.py → testing.py} +90 -1
- easylink/step.py +63 -21
- {easylink-0.1.4.dist-info → easylink-0.1.6.dist-info}/METADATA +1 -1
- {easylink-0.1.4.dist-info → easylink-0.1.6.dist-info}/RECORD +10 -10
- {easylink-0.1.4.dist-info → easylink-0.1.6.dist-info}/WHEEL +0 -0
- {easylink-0.1.4.dist-info → easylink-0.1.6.dist-info}/entry_points.txt +0 -0
- {easylink-0.1.4.dist-info → easylink-0.1.6.dist-info}/top_level.txt +0 -0
easylink/_version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.1.
|
1
|
+
__version__ = "0.1.6"
|
easylink/configuration.py
CHANGED
@@ -97,7 +97,7 @@ class Config(LayeredConfigTree):
|
|
97
97
|
def __init__(
|
98
98
|
self,
|
99
99
|
config_params: dict[str, Any],
|
100
|
-
potential_schemas:
|
100
|
+
potential_schemas: PipelineSchema | list[PipelineSchema] = PIPELINE_SCHEMAS,
|
101
101
|
) -> None:
|
102
102
|
super().__init__(layers=["initial_data", "default", "user_configured"])
|
103
103
|
self.update(DEFAULT_ENVIRONMENT, layer="default")
|
@@ -1,11 +1,12 @@
|
|
1
|
-
from easylink.pipeline_schema_constants import development,
|
1
|
+
from easylink.pipeline_schema_constants import development, testing
|
2
2
|
|
3
3
|
ALLOWED_SCHEMA_PARAMS = {
|
4
4
|
"development": development.SCHEMA_PARAMS,
|
5
5
|
}
|
6
6
|
|
7
7
|
TESTING_SCHEMA_PARAMS = {
|
8
|
-
"integration":
|
9
|
-
"
|
10
|
-
"
|
8
|
+
"integration": testing.SINGLE_STEP_SCHEMA_PARAMS,
|
9
|
+
"combine_bad_topology": testing.BAD_COMBINED_TOPOLOGY_SCHEMA_PARAMS,
|
10
|
+
"combine_bad_implementation_names": testing.BAD_COMBINED_TOPOLOGY_SCHEMA_PARAMS,
|
11
|
+
"nested_templated_steps": testing.NESTED_TEMPLATED_STEPS_SCHEMA_PARAMS,
|
11
12
|
}
|
@@ -11,7 +11,14 @@ from easylink.graph_components import (
|
|
11
11
|
OutputSlot,
|
12
12
|
OutputSlotMapping,
|
13
13
|
)
|
14
|
-
from easylink.step import
|
14
|
+
from easylink.step import (
|
15
|
+
HierarchicalStep,
|
16
|
+
InputStep,
|
17
|
+
LoopStep,
|
18
|
+
OutputStep,
|
19
|
+
ParallelStep,
|
20
|
+
Step,
|
21
|
+
)
|
15
22
|
from easylink.utilities.validation_utils import validate_input_file_dummy
|
16
23
|
|
17
24
|
SINGLE_STEP_NODES = [
|
@@ -128,3 +135,85 @@ BAD_COMBINED_TOPOLOGY_NODES = [
|
|
128
135
|
]
|
129
136
|
|
130
137
|
BAD_COMBINED_TOPOLOGY_SCHEMA_PARAMS = (BAD_COMBINED_TOPOLOGY_NODES, SINGLE_STEP_EDGES)
|
138
|
+
|
139
|
+
|
140
|
+
NESTED_TEMPLATED_STEPS_NODES = [
|
141
|
+
InputStep(),
|
142
|
+
LoopStep(
|
143
|
+
template_step=ParallelStep(
|
144
|
+
template_step=HierarchicalStep(
|
145
|
+
step_name="step_1",
|
146
|
+
input_slots=[
|
147
|
+
InputSlot(
|
148
|
+
name="step_1_main_input",
|
149
|
+
env_var="DUMMY_CONTAINER_MAIN_INPUT_FILE_PATHS",
|
150
|
+
validator=validate_input_file_dummy,
|
151
|
+
),
|
152
|
+
],
|
153
|
+
output_slots=[OutputSlot("step_1_main_output")],
|
154
|
+
nodes=[
|
155
|
+
Step(
|
156
|
+
step_name="step_1a",
|
157
|
+
input_slots=[
|
158
|
+
InputSlot(
|
159
|
+
name="step_1a_main_input",
|
160
|
+
env_var="DUMMY_CONTAINER_MAIN_INPUT_FILE_PATHS",
|
161
|
+
validator=validate_input_file_dummy,
|
162
|
+
),
|
163
|
+
],
|
164
|
+
output_slots=[OutputSlot("step_1a_main_output")],
|
165
|
+
),
|
166
|
+
Step(
|
167
|
+
step_name="step_1b",
|
168
|
+
input_slots=[
|
169
|
+
InputSlot(
|
170
|
+
name="step_1b_main_input",
|
171
|
+
env_var="DUMMY_CONTAINER_MAIN_INPUT_FILE_PATHS",
|
172
|
+
validator=validate_input_file_dummy,
|
173
|
+
),
|
174
|
+
],
|
175
|
+
output_slots=[OutputSlot("step_1b_main_output")],
|
176
|
+
),
|
177
|
+
],
|
178
|
+
edges=[
|
179
|
+
EdgeParams(
|
180
|
+
source_node="step_1a",
|
181
|
+
target_node="step_1b",
|
182
|
+
output_slot="step_1a_main_output",
|
183
|
+
input_slot="step_1b_main_input",
|
184
|
+
),
|
185
|
+
],
|
186
|
+
input_slot_mappings=[
|
187
|
+
InputSlotMapping(
|
188
|
+
parent_slot="step_1_main_input",
|
189
|
+
child_node="step_1a",
|
190
|
+
child_slot="step_1a_main_input",
|
191
|
+
),
|
192
|
+
],
|
193
|
+
output_slot_mappings=[
|
194
|
+
OutputSlotMapping(
|
195
|
+
parent_slot="step_1_main_output",
|
196
|
+
child_node="step_1b",
|
197
|
+
child_slot="step_1b_main_output",
|
198
|
+
),
|
199
|
+
],
|
200
|
+
),
|
201
|
+
),
|
202
|
+
self_edges=[
|
203
|
+
EdgeParams(
|
204
|
+
source_node="step_1",
|
205
|
+
target_node="step_1",
|
206
|
+
output_slot="step_1_main_output",
|
207
|
+
input_slot="step_1_main_input",
|
208
|
+
),
|
209
|
+
],
|
210
|
+
),
|
211
|
+
OutputStep(
|
212
|
+
input_slots=[
|
213
|
+
InputSlot(name="result", env_var=None, validator=validate_input_file_dummy)
|
214
|
+
],
|
215
|
+
),
|
216
|
+
]
|
217
|
+
|
218
|
+
|
219
|
+
NESTED_TEMPLATED_STEPS_SCHEMA_PARAMS = (NESTED_TEMPLATED_STEPS_NODES, SINGLE_STEP_EDGES)
|
easylink/step.py
CHANGED
@@ -282,6 +282,17 @@ class Step:
|
|
282
282
|
) -> None:
|
283
283
|
"""Sets the configuration state for this ``Step``.
|
284
284
|
|
285
|
+
The so-called 'configuration state' for a given ``Step`` is backed up by
|
286
|
+
a :class:`ConfigurationState` class and is assigned to its :attr:`_configuration_state`
|
287
|
+
attribute. There are two possible ``ConfigurationStates``:
|
288
|
+
:class:`LeafConfigurationState` and :class:`NonLeafConfigurationState`.
|
289
|
+
|
290
|
+
This method sets the configuration state of this ``Step`` based on whether
|
291
|
+
or not a :attr:`config_key` is set *and exists is the ``Step's`` configuration*
|
292
|
+
(i.e. its portion of the user-suppled pipeline specification
|
293
|
+
file); any required deviation from this behavior requires special
|
294
|
+
handling.
|
295
|
+
|
285
296
|
Parameters
|
286
297
|
----------
|
287
298
|
parent_config
|
@@ -378,8 +389,9 @@ class Step:
|
|
378
389
|
) -> dict[str, list[str]]:
|
379
390
|
"""Validates a non-leaf ``Step``."""
|
380
391
|
errors = {}
|
381
|
-
|
382
|
-
|
392
|
+
nodes = self.step_graph.nodes
|
393
|
+
for node in nodes:
|
394
|
+
step = nodes[node]["step"]
|
383
395
|
if isinstance(step, IOStep):
|
384
396
|
continue
|
385
397
|
if step.name not in step_config:
|
@@ -390,7 +402,7 @@ class Step:
|
|
390
402
|
)
|
391
403
|
if step_errors:
|
392
404
|
errors.update(step_errors)
|
393
|
-
extra_steps = set(step_config.keys()) - set(
|
405
|
+
extra_steps = set(step_config.keys()) - set(nodes)
|
394
406
|
for extra_step in extra_steps:
|
395
407
|
errors[f"step {extra_step}"] = [f"{extra_step} is not a valid step."]
|
396
408
|
return errors
|
@@ -807,12 +819,42 @@ class TemplatedStep(Step, ABC):
|
|
807
819
|
The configuration for any implementations to be combined.
|
808
820
|
input_data_config
|
809
821
|
The input data configuration for the entire pipeline.
|
822
|
+
|
823
|
+
Notes
|
824
|
+
-----
|
825
|
+
A ``TemplatedStep`` is *always* assigned a :class:`NonLeafConfigurationState`
|
826
|
+
even if it has no multiplicity since (despite having no copies to make) we
|
827
|
+
still need to traverse the sub-``Steps`` to get to the one with a single
|
828
|
+
:class:`~easylink.implementation.Implementation`, i.e. the one with a
|
829
|
+
:class:`LeafConfigurationState`.
|
810
830
|
"""
|
811
|
-
|
812
|
-
self.
|
813
|
-
|
814
|
-
|
815
|
-
|
831
|
+
step_config = parent_config[self.name]
|
832
|
+
if self.config_key not in step_config:
|
833
|
+
# Special handle the step_graph update
|
834
|
+
self.step_graph = StepGraph()
|
835
|
+
self.template_step.name = self.name
|
836
|
+
self.step_graph.add_node_from_step(self.template_step)
|
837
|
+
# Special handle the slot_mappings update
|
838
|
+
input_mappings = [
|
839
|
+
InputSlotMapping(slot, self.name, slot) for slot in self.input_slots
|
840
|
+
]
|
841
|
+
output_mappings = [
|
842
|
+
OutputSlotMapping(slot, self.name, slot) for slot in self.output_slots
|
843
|
+
]
|
844
|
+
self.slot_mappings = {"input": input_mappings, "output": output_mappings}
|
845
|
+
# Add the key back to the expanded config
|
846
|
+
expanded_config = LayeredConfigTree({self.name: step_config})
|
847
|
+
else:
|
848
|
+
expanded_config = self._get_config(step_config)
|
849
|
+
num_repeats = len(expanded_config)
|
850
|
+
self.step_graph = self._update_step_graph(num_repeats)
|
851
|
+
self.slot_mappings = self._update_slot_mappings(num_repeats)
|
852
|
+
# Manually set the configuration state to non-leaf instead of relying
|
853
|
+
# on super().get_configuration_state() because that method will erroneously
|
854
|
+
# set to leaf state in the event the user didn't include the config_key
|
855
|
+
# in the pipeline specification.
|
856
|
+
self._configuration_state = NonLeafConfigurationState(
|
857
|
+
self, expanded_config, combined_implementations, input_data_config
|
816
858
|
)
|
817
859
|
|
818
860
|
def _duplicate_template_step(self) -> Step:
|
@@ -1105,9 +1147,10 @@ class ChoiceStep(Step):
|
|
1105
1147
|
initial ones are handled.
|
1106
1148
|
|
1107
1149
|
We update the :class:`easylink.graph_components.StepGraph` and ``SlotMappings``
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1150
|
+
in :meth:`validate_step` (as opposed to in :meth:`set_configuration_state`
|
1151
|
+
as is done in :class:`TemplatedStep`) because :meth:`validate_step` is called
|
1152
|
+
prior to :meth:`set_configuration_state`, but the validations itself actually
|
1153
|
+
requires the updated ``StepGraph`` and ``SlotMappings``.
|
1111
1154
|
|
1112
1155
|
We do not attempt to validate the subgraph here if the 'type' key is unable
|
1113
1156
|
to be validated.
|
@@ -1136,7 +1179,7 @@ class ChoiceStep(Step):
|
|
1136
1179
|
]
|
1137
1180
|
}
|
1138
1181
|
|
1139
|
-
#
|
1182
|
+
# HACK: Update the step graph and mappings here because we need them for validation
|
1140
1183
|
self.step_graph = self._update_step_graph(subgraph)
|
1141
1184
|
self.slot_mappings = self._update_slot_mappings(subgraph)
|
1142
1185
|
# NOTE: A ChoiceStep is by definition non-leaf step
|
@@ -1163,11 +1206,11 @@ class ChoiceStep(Step):
|
|
1163
1206
|
|
1164
1207
|
Notes
|
1165
1208
|
-----
|
1166
|
-
We update the :class
|
1167
|
-
:
|
1168
|
-
:meth:`validate_step`
|
1169
|
-
:
|
1170
|
-
|
1209
|
+
We update the :class:`easylink.graph_components.StepGraph` and ``SlotMappings``
|
1210
|
+
in :meth:`validate_step` (as opposed to in :meth:`set_configuration_state`
|
1211
|
+
as is done in :class:`TemplatedStep`) because :meth:`validate_step` is called
|
1212
|
+
prior to :meth:`set_configuration_state`, but the validations itself actually
|
1213
|
+
requires the updated ``StepGraph`` and ``SlotMappings``.
|
1171
1214
|
"""
|
1172
1215
|
|
1173
1216
|
chosen_parent_config = LayeredConfigTree(
|
@@ -1364,7 +1407,6 @@ class LeafConfigurationState(ConfigurationState):
|
|
1364
1407
|
for mapping in mappings:
|
1365
1408
|
imp_edge = mapping.remap_edge(edge)
|
1366
1409
|
implementation_edges.append(imp_edge)
|
1367
|
-
|
1368
1410
|
elif edge.target_node == self._step.name:
|
1369
1411
|
mappings = [
|
1370
1412
|
mapping
|
@@ -1520,7 +1562,6 @@ class NonLeafConfigurationState(ConfigurationState):
|
|
1520
1562
|
new_step = self._step.step_graph.nodes[mapping.child_node]["step"]
|
1521
1563
|
imp_edges = new_step.get_implementation_edges(new_edge)
|
1522
1564
|
implementation_edges.extend(imp_edges)
|
1523
|
-
|
1524
1565
|
elif edge.target_node == self._step.name:
|
1525
1566
|
mappings = [
|
1526
1567
|
mapping
|
@@ -1544,8 +1585,9 @@ class NonLeafConfigurationState(ConfigurationState):
|
|
1544
1585
|
This method recursively traverses the ``StepGraph`` and sets the configuration
|
1545
1586
|
state for each ``Step`` until reaching all leaf nodes.
|
1546
1587
|
"""
|
1547
|
-
|
1548
|
-
|
1588
|
+
nodes = self._step.step_graph.nodes
|
1589
|
+
for node in nodes:
|
1590
|
+
step = nodes[node]["step"]
|
1549
1591
|
step.set_configuration_state(
|
1550
1592
|
self.pipeline_config, self.combined_implementations, self.input_data_config
|
1551
1593
|
)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
easylink/__about__.py,sha256=2-oxCfu9t9yUJouLDwqYRZ0eii8kN25SxRzsawjWjho,440
|
2
2
|
easylink/__init__.py,sha256=gGMcIVfiVnHtlDw5mZwhevcDb2wt-kuP6F64gnkFack,159
|
3
|
-
easylink/_version.py,sha256=
|
3
|
+
easylink/_version.py,sha256=n3oM6B_EMz93NsTI18NNZd-jKFcUPzUkbIKj5VFK5ok,22
|
4
4
|
easylink/cli.py,sha256=O0YvFnjxM3N8ox6wMi5-SSQZ6bS4_VcRT3apCIY7u0I,6117
|
5
|
-
easylink/configuration.py,sha256=
|
5
|
+
easylink/configuration.py,sha256=Ire2pMZNZ6wtSwhcWnQpYa-snX4KrhXgovlQwQ2Wxf4,12530
|
6
6
|
easylink/graph_components.py,sha256=LIHLrASrppTr9XHUFZymtT9rE7_cFzCB1LVxyO3pCWk,11554
|
7
7
|
easylink/implementation.py,sha256=1TFbsUxOkDkyyMtCwYQtA6uwZb5TawEw4CHjjSot0_s,8873
|
8
8
|
easylink/implementation_metadata.yaml,sha256=VvlEu3Dvlmeh1MpzeYx91j22GiV-9mu3hZP5yVuW04o,6763
|
@@ -11,12 +11,12 @@ easylink/pipeline_graph.py,sha256=K8padPqQG6kSupYCQgbjYn_gs51tE1CmOvWmZ49EKLc,19
|
|
11
11
|
easylink/pipeline_schema.py,sha256=ckvA4deRYalY5dLLbJDrO_pKttMuWnEUvSn5fSdu4jc,5900
|
12
12
|
easylink/rule.py,sha256=dHr95tI4O39makPp9nEGFaIsGhOoa93RwuVzIVXUhak,7606
|
13
13
|
easylink/runner.py,sha256=CSqYDWzY4pBvaklUUvj75UeJ4VxqwW9MYgcwGrAlspo,6222
|
14
|
-
easylink/step.py,sha256=
|
14
|
+
easylink/step.py,sha256=NCN1L5ojpfJ1CgV_Ih4duQL_aUFL3ri_XiNguH20JDE,62709
|
15
15
|
easylink/images/spark_cluster/Dockerfile,sha256=3PHotbR4jdjVYRHOJ0VQW55b5Qd4tQ1pLLQMrTKWVA0,576
|
16
16
|
easylink/images/spark_cluster/README.md,sha256=KdgSttZRplNNWqHn4K1GTsTIab3dTOSG4V99QPLxSp8,569
|
17
|
-
easylink/pipeline_schema_constants/__init__.py,sha256=
|
17
|
+
easylink/pipeline_schema_constants/__init__.py,sha256=gVg8_0xv4FxG3B-Jy5MwiXIVntu4m36uCdA3ohVTN7w,460
|
18
18
|
easylink/pipeline_schema_constants/development.py,sha256=WaS6EQzgCI6opnY-7OCHpT0JpP2OvRmYrWVdt_ND_bk,10915
|
19
|
-
easylink/pipeline_schema_constants/
|
19
|
+
easylink/pipeline_schema_constants/testing.py,sha256=GUJtVGIzLd71j7hX_qaSuMT3FCxwFOGzZwWc_1Tbtsk,7016
|
20
20
|
easylink/steps/dev/README.md,sha256=u9dZUggpY2Lf2qb-xkDLWWgHjcmi4osbQtzSNo4uklE,4549
|
21
21
|
easylink/steps/dev/build-containers-local.sh,sha256=Wy3pfcyt7I-BNvHcr7ZXDe0g5Ihd00BIPqt9YuRbLeA,259
|
22
22
|
easylink/steps/dev/build-containers-remote.sh,sha256=Hy-kaaXf-ta6n8SzOz_ahByjMY5T7J71MvzXRXDvQw8,271
|
@@ -41,8 +41,8 @@ easylink/utilities/general_utils.py,sha256=PSlTiHmafuI_dDSH0cW7iSCkTV0WgqX9ZgzlT
|
|
41
41
|
easylink/utilities/paths.py,sha256=yl0cuWChJmB6YKMCQavTKw9jIl-VQhH6cnsM6D5c0Zk,599
|
42
42
|
easylink/utilities/spark.smk,sha256=tQ7RArNQzhjbaBQQcRORB4IxxkuDx4gPHUBcWHDYJ_U,5795
|
43
43
|
easylink/utilities/validation_utils.py,sha256=qOgn1n3_m5blFN7eHJ9MbOt5DkFA6DWucAOUAjvGvco,764
|
44
|
-
easylink-0.1.
|
45
|
-
easylink-0.1.
|
46
|
-
easylink-0.1.
|
47
|
-
easylink-0.1.
|
48
|
-
easylink-0.1.
|
44
|
+
easylink-0.1.6.dist-info/METADATA,sha256=Jbmi6F9PaLYIOqs63ViVjqaO6-3StEA7d_PE5N1UYik,2804
|
45
|
+
easylink-0.1.6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
46
|
+
easylink-0.1.6.dist-info/entry_points.txt,sha256=OGMZDFltg3yMboT7XjJt3joiPhRfV_7jnREVtrAIQNU,51
|
47
|
+
easylink-0.1.6.dist-info/top_level.txt,sha256=oHcOpcF_jDMWFiJRzfGQvuskENGDjSPC_Agu9Z_Xvik,9
|
48
|
+
easylink-0.1.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|