metaflow 2.18.11__py2.py3-none-any.whl → 2.18.12__py2.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.
- metaflow/plugins/argo/argo_workflows.py +33 -1
- metaflow/plugins/argo/argo_workflows_cli.py +20 -0
- metaflow/plugins/argo/capture_error.py +5 -2
- metaflow/plugins/cards/card_modules/components.py +23 -3
- metaflow/runner/utils.py +10 -10
- metaflow/version.py +1 -1
- {metaflow-2.18.11.dist-info → metaflow-2.18.12.dist-info}/METADATA +2 -2
- {metaflow-2.18.11.dist-info → metaflow-2.18.12.dist-info}/RECORD +15 -15
- {metaflow-2.18.11.data → metaflow-2.18.12.data}/data/share/metaflow/devtools/Makefile +0 -0
- {metaflow-2.18.11.data → metaflow-2.18.12.data}/data/share/metaflow/devtools/Tiltfile +0 -0
- {metaflow-2.18.11.data → metaflow-2.18.12.data}/data/share/metaflow/devtools/pick_services.sh +0 -0
- {metaflow-2.18.11.dist-info → metaflow-2.18.12.dist-info}/WHEEL +0 -0
- {metaflow-2.18.11.dist-info → metaflow-2.18.12.dist-info}/entry_points.txt +0 -0
- {metaflow-2.18.11.dist-info → metaflow-2.18.12.dist-info}/licenses/LICENSE +0 -0
- {metaflow-2.18.11.dist-info → metaflow-2.18.12.dist-info}/top_level.txt +0 -0
@@ -121,6 +121,8 @@ class ArgoWorkflows(object):
|
|
121
121
|
incident_io_metadata: List[str] = None,
|
122
122
|
enable_heartbeat_daemon=True,
|
123
123
|
enable_error_msg_capture=False,
|
124
|
+
workflow_title=None,
|
125
|
+
workflow_description=None,
|
124
126
|
):
|
125
127
|
# Some high-level notes -
|
126
128
|
#
|
@@ -177,6 +179,8 @@ class ArgoWorkflows(object):
|
|
177
179
|
)
|
178
180
|
self.enable_heartbeat_daemon = enable_heartbeat_daemon
|
179
181
|
self.enable_error_msg_capture = enable_error_msg_capture
|
182
|
+
self.workflow_title = workflow_title
|
183
|
+
self.workflow_description = workflow_description
|
180
184
|
self.parameters = self._process_parameters()
|
181
185
|
self.config_parameters = self._process_config_parameters()
|
182
186
|
self.triggers, self.trigger_options = self._process_triggers()
|
@@ -430,6 +434,25 @@ class ArgoWorkflows(object):
|
|
430
434
|
"metaflow/project_flow_name": current.project_flow_name,
|
431
435
|
}
|
432
436
|
)
|
437
|
+
|
438
|
+
# Add Argo Workflows title and description annotations
|
439
|
+
# https://argo-workflows.readthedocs.io/en/latest/title-and-description/
|
440
|
+
# Use CLI-provided values or auto-populate from metadata
|
441
|
+
title = (
|
442
|
+
(self.workflow_title.strip() if self.workflow_title else None)
|
443
|
+
or current.get("project_flow_name")
|
444
|
+
or self.flow.name
|
445
|
+
)
|
446
|
+
|
447
|
+
description = (
|
448
|
+
self.workflow_description.strip() if self.workflow_description else None
|
449
|
+
) or (self.flow.__doc__.strip() if self.flow.__doc__ else None)
|
450
|
+
|
451
|
+
if title:
|
452
|
+
annotations["workflows.argoproj.io/title"] = title
|
453
|
+
if description:
|
454
|
+
annotations["workflows.argoproj.io/description"] = description
|
455
|
+
|
433
456
|
return annotations
|
434
457
|
|
435
458
|
def _get_schedule(self):
|
@@ -894,7 +917,16 @@ class ArgoWorkflows(object):
|
|
894
917
|
.annotations(
|
895
918
|
{
|
896
919
|
**annotations,
|
897
|
-
**
|
920
|
+
**{
|
921
|
+
k: v
|
922
|
+
for k, v in self._base_annotations.items()
|
923
|
+
if k
|
924
|
+
# Skip custom title/description for workflows as this makes it harder to find specific runs.
|
925
|
+
not in [
|
926
|
+
"workflows.argoproj.io/title",
|
927
|
+
"workflows.argoproj.io/description",
|
928
|
+
]
|
929
|
+
},
|
898
930
|
**{"metaflow/run_id": "argo-{{workflow.name}}"},
|
899
931
|
}
|
900
932
|
)
|
@@ -227,6 +227,18 @@ def argo_workflows(obj, name=None):
|
|
227
227
|
show_default=True,
|
228
228
|
help="Capture stack trace of first failed task in exit hook.",
|
229
229
|
)
|
230
|
+
@click.option(
|
231
|
+
"--workflow-title",
|
232
|
+
default=None,
|
233
|
+
type=str,
|
234
|
+
help="Custom title for the workflow displayed in Argo Workflows UI. Defaults to `project_flow_name`. Supports markdown formatting.",
|
235
|
+
)
|
236
|
+
@click.option(
|
237
|
+
"--workflow-description",
|
238
|
+
default=None,
|
239
|
+
type=str,
|
240
|
+
help="Custom description for the workflow displayed in Argo Workflows UI. Defaults to the flow's docstring if available. Supports markdown formatting and multi-line text.",
|
241
|
+
)
|
230
242
|
@click.pass_obj
|
231
243
|
def create(
|
232
244
|
obj,
|
@@ -248,6 +260,8 @@ def create(
|
|
248
260
|
incident_io_alert_source_config_id=None,
|
249
261
|
incident_io_metadata=None,
|
250
262
|
enable_heartbeat_daemon=True,
|
263
|
+
workflow_title=None,
|
264
|
+
workflow_description=None,
|
251
265
|
deployer_attribute_file=None,
|
252
266
|
enable_error_msg_capture=False,
|
253
267
|
):
|
@@ -312,6 +326,8 @@ def create(
|
|
312
326
|
incident_io_metadata,
|
313
327
|
enable_heartbeat_daemon,
|
314
328
|
enable_error_msg_capture,
|
329
|
+
workflow_title,
|
330
|
+
workflow_description,
|
315
331
|
)
|
316
332
|
|
317
333
|
if only_json:
|
@@ -658,6 +674,8 @@ def make_flow(
|
|
658
674
|
incident_io_metadata,
|
659
675
|
enable_heartbeat_daemon,
|
660
676
|
enable_error_msg_capture,
|
677
|
+
workflow_title,
|
678
|
+
workflow_description,
|
661
679
|
):
|
662
680
|
# TODO: Make this check less specific to Amazon S3 as we introduce
|
663
681
|
# support for more cloud object stores.
|
@@ -750,6 +768,8 @@ def make_flow(
|
|
750
768
|
incident_io_metadata=incident_io_metadata,
|
751
769
|
enable_heartbeat_daemon=enable_heartbeat_daemon,
|
752
770
|
enable_error_msg_capture=enable_error_msg_capture,
|
771
|
+
workflow_title=workflow_title,
|
772
|
+
workflow_description=workflow_description,
|
753
773
|
)
|
754
774
|
|
755
775
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import json
|
2
2
|
import os
|
3
|
-
from datetime import datetime
|
3
|
+
from datetime import datetime, timezone
|
4
4
|
|
5
5
|
###
|
6
6
|
# Algorithm to determine 1st error:
|
@@ -26,6 +26,9 @@ def parse_workflow_failures():
|
|
26
26
|
def group_failures_by_template(failures):
|
27
27
|
groups = {}
|
28
28
|
for failure in failures:
|
29
|
+
if failure.get("finishedAt", None) is None:
|
30
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
31
|
+
failure["finishedAt"] = timestamp
|
29
32
|
groups.setdefault(failure["templateName"], []).append(failure)
|
30
33
|
return groups
|
31
34
|
|
@@ -53,7 +56,7 @@ def determine_first_error():
|
|
53
56
|
grouped_failures = group_failures_by_template(failures)
|
54
57
|
for group in grouped_failures.values():
|
55
58
|
group.sort(
|
56
|
-
key=lambda
|
59
|
+
key=lambda g: datetime.strptime(g["finishedAt"], "%Y-%m-%dT%H:%M:%SZ")
|
57
60
|
)
|
58
61
|
|
59
62
|
earliest_group = grouped_failures[
|
@@ -15,6 +15,7 @@ from .renderer_tools import render_safely
|
|
15
15
|
from .json_viewer import JSONViewer as _JSONViewer, YAMLViewer as _YAMLViewer
|
16
16
|
import uuid
|
17
17
|
import inspect
|
18
|
+
import textwrap
|
18
19
|
|
19
20
|
|
20
21
|
def _warning_with_component(component, msg):
|
@@ -656,19 +657,38 @@ class Markdown(UserComponent):
|
|
656
657
|
)
|
657
658
|
```
|
658
659
|
|
660
|
+
Multi-line strings with indentation are automatically dedented:
|
661
|
+
```
|
662
|
+
current.card.append(
|
663
|
+
Markdown(f'''
|
664
|
+
# Header
|
665
|
+
- Item 1
|
666
|
+
- Item 2
|
667
|
+
''')
|
668
|
+
)
|
669
|
+
```
|
670
|
+
|
659
671
|
Parameters
|
660
672
|
----------
|
661
673
|
text : str
|
662
|
-
Text formatted in Markdown.
|
674
|
+
Text formatted in Markdown. Leading whitespace common to all lines
|
675
|
+
is automatically removed to support indented multi-line strings.
|
663
676
|
"""
|
664
677
|
|
665
678
|
REALTIME_UPDATABLE = True
|
666
679
|
|
680
|
+
@staticmethod
|
681
|
+
def _dedent_text(text):
|
682
|
+
"""Remove common leading whitespace from all lines."""
|
683
|
+
if text is None:
|
684
|
+
return None
|
685
|
+
return textwrap.dedent(text)
|
686
|
+
|
667
687
|
def update(self, text=None):
|
668
|
-
self._text = text
|
688
|
+
self._text = self._dedent_text(text)
|
669
689
|
|
670
690
|
def __init__(self, text=None):
|
671
|
-
self._text = text
|
691
|
+
self._text = self._dedent_text(text)
|
672
692
|
|
673
693
|
@with_default_component_id
|
674
694
|
@render_safely
|
metaflow/runner/utils.py
CHANGED
@@ -109,7 +109,6 @@ def read_from_fifo_when_ready(
|
|
109
109
|
content = bytearray()
|
110
110
|
poll = select.poll()
|
111
111
|
poll.register(fifo_fd, select.POLLIN)
|
112
|
-
max_timeout = 3 # Wait for 10 * 3 = 30 ms after last write
|
113
112
|
while True:
|
114
113
|
if check_process_exited(command_obj) and command_obj.process.returncode != 0:
|
115
114
|
raise CalledProcessError(
|
@@ -137,15 +136,16 @@ def read_from_fifo_when_ready(
|
|
137
136
|
else:
|
138
137
|
# We had no events (just a timeout) and the read didn't return
|
139
138
|
# an exception so the file is still open; we continue waiting for data
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
139
|
+
# On some systems (notably MacOS), even after the file is closed on the
|
140
|
+
# other end, we may not get a BlockingIOError or proper EOF signal.
|
141
|
+
# Instead of using an arbitrary timeout, check if the writer process
|
142
|
+
# has actually exited. If it has and we have content, we can safely
|
143
|
+
# assume EOF. If the process is still running, continue waiting.
|
144
|
+
if content and check_process_exited(command_obj):
|
145
|
+
# Process has exited and we got an empty read with no poll events.
|
146
|
+
# This is EOF - break out to return the content we've collected.
|
147
|
+
break
|
148
|
+
# else: process is still running, continue waiting for more data
|
149
149
|
except BlockingIOError:
|
150
150
|
has_blocking_error = True
|
151
151
|
if content:
|
metaflow/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
metaflow_version = "2.18.
|
1
|
+
metaflow_version = "2.18.12"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: metaflow
|
3
|
-
Version: 2.18.
|
3
|
+
Version: 2.18.12
|
4
4
|
Summary: Metaflow: More AI and ML, Less Engineering
|
5
5
|
Author: Metaflow Developers
|
6
6
|
Author-email: help@metaflow.org
|
@@ -26,7 +26,7 @@ License-File: LICENSE
|
|
26
26
|
Requires-Dist: requests
|
27
27
|
Requires-Dist: boto3
|
28
28
|
Provides-Extra: stubs
|
29
|
-
Requires-Dist: metaflow-stubs==2.18.
|
29
|
+
Requires-Dist: metaflow-stubs==2.18.12; extra == "stubs"
|
30
30
|
Dynamic: author
|
31
31
|
Dynamic: author-email
|
32
32
|
Dynamic: classifier
|
@@ -36,7 +36,7 @@ metaflow/tuple_util.py,sha256=_G5YIEhuugwJ_f6rrZoelMFak3DqAR2tt_5CapS1XTY,830
|
|
36
36
|
metaflow/unbounded_foreach.py,sha256=p184WMbrMJ3xKYHwewj27ZhRUsSj_kw1jlye5gA9xJk,387
|
37
37
|
metaflow/util.py,sha256=g2SOU_CRzJLgDM_UGF9QDMANMAIHAsDRXE6S76_YzsY,14594
|
38
38
|
metaflow/vendor.py,sha256=A82CGHfStZGDP5pQ5XzRjFkbN1ZC-vFmghXIrzMDDNg,5868
|
39
|
-
metaflow/version.py,sha256=
|
39
|
+
metaflow/version.py,sha256=LEAeq12k2u6Mfx_BKRFo6XFbIXmlvtKvNKon7OjzR2k,29
|
40
40
|
metaflow/_vendor/__init__.py,sha256=y_CiwUD3l4eAKvTVDZeqgVujMy31cAM1qjAB-HfI-9s,353
|
41
41
|
metaflow/_vendor/typing_extensions.py,sha256=q9zxWa6p6CzF1zZvSkygSlklduHf_b3K7MCxGz7MJRc,134519
|
42
42
|
metaflow/_vendor/zipp.py,sha256=ajztOH-9I7KA_4wqDYygtHa6xUBVZgFpmZ8FE74HHHI,8425
|
@@ -231,12 +231,12 @@ metaflow/plugins/airflow/sensors/s3_sensor.py,sha256=iDReG-7FKnumrtQg-HY6cCUAAqN
|
|
231
231
|
metaflow/plugins/argo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
232
232
|
metaflow/plugins/argo/argo_client.py,sha256=oT4ZrCyE7CYEbqNN0SfoZfSHd5fYW9XtuOrQEiUd1co,17230
|
233
233
|
metaflow/plugins/argo/argo_events.py,sha256=_C1KWztVqgi3zuH57pInaE9OzABc2NnncC-zdwOMZ-w,5909
|
234
|
-
metaflow/plugins/argo/argo_workflows.py,sha256=
|
235
|
-
metaflow/plugins/argo/argo_workflows_cli.py,sha256
|
234
|
+
metaflow/plugins/argo/argo_workflows.py,sha256=89C72toG6tzsix8oZ3wr5DBEn_88GjydEWzvcL3L1S0,217637
|
235
|
+
metaflow/plugins/argo/argo_workflows_cli.py,sha256=GRDsiE8QT9HEdeAUODtyyGiqePhShSkwJJ8tiPQwwiI,52992
|
236
236
|
metaflow/plugins/argo/argo_workflows_decorator.py,sha256=CLSjPqFTGucZ2_dSQGAYkoWWUZBQ9TCBXul4rxhDj3w,8282
|
237
237
|
metaflow/plugins/argo/argo_workflows_deployer.py,sha256=6kHxEnYXJwzNCM9swI8-0AckxtPWqwhZLerYkX8fxUM,4444
|
238
238
|
metaflow/plugins/argo/argo_workflows_deployer_objects.py,sha256=ydBE-lP42eNKvep36nQdUBPS3rQQErvoA7rCgyp5M6I,14949
|
239
|
-
metaflow/plugins/argo/capture_error.py,sha256=
|
239
|
+
metaflow/plugins/argo/capture_error.py,sha256=9ggbGHyR9UBPswOqAHCbpE9kdXuV3uBYslKiybFxqhs,2042
|
240
240
|
metaflow/plugins/argo/conditional_input_paths.py,sha256=Vtca74XbhnqAXgJJXKasLEa28jZbKBZPC5w4NAIOURc,1251
|
241
241
|
metaflow/plugins/argo/exit_hooks.py,sha256=nh8IEkzAtQnbKVnh3N9CVnVKZB39Bjm3e0LFrACsLz8,6109
|
242
242
|
metaflow/plugins/argo/generate_input_paths.py,sha256=loYsI6RFX9LlFsHb7Fe-mzlTTtRdySoOu7sYDy-uXK0,881
|
@@ -287,7 +287,7 @@ metaflow/plugins/cards/card_modules/base.html,sha256=Y208ZKIZqEWWUcoBFTLTdWKAG0C
|
|
287
287
|
metaflow/plugins/cards/card_modules/basic.py,sha256=bKU_b_Wfs2OC6me6kPp1Jm_SLvaJ4dkUCMAt2VLampk,26430
|
288
288
|
metaflow/plugins/cards/card_modules/bundle.css,sha256=zlYjv5rt7lMqiQzd_OAe4QdQeM3J3YbwljnEghlbTaU,28052
|
289
289
|
metaflow/plugins/cards/card_modules/card.py,sha256=6sbqP5mwf7QWvQvX2N_bC78H9ixuI5sQ8612Q5islys,4627
|
290
|
-
metaflow/plugins/cards/card_modules/components.py,sha256=
|
290
|
+
metaflow/plugins/cards/card_modules/components.py,sha256=z9IT9gVpI22hUhGtJbgcy5oMpGzPeTof_lEkOOfMa9Q,46150
|
291
291
|
metaflow/plugins/cards/card_modules/convert_to_native_type.py,sha256=opjGOvWg7trOqzhTRZ7h1cFlYrNj68Wn3_EyDTIKEvw,17320
|
292
292
|
metaflow/plugins/cards/card_modules/json_viewer.py,sha256=DWOcQPk6DXbeGuYEqv1gGrQW1eMVYlCXv3kMsVLnhNc,7113
|
293
293
|
metaflow/plugins/cards/card_modules/main.css,sha256=avu7BTB9qj0M8LvqNLUhikUFQhmAJhQQ7REcUgh9zMw,11725
|
@@ -384,7 +384,7 @@ metaflow/runner/metaflow_runner.py,sha256=uo3BzcAfZ67VT_f-TPe5ZHiWHn6uuojWusOMGk
|
|
384
384
|
metaflow/runner/nbdeploy.py,sha256=Sp5w-6nCZwjHaRBHWxi8udya-RYnJOB76KNLjB4L7Gs,4166
|
385
385
|
metaflow/runner/nbrun.py,sha256=LhJu-Teoi7wTkNxg0kpNPVXFxH_9P4lvtp0ysMEIFJ8,7299
|
386
386
|
metaflow/runner/subprocess_manager.py,sha256=x-MtPpGGMQUkIbQ_oNOuR-45b91DFvsCJ0SPoFc0dF4,23028
|
387
|
-
metaflow/runner/utils.py,sha256=
|
387
|
+
metaflow/runner/utils.py,sha256=x9EED11RZGf7J4OuK-cVuj8gxGlSjRQFSqqTehvBSjw,10588
|
388
388
|
metaflow/sidecar/__init__.py,sha256=1mmNpmQ5puZCpRmmYlCOeieZ4108Su9XQ4_EqF1FGOU,131
|
389
389
|
metaflow/sidecar/sidecar.py,sha256=EspKXvPPNiyRToaUZ51PS5TT_PzrBNAurn_wbFnmGr0,1334
|
390
390
|
metaflow/sidecar/sidecar_messages.py,sha256=zPsCoYgDIcDkkvdC9MEpJTJ3y6TSGm2JWkRc4vxjbFA,1071
|
@@ -430,12 +430,12 @@ metaflow/user_decorators/mutable_flow.py,sha256=EywKTN3cnXPQF_s62wQaC4a4aH14j8oe
|
|
430
430
|
metaflow/user_decorators/mutable_step.py,sha256=-BY0UDXf_RCAEnC5JlLzEXGdiw1KD9oSrSxS_SWaB9Y,16791
|
431
431
|
metaflow/user_decorators/user_flow_decorator.py,sha256=2yDwZq9QGv9W-7kEuKwa8o4ZkTvuHJ5ESz7VVrGViAI,9890
|
432
432
|
metaflow/user_decorators/user_step_decorator.py,sha256=4558NR8RJtN22OyTwCXO80bAMhMTaRGMoX12b1GMcPc,27232
|
433
|
-
metaflow-2.18.
|
434
|
-
metaflow-2.18.
|
435
|
-
metaflow-2.18.
|
436
|
-
metaflow-2.18.
|
437
|
-
metaflow-2.18.
|
438
|
-
metaflow-2.18.
|
439
|
-
metaflow-2.18.
|
440
|
-
metaflow-2.18.
|
441
|
-
metaflow-2.18.
|
433
|
+
metaflow-2.18.12.data/data/share/metaflow/devtools/Makefile,sha256=TT4TCq8ALSfqYyGqDPocN5oPcZe2FqoCZxmGO1LmyCc,13760
|
434
|
+
metaflow-2.18.12.data/data/share/metaflow/devtools/Tiltfile,sha256=b6l_fjDO0wtxOkO85lFvuf3HDa6wnzHhhBG8yv1kQqk,23949
|
435
|
+
metaflow-2.18.12.data/data/share/metaflow/devtools/pick_services.sh,sha256=PGjQeDIigFHeoQ0asmYNdYDPIOdeYy1UYvkw2wdN4zg,2209
|
436
|
+
metaflow-2.18.12.dist-info/licenses/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
|
437
|
+
metaflow-2.18.12.dist-info/METADATA,sha256=O2fzkU976nnqO8o9Ufxng-zphV6LCS3qR9u-zbHSZMg,6743
|
438
|
+
metaflow-2.18.12.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
|
439
|
+
metaflow-2.18.12.dist-info/entry_points.txt,sha256=RvEq8VFlgGe_FfqGOZi0D7ze1hLD0pAtXeNyGfzc_Yc,103
|
440
|
+
metaflow-2.18.12.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
|
441
|
+
metaflow-2.18.12.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{metaflow-2.18.11.data → metaflow-2.18.12.data}/data/share/metaflow/devtools/pick_services.sh
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|