nextpipe 0.6.2.dev0__py3-none-any.whl → 0.6.2.dev2__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.
- nextpipe/__about__.py +1 -1
- nextpipe/constants.py +17 -0
- nextpipe/flow.py +56 -9
- nextpipe/schema.py +2 -0
- nextpipe/uplink.py +3 -11
- {nextpipe-0.6.2.dev0.dist-info → nextpipe-0.6.2.dev2.dist-info}/METADATA +1 -1
- nextpipe-0.6.2.dev2.dist-info/RECORD +15 -0
- nextpipe-0.6.2.dev0.dist-info/RECORD +0 -14
- {nextpipe-0.6.2.dev0.dist-info → nextpipe-0.6.2.dev2.dist-info}/WHEEL +0 -0
- {nextpipe-0.6.2.dev0.dist-info → nextpipe-0.6.2.dev2.dist-info}/licenses/LICENSE.md +0 -0
nextpipe/__about__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "v0.6.2-dev.
|
|
1
|
+
__version__ = "v0.6.2-dev.2"
|
nextpipe/constants.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
ENV_APP_ID = "NEXTMV_APP_ID"
|
|
4
|
+
"""Environment variable name for the application ID."""
|
|
5
|
+
|
|
6
|
+
ENV_RUN_ID = "NEXTMV_RUN_ID"
|
|
7
|
+
"""Environment variable name for the run ID."""
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def __get_run_info():
|
|
11
|
+
"""
|
|
12
|
+
Retrieves information about the run from environment variables.
|
|
13
|
+
If the environment variables are not set, it returns None for both values.
|
|
14
|
+
"""
|
|
15
|
+
app_id = os.environ.get(ENV_APP_ID)
|
|
16
|
+
run_id = os.environ.get(ENV_RUN_ID)
|
|
17
|
+
return app_id, run_id
|
nextpipe/flow.py
CHANGED
|
@@ -40,6 +40,8 @@ from typing import Any
|
|
|
40
40
|
import nextmv
|
|
41
41
|
from nextmv.cloud import Application, Client
|
|
42
42
|
|
|
43
|
+
from nextpipe.constants import __get_run_info
|
|
44
|
+
|
|
43
45
|
from . import config, decorators, graph, schema, threads, uplink, utils
|
|
44
46
|
from .__about__ import __version__
|
|
45
47
|
|
|
@@ -862,9 +864,9 @@ class Runner:
|
|
|
862
864
|
"""
|
|
863
865
|
|
|
864
866
|
reference: FlowNode = job.reference
|
|
865
|
-
|
|
867
|
+
failed = job.error is not None or reference.error is not None
|
|
868
|
+
reference.status = STATUS_SUCCEEDED if not failed else STATUS_FAILED
|
|
866
869
|
reference.result = job.result
|
|
867
|
-
reference.error = job.error
|
|
868
870
|
# Check if the job failed and mark the flow as failed if it did
|
|
869
871
|
with self.lock_fail:
|
|
870
872
|
if job.error is not None and not self.fail:
|
|
@@ -878,6 +880,20 @@ class Runner:
|
|
|
878
880
|
# Inform the platform about the node update
|
|
879
881
|
self.uplink.submit_update(self.graph._to_uplink_dto())
|
|
880
882
|
|
|
883
|
+
@staticmethod
|
|
884
|
+
def __determine_sub_run_info(app_step_id: str, step_name: str) -> tuple[str, str]:
|
|
885
|
+
"""
|
|
886
|
+
Determine name and description to use for sub-runs.
|
|
887
|
+
"""
|
|
888
|
+
wf_app_id, wf_run_id = __get_run_info()
|
|
889
|
+
wf_app_id = wf_app_id or app_step_id # Fallback if dynamic detection fails
|
|
890
|
+
wf_run_id = wf_run_id or "local" # Use "local" for non-platform runs
|
|
891
|
+
step_name = step_name[:50] # Truncate step name to 50 chars to keep overall name within limits
|
|
892
|
+
name = f"Nextpipe step {step_name} ({wf_app_id}/{wf_run_id})"
|
|
893
|
+
name = name[:128] # Truncate to 128 chars to comply with platform limits
|
|
894
|
+
description = f"This run was started by the nextpipe parent: {wf_app_id} (run-id: {wf_run_id})"
|
|
895
|
+
return name, description
|
|
896
|
+
|
|
881
897
|
@staticmethod
|
|
882
898
|
def __run_step(
|
|
883
899
|
node: FlowNode,
|
|
@@ -917,6 +933,9 @@ class Runner:
|
|
|
917
933
|
if node.parent.definition.is_app():
|
|
918
934
|
app_step: decorators.App = node.parent.definition.app
|
|
919
935
|
|
|
936
|
+
# Try to detect platform run context.
|
|
937
|
+
app_run_name, app_run_description = Runner.__determine_sub_run_info(app_step.app_id, node.id)
|
|
938
|
+
|
|
920
939
|
# Prepare the input for the app
|
|
921
940
|
# TODO: We only support one predecessor for app steps for now. This may
|
|
922
941
|
# change in the future. We may want to support multiple predecessors for
|
|
@@ -928,7 +947,10 @@ class Runner:
|
|
|
928
947
|
# If the input is AppRunConfig, unwrap it.
|
|
929
948
|
app_run_config: schema.AppRunConfig = inputs[0]
|
|
930
949
|
input = app_run_config.input
|
|
931
|
-
|
|
950
|
+
if app_run_config.name:
|
|
951
|
+
app_run_name = app_run_config.name
|
|
952
|
+
if app_run_config.description:
|
|
953
|
+
app_run_description = app_run_config.description
|
|
932
954
|
app_run_options = app_run_config.get_options()
|
|
933
955
|
# Merge the options from the app decorator with the options from the
|
|
934
956
|
# AppRunConfig. AppRunConfig options take precedence.
|
|
@@ -938,12 +960,10 @@ class Runner:
|
|
|
938
960
|
run_result: nextmv.RunResult = inputs[0]
|
|
939
961
|
input = run_result.output
|
|
940
962
|
options = app_step.options
|
|
941
|
-
name = node.id
|
|
942
963
|
else:
|
|
943
964
|
# If the input is not AppRunConfig, we use it directly.
|
|
944
965
|
input = inputs[0]
|
|
945
966
|
options = app_step.options
|
|
946
|
-
name = node.id
|
|
947
967
|
|
|
948
968
|
# Detect dir mode / multi-file direct input
|
|
949
969
|
is_dir_mode = False
|
|
@@ -964,7 +984,8 @@ class Runner:
|
|
|
964
984
|
[], # No nameless arguments
|
|
965
985
|
{ # We use the named arguments to pass the user arguments to the run function
|
|
966
986
|
"options": options,
|
|
967
|
-
"name":
|
|
987
|
+
"name": app_run_name,
|
|
988
|
+
"description": app_run_description,
|
|
968
989
|
},
|
|
969
990
|
)
|
|
970
991
|
|
|
@@ -1003,13 +1024,36 @@ class Runner:
|
|
|
1003
1024
|
)
|
|
1004
1025
|
else:
|
|
1005
1026
|
utils.log_internal(f"Bypassing app step {node.id} run, using bypass result")
|
|
1027
|
+
# We wrap the bypass result in a dummy RunResult to ensure consistent behavior.
|
|
1028
|
+
result = nextmv.RunResult(
|
|
1029
|
+
id="bypassed-run",
|
|
1030
|
+
name="bypassed-run",
|
|
1031
|
+
description="This run was bypassed using a user-supplied result.",
|
|
1032
|
+
user_email="unavailable",
|
|
1033
|
+
metadata=nextmv.Metadata(
|
|
1034
|
+
application_id="unavailable",
|
|
1035
|
+
application_instance_id="unavailable",
|
|
1036
|
+
application_version_id="unavailable",
|
|
1037
|
+
created_at="unavailable",
|
|
1038
|
+
duration="unavailable",
|
|
1039
|
+
error="unavailable",
|
|
1040
|
+
input_size=0.0,
|
|
1041
|
+
output_size=0.0,
|
|
1042
|
+
format=nextmv.Format(
|
|
1043
|
+
format_input=nextmv.FormatInput(
|
|
1044
|
+
input_type=nextmv.InputFormat.MULTI_FILE
|
|
1045
|
+
if is_dir_mode
|
|
1046
|
+
else nextmv.InputFormat.JSON,
|
|
1047
|
+
),
|
|
1048
|
+
),
|
|
1049
|
+
status_v2=nextmv.StatusV2.succeeded,
|
|
1050
|
+
),
|
|
1051
|
+
output=app_step.bypass_result,
|
|
1052
|
+
)
|
|
1006
1053
|
# If the user supplied a bypass result, we need to write it to the temp dir if it's in dir mode
|
|
1007
1054
|
if isinstance(app_step.bypass_result, str) and os.path.isdir(app_step.bypass_result):
|
|
1008
|
-
# If the bypass result is a directory, we copy its contents to the temp dir
|
|
1009
1055
|
for filename in os.listdir(app_step.bypass_result):
|
|
1010
1056
|
shutil.copy(os.path.join(app_step.bypass_result, filename), temp_dir)
|
|
1011
|
-
else:
|
|
1012
|
-
result = app_step.bypass_result
|
|
1013
1057
|
finally: # Make sure we clean up temp dir on failure too
|
|
1014
1058
|
# If the temp dir is empty, remove it
|
|
1015
1059
|
dir_result = False
|
|
@@ -1018,6 +1062,9 @@ class Runner:
|
|
|
1018
1062
|
else:
|
|
1019
1063
|
dir_result = True
|
|
1020
1064
|
|
|
1065
|
+
# Emit result status to DAG
|
|
1066
|
+
node.error = result.metadata.error
|
|
1067
|
+
|
|
1021
1068
|
# Return result
|
|
1022
1069
|
# - Do not unwrap if full result is requested
|
|
1023
1070
|
# - If the output came in a directory, return the directory path
|
nextpipe/schema.py
CHANGED
nextpipe/uplink.py
CHANGED
|
@@ -27,7 +27,6 @@ ExcludeIfNone
|
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
29
|
import datetime
|
|
30
|
-
import os
|
|
31
30
|
import threading
|
|
32
31
|
import time
|
|
33
32
|
from dataclasses import dataclass, field
|
|
@@ -35,6 +34,7 @@ from dataclasses import dataclass, field
|
|
|
35
34
|
from dataclasses_json import config, dataclass_json
|
|
36
35
|
from nextmv.cloud import Client
|
|
37
36
|
|
|
37
|
+
from nextpipe.constants import __get_run_info
|
|
38
38
|
from nextpipe.utils import log_internal
|
|
39
39
|
|
|
40
40
|
FAILED_UPDATES_THRESHOLD = 10
|
|
@@ -46,12 +46,6 @@ UPDATE_INTERVAL = 5
|
|
|
46
46
|
MAX_DOCS_LENGTH = 1000
|
|
47
47
|
"""Maximum length for documentation strings sent to the platform."""
|
|
48
48
|
|
|
49
|
-
ENV_APP_ID = "NEXTMV_APP_ID"
|
|
50
|
-
"""Environment variable name for the application ID."""
|
|
51
|
-
|
|
52
|
-
ENV_RUN_ID = "NEXTMV_RUN_ID"
|
|
53
|
-
"""Environment variable name for the run ID."""
|
|
54
|
-
|
|
55
49
|
|
|
56
50
|
def ExcludeIfNone(value):
|
|
57
51
|
"""
|
|
@@ -278,10 +272,8 @@ class UplinkClient:
|
|
|
278
272
|
|
|
279
273
|
if config is None:
|
|
280
274
|
# Load config from environment
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
run_id=os.environ.get(ENV_RUN_ID),
|
|
284
|
-
)
|
|
275
|
+
app_id, run_id = __get_run_info()
|
|
276
|
+
config = UplinkConfig(application_id=app_id, run_id=run_id)
|
|
285
277
|
self.config = config
|
|
286
278
|
self.inactive = False
|
|
287
279
|
if not self.config.application_id or not self.config.run_id:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nextpipe
|
|
3
|
-
Version: 0.6.2.
|
|
3
|
+
Version: 0.6.2.dev2
|
|
4
4
|
Summary: Framework for Decision Pipeline modeling and execution
|
|
5
5
|
Project-URL: Homepage, https://www.nextmv.io
|
|
6
6
|
Project-URL: Documentation, https://nextpipe.docs.nextmv.io/en/latest/
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
nextpipe/__about__.py,sha256=1-zmKDjeDRIz4nXrUOXUKYbr__bsifB-n1WTe2B-bAc,29
|
|
2
|
+
nextpipe/__init__.py,sha256=SzRhi2z33zmvskfgqoRHwaKvRnt8G1_JJR1M7BXlda0,694
|
|
3
|
+
nextpipe/config.py,sha256=JSShEaK3fnqieGofalQysKxEJUkyrWIRbwhdyH9yYZM,1659
|
|
4
|
+
nextpipe/constants.py,sha256=zvfSKKL4QDZ3D68H5bIW1YicaZf9mKEVTMFeviM3mbo,467
|
|
5
|
+
nextpipe/decorators.py,sha256=MLTwuTONn30-esVaF7q3hNdOp8AnJ5ksNswQHpFrGlE,25727
|
|
6
|
+
nextpipe/flow.py,sha256=bSiAIIMBRLSx1gYErJfm3BdsS64rnjGeW3IDL0HBDzY,42474
|
|
7
|
+
nextpipe/graph.py,sha256=Oi8HQ4fgvBYxpRK6xBoLtoxftGb-gCOb09BqFwzrwWs,2867
|
|
8
|
+
nextpipe/schema.py,sha256=HsJnzpYhemXUa8IZvFEChPB-_5YXTCbkYSPf5zpPqo8,3263
|
|
9
|
+
nextpipe/threads.py,sha256=5s7jF-hgVF_Eqfxgf6hsF6dhXsRSfqTsq5F0JBy4hNw,9039
|
|
10
|
+
nextpipe/uplink.py,sha256=I1gwTcXn-FuIwvQWC_EarrBzHQLgTIShwUQ_aHgmiuE,11477
|
|
11
|
+
nextpipe/utils.py,sha256=-ni6Em1QfatgVMh95hYSPVCdTboozB8vRKkakti3gls,8063
|
|
12
|
+
nextpipe-0.6.2.dev2.dist-info/METADATA,sha256=V842M8UKeo2nlgePGCFRlFTtD-VnTmacGkQWJ2pqB0Q,8760
|
|
13
|
+
nextpipe-0.6.2.dev2.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
14
|
+
nextpipe-0.6.2.dev2.dist-info/licenses/LICENSE.md,sha256=FpVScuRcgdbeBNVsMzoPyBbKL2eCB1vFor1vfNNFEj4,4106
|
|
15
|
+
nextpipe-0.6.2.dev2.dist-info/RECORD,,
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
nextpipe/__about__.py,sha256=bi5y8mslt4NrZtMLt6ABCGOIP47OVFOxqStiERVx_YI,29
|
|
2
|
-
nextpipe/__init__.py,sha256=SzRhi2z33zmvskfgqoRHwaKvRnt8G1_JJR1M7BXlda0,694
|
|
3
|
-
nextpipe/config.py,sha256=JSShEaK3fnqieGofalQysKxEJUkyrWIRbwhdyH9yYZM,1659
|
|
4
|
-
nextpipe/decorators.py,sha256=MLTwuTONn30-esVaF7q3hNdOp8AnJ5ksNswQHpFrGlE,25727
|
|
5
|
-
nextpipe/flow.py,sha256=DW8ohC-6ZuCnmliXnYD1J9P500SI-0RKluGRM9OGcRU,40005
|
|
6
|
-
nextpipe/graph.py,sha256=Oi8HQ4fgvBYxpRK6xBoLtoxftGb-gCOb09BqFwzrwWs,2867
|
|
7
|
-
nextpipe/schema.py,sha256=wZ61Tlu0k8b36OnCNwu6EHpXiIB_H5g9WSDdJxG6Uc4,3193
|
|
8
|
-
nextpipe/threads.py,sha256=5s7jF-hgVF_Eqfxgf6hsF6dhXsRSfqTsq5F0JBy4hNw,9039
|
|
9
|
-
nextpipe/uplink.py,sha256=j4k7Msa1Il7uxrQeXd1yoCMWWd9KmkbQb72EZy4zMSs,11646
|
|
10
|
-
nextpipe/utils.py,sha256=-ni6Em1QfatgVMh95hYSPVCdTboozB8vRKkakti3gls,8063
|
|
11
|
-
nextpipe-0.6.2.dev0.dist-info/METADATA,sha256=bQ3wmIZt8rl58LGWwdyVHqqZGPLvmW2nboOwrlH8Zus,8760
|
|
12
|
-
nextpipe-0.6.2.dev0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
13
|
-
nextpipe-0.6.2.dev0.dist-info/licenses/LICENSE.md,sha256=FpVScuRcgdbeBNVsMzoPyBbKL2eCB1vFor1vfNNFEj4,4106
|
|
14
|
-
nextpipe-0.6.2.dev0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|