digitalhub-runtime-python 0.14.2__tar.gz → 0.15.0b1__tar.gz
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.
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/.github/workflows/release.yml +1 -1
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/.github/workflows/run_local_test.yml +1 -1
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/PKG-INFO +7 -5
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/__init__.py +1 -1
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/function/python/builder.py +4 -6
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/function/python/entity.py +10 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/function/python/models.py +1 -1
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/function/python/spec.py +3 -3
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/function/python/utils.py +58 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/_base/entity.py +0 -44
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/_base/spec.py +12 -23
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/job/entity.py +33 -0
- digitalhub_runtime_python-0.15.0b1/digitalhub_runtime_python/entities/run/serve/entity.py +86 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/build/spec.py +1 -11
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/serve/spec.py +3 -13
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/runtimes/runtime.py +3 -3
- digitalhub_runtime_python-0.15.0b1/digitalhub_runtime_python/utils/configuration.py +345 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/utils/inputs.py +6 -6
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/utils/outputs.py +12 -21
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/utils/utils.py +36 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/pyproject.toml +10 -8
- digitalhub_runtime_python-0.14.2/digitalhub_runtime_python/entities/run/serve/entity.py +0 -36
- digitalhub_runtime_python-0.14.2/digitalhub_runtime_python/utils/configuration.py +0 -212
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/.github/scripts/bump.sh +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/.github/scripts/changelog.sh +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/.github/scripts/cliff.toml +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/.github/workflows/test_release.yml +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/.gitignore +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/AUTHORS +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/CONTRIBUTING +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/COPYRIGHT +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/LICENSE +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/README.md +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/_base/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/_base/runtime_entity/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/_base/runtime_entity/builder.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/_commons/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/_commons/enums.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/function/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/function/python/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/function/python/status.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/_base/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/_base/builder.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/_base/status.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/_base/utils.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/build/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/build/builder.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/build/entity.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/build/spec.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/build/status.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/job/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/job/builder.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/job/spec.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/job/status.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/serve/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/serve/builder.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/serve/spec.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/run/serve/status.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/build/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/build/builder.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/build/entity.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/build/status.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/job/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/job/builder.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/job/entity.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/job/models.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/job/spec.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/job/status.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/serve/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/serve/builder.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/serve/entity.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/entities/task/serve/status.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/runtimes/__init__.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/digitalhub_runtime_python/runtimes/builder.py +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/test/instances/entities/function/function-python-git.json +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/test/instances/entities/function/function-python-local.json +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/test/instances/entities/function/function-python-zip.json +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/test/instances/entities/run/run-python+build:run.json +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/test/instances/entities/run/run-python+job:run.json +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/test/instances/entities/run/run-python+serve:run.json +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/test/instances/entities/task/task-python+build.json +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/test/instances/entities/task/task-python+job.json +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/test/instances/entities/task/task-python+serve.json +0 -0
- {digitalhub_runtime_python-0.14.2 → digitalhub_runtime_python-0.15.0b1}/test/instances/test_validate.py +0 -0
|
@@ -132,7 +132,7 @@ jobs:
|
|
|
132
132
|
branch=${{ github.ref }}
|
|
133
133
|
|
|
134
134
|
# Define the repositories to trigger
|
|
135
|
-
repos=("digitalhub-
|
|
135
|
+
repos=( "digitalhub-tests" "digitalhub-serverless" "digitalhub-sdk-wrapper-hera")
|
|
136
136
|
|
|
137
137
|
# Loop over the repositories and trigger the workflow
|
|
138
138
|
for repo in "${repos[@]}"; do
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digitalhub-runtime-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0b1
|
|
4
4
|
Summary: Python runtime for DHCore
|
|
5
5
|
Project-URL: Homepage, https://github.com/scc-digitalhub/digitalhub-sdk-runtime-python
|
|
6
6
|
Author-email: Fondazione Bruno Kessler <digitalhub@fbk.eu>, Matteo Martini <mmartini@fbk.eu>
|
|
@@ -209,15 +209,17 @@ License-File: AUTHORS
|
|
|
209
209
|
License-File: LICENSE
|
|
210
210
|
Keywords: data,dataops,kubernetes
|
|
211
211
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
212
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
213
212
|
Classifier: Programming Language :: Python :: 3.10
|
|
214
213
|
Classifier: Programming Language :: Python :: 3.11
|
|
215
214
|
Classifier: Programming Language :: Python :: 3.12
|
|
216
|
-
|
|
217
|
-
Requires-
|
|
215
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
216
|
+
Requires-Python: <3.14,>=3.10
|
|
217
|
+
Requires-Dist: digitalhub[full]<0.16,>=0.15.0b
|
|
218
|
+
Requires-Dist: msgpack
|
|
218
219
|
Requires-Dist: nuclio-sdk
|
|
220
|
+
Requires-Dist: pip
|
|
219
221
|
Provides-Extra: dev
|
|
220
|
-
Requires-Dist: digitalhub[dev]<0.
|
|
222
|
+
Requires-Dist: digitalhub[dev]<0.16,>=0.15.0b; extra == 'dev'
|
|
221
223
|
Description-Content-Type: text/markdown
|
|
222
224
|
|
|
223
225
|
# DigitalHub SDK Runtime Python
|
|
@@ -9,7 +9,7 @@ from digitalhub_runtime_python.entities.run.serve.builder import RunPythonRunSer
|
|
|
9
9
|
from digitalhub_runtime_python.entities.task.build.builder import TaskPythonBuildBuilder
|
|
10
10
|
from digitalhub_runtime_python.entities.task.job.builder import TaskPythonJobBuilder
|
|
11
11
|
from digitalhub_runtime_python.entities.task.serve.builder import TaskPythonServeBuilder
|
|
12
|
-
from digitalhub_runtime_python.utils.utils import handler
|
|
12
|
+
from digitalhub_runtime_python.utils.utils import handler, parse_requirements
|
|
13
13
|
|
|
14
14
|
entity_builders = (
|
|
15
15
|
(EntityKinds.FUNCTION_PYTHON.value, FunctionPythonBuilder),
|
|
@@ -49,7 +49,7 @@ class FunctionPythonBuilder(FunctionBuilder, RuntimeEntityBuilderPython):
|
|
|
49
49
|
)
|
|
50
50
|
return source_post_check(obj)
|
|
51
51
|
|
|
52
|
-
def from_dict(self, obj: dict
|
|
52
|
+
def from_dict(self, obj: dict) -> FunctionPython:
|
|
53
53
|
"""
|
|
54
54
|
Create a new object from dictionary.
|
|
55
55
|
|
|
@@ -57,18 +57,16 @@ class FunctionPythonBuilder(FunctionBuilder, RuntimeEntityBuilderPython):
|
|
|
57
57
|
----------
|
|
58
58
|
obj : dict
|
|
59
59
|
Dictionary to create object from.
|
|
60
|
-
validate : bool
|
|
61
|
-
Flag to indicate if arguments must be validated.
|
|
62
60
|
|
|
63
61
|
Returns
|
|
64
62
|
-------
|
|
65
63
|
FunctionPython
|
|
66
64
|
Object instance.
|
|
67
65
|
"""
|
|
68
|
-
entity = super().from_dict(obj
|
|
66
|
+
entity = super().from_dict(obj)
|
|
69
67
|
return source_post_check(entity)
|
|
70
68
|
|
|
71
|
-
def _parse_dict(self, obj: dict
|
|
69
|
+
def _parse_dict(self, obj: dict) -> dict:
|
|
72
70
|
"""
|
|
73
71
|
Get dictionary and parse it to a valid entity dictionary.
|
|
74
72
|
|
|
@@ -91,4 +89,4 @@ class FunctionPythonBuilder(FunctionBuilder, RuntimeEntityBuilderPython):
|
|
|
91
89
|
if source:
|
|
92
90
|
spec_dict["source"] = source_check(source=source)["source"]
|
|
93
91
|
|
|
94
|
-
return super()._parse_dict(obj
|
|
92
|
+
return super()._parse_dict(obj)
|
|
@@ -11,6 +11,8 @@ from digitalhub.utils.generic_utils import decode_base64_string
|
|
|
11
11
|
from digitalhub.utils.io_utils import write_text
|
|
12
12
|
from digitalhub.utils.uri_utils import has_local_scheme
|
|
13
13
|
|
|
14
|
+
from digitalhub_runtime_python.entities.function.python.utils import read_installed_packages
|
|
15
|
+
|
|
14
16
|
if typing.TYPE_CHECKING:
|
|
15
17
|
from digitalhub.entities._base.entity.metadata import Metadata
|
|
16
18
|
|
|
@@ -69,3 +71,11 @@ class FunctionPython(Function):
|
|
|
69
71
|
return pth
|
|
70
72
|
|
|
71
73
|
return super().export()
|
|
74
|
+
|
|
75
|
+
def _post_create_hook_before_save(self) -> None:
|
|
76
|
+
"""
|
|
77
|
+
Hook method called after the creation of the entity but before saving
|
|
78
|
+
in Core.
|
|
79
|
+
Can be overridden in subclasses to implement custom behavior.
|
|
80
|
+
"""
|
|
81
|
+
self.spec.requirements = read_installed_packages(self.spec.requirements)
|
|
@@ -42,11 +42,11 @@ class FunctionValidatorPython(FunctionValidator):
|
|
|
42
42
|
python_version: PythonVersion
|
|
43
43
|
"Python version"
|
|
44
44
|
|
|
45
|
-
image: str = None
|
|
45
|
+
image: str | None = None
|
|
46
46
|
"Image where the function will be executed"
|
|
47
47
|
|
|
48
|
-
base_image: str = None
|
|
48
|
+
base_image: str | None = None
|
|
49
49
|
"Base image used to build the image where the function will be executed"
|
|
50
50
|
|
|
51
|
-
requirements: list[str] = None
|
|
51
|
+
requirements: list[str] | None = None
|
|
52
52
|
"Requirements list to be installed in the image where the function will be executed"
|
|
@@ -12,6 +12,7 @@ from digitalhub.utils.exceptions import EntityError
|
|
|
12
12
|
from digitalhub.utils.file_utils import eval_py_type, eval_zip_type
|
|
13
13
|
from digitalhub.utils.generic_utils import encode_string, read_source
|
|
14
14
|
from digitalhub.utils.uri_utils import has_local_scheme
|
|
15
|
+
from pip._internal.operations import freeze
|
|
15
16
|
|
|
16
17
|
from digitalhub_runtime_python.entities.function.python.models import Lang
|
|
17
18
|
|
|
@@ -19,6 +20,9 @@ if typing.TYPE_CHECKING:
|
|
|
19
20
|
from digitalhub_runtime_python.entities.function.python.entity import FunctionPython
|
|
20
21
|
|
|
21
22
|
|
|
23
|
+
SEPARATORS = ["==", ">=", "<=", ">", "<", "~=", "!="]
|
|
24
|
+
|
|
25
|
+
|
|
22
26
|
def source_check(**kwargs) -> dict:
|
|
23
27
|
"""
|
|
24
28
|
Check source code.
|
|
@@ -156,3 +160,57 @@ def source_post_check(exec: FunctionPython) -> FunctionPython:
|
|
|
156
160
|
exec.spec.source["handler"] = f"{Path(code_src).stem}:{exec.spec.source['handler']}"
|
|
157
161
|
|
|
158
162
|
return exec
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def read_installed_packages(requirements: list[str] | None = None) -> list[str] | None:
|
|
166
|
+
"""
|
|
167
|
+
Read installed packages in execution context.
|
|
168
|
+
|
|
169
|
+
If requirements is provided, returns only those packages with their
|
|
170
|
+
versions filled in from the environment. Package names without versions
|
|
171
|
+
in the requirements list will have their versions added if found.
|
|
172
|
+
|
|
173
|
+
Parameters
|
|
174
|
+
----------
|
|
175
|
+
requirements : list[str]
|
|
176
|
+
Optional list of package names (e.g., ['pandas', 'torch']) or
|
|
177
|
+
requirements with versions (e.g., ['pandas==2.0.0']).
|
|
178
|
+
|
|
179
|
+
Returns
|
|
180
|
+
-------
|
|
181
|
+
list[str]
|
|
182
|
+
List of installed packages in pip freeze format (e.g., ['numpy==1.24.0', 'pandas==2.0.0']).
|
|
183
|
+
"""
|
|
184
|
+
if requirements is None:
|
|
185
|
+
return
|
|
186
|
+
|
|
187
|
+
# Build a mapping of normalized package names to their installed versions
|
|
188
|
+
installed_map: dict[str, str] = {}
|
|
189
|
+
for pkg in freeze.freeze():
|
|
190
|
+
# Handle different separators
|
|
191
|
+
for sep in SEPARATORS:
|
|
192
|
+
if sep in pkg:
|
|
193
|
+
name, version = pkg.split(sep, 1)
|
|
194
|
+
# Normalize package name (lowercase, replace _ with -)
|
|
195
|
+
installed_map[name.lower().replace("_", "-")] = f"{name}{sep}{version}"
|
|
196
|
+
break
|
|
197
|
+
|
|
198
|
+
result = []
|
|
199
|
+
for req in requirements:
|
|
200
|
+
# Check if requirement already has a version specifier
|
|
201
|
+
has_version = any(sep in req for sep in SEPARATORS)
|
|
202
|
+
|
|
203
|
+
if has_version:
|
|
204
|
+
# Keep as-is if version is already specified
|
|
205
|
+
result.append(req)
|
|
206
|
+
else:
|
|
207
|
+
# Normalize the requirement name for lookup
|
|
208
|
+
normalized_name = req.lower().replace("_", "-")
|
|
209
|
+
if normalized_name in installed_map:
|
|
210
|
+
# Use the installed version
|
|
211
|
+
result.append(installed_map[normalized_name])
|
|
212
|
+
else:
|
|
213
|
+
# Package not found in environment, keep without version
|
|
214
|
+
result.append(req)
|
|
215
|
+
|
|
216
|
+
return result
|
|
@@ -8,12 +8,10 @@ import time
|
|
|
8
8
|
import typing
|
|
9
9
|
from typing import Any
|
|
10
10
|
|
|
11
|
-
import requests
|
|
12
11
|
from digitalhub.entities._commons.enums import Relationship, State
|
|
13
12
|
from digitalhub.entities._commons.utils import get_entity_type_from_key
|
|
14
13
|
from digitalhub.entities.run._base.entity import Run
|
|
15
14
|
from digitalhub.factory.entity import entity_factory
|
|
16
|
-
from digitalhub.utils.exceptions import EntityError
|
|
17
15
|
from digitalhub.utils.logger import LOGGER
|
|
18
16
|
|
|
19
17
|
from digitalhub_runtime_python.entities._commons.enums import Actions
|
|
@@ -225,45 +223,3 @@ class RunPythonRun(Run):
|
|
|
225
223
|
if self.status.results is None:
|
|
226
224
|
return {}
|
|
227
225
|
return self.status.results
|
|
228
|
-
|
|
229
|
-
def invoke(
|
|
230
|
-
self,
|
|
231
|
-
method: str = "POST",
|
|
232
|
-
url: str | None = None,
|
|
233
|
-
**kwargs,
|
|
234
|
-
) -> requests.Response:
|
|
235
|
-
"""
|
|
236
|
-
Invoke run.
|
|
237
|
-
|
|
238
|
-
Parameters
|
|
239
|
-
----------
|
|
240
|
-
method : str
|
|
241
|
-
Method of the request.
|
|
242
|
-
url : str
|
|
243
|
-
URL of the request.
|
|
244
|
-
**kwargs : dict
|
|
245
|
-
Keyword arguments to pass to the request.
|
|
246
|
-
|
|
247
|
-
Returns
|
|
248
|
-
-------
|
|
249
|
-
requests.Response
|
|
250
|
-
Response from service.
|
|
251
|
-
"""
|
|
252
|
-
try:
|
|
253
|
-
base_url: str = self.status.service.get("url")
|
|
254
|
-
except AttributeError:
|
|
255
|
-
raise EntityError(
|
|
256
|
-
"Url not specified and service not found on run status."
|
|
257
|
-
" If a service is deploying, use run.wait() or try again later."
|
|
258
|
-
)
|
|
259
|
-
|
|
260
|
-
if url is not None and not url.removeprefix("http://").removeprefix("https://").startswith(base_url):
|
|
261
|
-
raise EntityError(f"Invalid URL: {url}. It must start with the service URL: {base_url}")
|
|
262
|
-
|
|
263
|
-
if url is None:
|
|
264
|
-
url = f"http://{base_url}"
|
|
265
|
-
|
|
266
|
-
if "data" not in kwargs and "json" not in kwargs:
|
|
267
|
-
method = "GET"
|
|
268
|
-
|
|
269
|
-
return requests.request(method=method, url=url, **kwargs)
|
|
@@ -16,16 +16,11 @@ class RunSpecPythonRun(RunSpec):
|
|
|
16
16
|
local_execution: bool = False,
|
|
17
17
|
function: str | None = None,
|
|
18
18
|
workflow: str | None = None,
|
|
19
|
-
node_selector: list[dict] | None = None,
|
|
20
19
|
volumes: list[dict] | None = None,
|
|
21
20
|
resources: dict | None = None,
|
|
22
|
-
affinity: dict | None = None,
|
|
23
|
-
tolerations: list[dict] | None = None,
|
|
24
21
|
envs: list[dict] | None = None,
|
|
25
22
|
secrets: list[str] | None = None,
|
|
26
23
|
profile: str | None = None,
|
|
27
|
-
runtime_class: str | None = None,
|
|
28
|
-
priority_class: str | None = None,
|
|
29
24
|
source: dict | None = None,
|
|
30
25
|
image: str | None = None,
|
|
31
26
|
base_image: str | None = None,
|
|
@@ -45,16 +40,11 @@ class RunSpecPythonRun(RunSpec):
|
|
|
45
40
|
local_execution,
|
|
46
41
|
function,
|
|
47
42
|
workflow,
|
|
48
|
-
node_selector,
|
|
49
43
|
volumes,
|
|
50
44
|
resources,
|
|
51
|
-
affinity,
|
|
52
|
-
tolerations,
|
|
53
45
|
envs,
|
|
54
46
|
secrets,
|
|
55
47
|
profile,
|
|
56
|
-
runtime_class,
|
|
57
|
-
priority_class,
|
|
58
48
|
**kwargs,
|
|
59
49
|
)
|
|
60
50
|
self.source = source
|
|
@@ -62,7 +52,6 @@ class RunSpecPythonRun(RunSpec):
|
|
|
62
52
|
self.base_image = base_image
|
|
63
53
|
self.python_version = python_version
|
|
64
54
|
self.requirements = requirements
|
|
65
|
-
|
|
66
55
|
self.service_type = service_type
|
|
67
56
|
self.service_name = service_name
|
|
68
57
|
self.replicas = replicas
|
|
@@ -76,26 +65,26 @@ class RunValidatorPythonRun(RunValidator):
|
|
|
76
65
|
"""RunValidatorPythonRun validator."""
|
|
77
66
|
|
|
78
67
|
# Function parameters
|
|
79
|
-
source: dict = None
|
|
80
|
-
image: str = None
|
|
81
|
-
base_image: str = None
|
|
82
|
-
python_version: str = None
|
|
83
|
-
requirements: list = None
|
|
68
|
+
source: dict | None = None
|
|
69
|
+
image: str | None = None
|
|
70
|
+
base_image: str | None = None
|
|
71
|
+
python_version: str | None = None
|
|
72
|
+
requirements: list | None = None
|
|
84
73
|
|
|
85
74
|
# Task serve
|
|
86
|
-
service_type: str = None
|
|
87
|
-
service_name: str = None
|
|
88
|
-
replicas: int = None
|
|
75
|
+
service_type: str | None = None
|
|
76
|
+
service_name: str | None = None
|
|
77
|
+
replicas: int | None = None
|
|
89
78
|
|
|
90
79
|
# Task build
|
|
91
|
-
instructions: list[str] = None
|
|
80
|
+
instructions: list[str] | None = None
|
|
92
81
|
|
|
93
82
|
# Run parameters
|
|
94
|
-
inputs: dict = None
|
|
83
|
+
inputs: dict | None = None
|
|
95
84
|
"""Run inputs."""
|
|
96
85
|
|
|
97
|
-
parameters: dict = None
|
|
86
|
+
parameters: dict | None = None
|
|
98
87
|
"""Run parameters."""
|
|
99
88
|
|
|
100
|
-
init_parameters: dict = None
|
|
89
|
+
init_parameters: dict | None = None
|
|
101
90
|
"""Init function parameters."""
|
|
@@ -34,3 +34,36 @@ class RunPythonRunJob(RunPythonRun):
|
|
|
34
34
|
|
|
35
35
|
self.spec: RunSpecPythonRunJob
|
|
36
36
|
self.status: RunStatusPythonRunJob
|
|
37
|
+
|
|
38
|
+
def add_output(self, name: str, value: str) -> None:
|
|
39
|
+
"""
|
|
40
|
+
Add an output to the run job.
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
name : str
|
|
45
|
+
The name of the output.
|
|
46
|
+
value : str
|
|
47
|
+
The value of the output.
|
|
48
|
+
"""
|
|
49
|
+
if self.status.outputs is None:
|
|
50
|
+
self.status.outputs = {}
|
|
51
|
+
self.status.outputs[name] = value
|
|
52
|
+
|
|
53
|
+
def set_status(self, status: dict) -> None:
|
|
54
|
+
"""
|
|
55
|
+
Patch to merge outputs when updating status.
|
|
56
|
+
|
|
57
|
+
Parameters
|
|
58
|
+
----------
|
|
59
|
+
status : dict
|
|
60
|
+
The status dictionary to update.
|
|
61
|
+
"""
|
|
62
|
+
if self.status.outputs is None:
|
|
63
|
+
self.status.outputs = {}
|
|
64
|
+
if "outputs" in status:
|
|
65
|
+
status["outputs"] = {
|
|
66
|
+
**self.status.outputs,
|
|
67
|
+
**status["outputs"],
|
|
68
|
+
}
|
|
69
|
+
return super().set_status(status)
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import typing
|
|
8
|
+
|
|
9
|
+
import requests
|
|
10
|
+
from digitalhub.utils.exceptions import EntityError
|
|
11
|
+
|
|
12
|
+
from digitalhub_runtime_python.entities.run._base.entity import RunPythonRun
|
|
13
|
+
|
|
14
|
+
if typing.TYPE_CHECKING:
|
|
15
|
+
from digitalhub.entities._base.entity.metadata import Metadata
|
|
16
|
+
|
|
17
|
+
from digitalhub_runtime_python.entities.run.serve.spec import RunSpecPythonRunServe
|
|
18
|
+
from digitalhub_runtime_python.entities.run.serve.status import RunStatusPythonRunServe
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class RunPythonRunServe(RunPythonRun):
|
|
22
|
+
"""
|
|
23
|
+
RunPythonRunServe class.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
project: str,
|
|
29
|
+
uuid: str,
|
|
30
|
+
kind: str,
|
|
31
|
+
metadata: Metadata,
|
|
32
|
+
spec: RunSpecPythonRunServe,
|
|
33
|
+
status: RunStatusPythonRunServe,
|
|
34
|
+
user: str | None = None,
|
|
35
|
+
) -> None:
|
|
36
|
+
super().__init__(project, uuid, kind, metadata, spec, status, user)
|
|
37
|
+
|
|
38
|
+
self.spec: RunSpecPythonRunServe
|
|
39
|
+
self.status: RunStatusPythonRunServe
|
|
40
|
+
|
|
41
|
+
def invoke(
|
|
42
|
+
self,
|
|
43
|
+
method: str = "POST",
|
|
44
|
+
url: str | None = None,
|
|
45
|
+
**kwargs,
|
|
46
|
+
) -> requests.Response:
|
|
47
|
+
"""
|
|
48
|
+
Invoke run service endpoint. It uses the service URL from the run
|
|
49
|
+
status if no URL is specified.
|
|
50
|
+
The method defaults to "POST" if data or json is provided in kwargs,
|
|
51
|
+
otherwise it defaults to "GET". The function returns a requests.Response
|
|
52
|
+
object.
|
|
53
|
+
|
|
54
|
+
Parameters
|
|
55
|
+
----------
|
|
56
|
+
method : str
|
|
57
|
+
Method of the request (e.g., "GET", "POST").
|
|
58
|
+
url : str
|
|
59
|
+
URL to invoke. If specified, it must start with the service URL
|
|
60
|
+
(http:// or https:// prefixes are required and stripped before comparison).
|
|
61
|
+
**kwargs : dict
|
|
62
|
+
Keyword arguments to pass to the request.
|
|
63
|
+
|
|
64
|
+
Returns
|
|
65
|
+
-------
|
|
66
|
+
requests.Response
|
|
67
|
+
Response from service.
|
|
68
|
+
"""
|
|
69
|
+
try:
|
|
70
|
+
base_url: str = self.status.service.get("url")
|
|
71
|
+
except AttributeError:
|
|
72
|
+
raise EntityError(
|
|
73
|
+
"Url not specified and service not found on run status."
|
|
74
|
+
" If a service is deploying, use run.wait() or try again later."
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
if url is not None and not url.removeprefix("http://").removeprefix("https://").startswith(base_url):
|
|
78
|
+
raise EntityError(f"Invalid URL: {url}. It must start with the service URL: {base_url}")
|
|
79
|
+
|
|
80
|
+
if url is None:
|
|
81
|
+
url = f"http://{base_url}"
|
|
82
|
+
|
|
83
|
+
if "data" not in kwargs and "json" not in kwargs:
|
|
84
|
+
method = "GET"
|
|
85
|
+
|
|
86
|
+
return requests.request(method=method, url=url, **kwargs)
|
|
@@ -13,31 +13,21 @@ class TaskSpecPythonBuild(TaskSpecFunction):
|
|
|
13
13
|
def __init__(
|
|
14
14
|
self,
|
|
15
15
|
function: str,
|
|
16
|
-
node_selector: list[dict] | None = None,
|
|
17
16
|
volumes: list[dict] | None = None,
|
|
18
17
|
resources: dict | None = None,
|
|
19
|
-
affinity: dict | None = None,
|
|
20
|
-
tolerations: list[dict] | None = None,
|
|
21
18
|
envs: list[dict] | None = None,
|
|
22
19
|
secrets: list[str] | None = None,
|
|
23
20
|
profile: str | None = None,
|
|
24
|
-
runtime_class: str | None = None,
|
|
25
|
-
priority_class: str | None = None,
|
|
26
21
|
instructions: list | None = None,
|
|
27
22
|
**kwargs,
|
|
28
23
|
) -> None:
|
|
29
24
|
super().__init__(
|
|
30
25
|
function,
|
|
31
|
-
node_selector,
|
|
32
26
|
volumes,
|
|
33
27
|
resources,
|
|
34
|
-
affinity,
|
|
35
|
-
tolerations,
|
|
36
28
|
envs,
|
|
37
29
|
secrets,
|
|
38
30
|
profile,
|
|
39
|
-
runtime_class,
|
|
40
|
-
priority_class,
|
|
41
31
|
**kwargs,
|
|
42
32
|
)
|
|
43
33
|
self.instructions = instructions
|
|
@@ -48,5 +38,5 @@ class TaskValidatorPythonBuild(TaskValidatorFunction):
|
|
|
48
38
|
TaskValidatorPythonBuild validator.
|
|
49
39
|
"""
|
|
50
40
|
|
|
51
|
-
instructions: list[str] = None
|
|
41
|
+
instructions: list[str] | None = None
|
|
52
42
|
"""Build instructions."""
|
|
@@ -15,16 +15,11 @@ class TaskSpecPythonServe(TaskSpecFunction):
|
|
|
15
15
|
def __init__(
|
|
16
16
|
self,
|
|
17
17
|
function: str,
|
|
18
|
-
node_selector: list[dict] | None = None,
|
|
19
18
|
volumes: list[dict] | None = None,
|
|
20
19
|
resources: dict | None = None,
|
|
21
|
-
affinity: dict | None = None,
|
|
22
|
-
tolerations: list[dict] | None = None,
|
|
23
20
|
envs: list[dict] | None = None,
|
|
24
21
|
secrets: list[str] | None = None,
|
|
25
22
|
profile: str | None = None,
|
|
26
|
-
runtime_class: str | None = None,
|
|
27
|
-
priority_class: str | None = None,
|
|
28
23
|
replicas: int | None = None,
|
|
29
24
|
service_type: str | None = None,
|
|
30
25
|
service_name: str | None = None,
|
|
@@ -32,16 +27,11 @@ class TaskSpecPythonServe(TaskSpecFunction):
|
|
|
32
27
|
) -> None:
|
|
33
28
|
super().__init__(
|
|
34
29
|
function,
|
|
35
|
-
node_selector,
|
|
36
30
|
volumes,
|
|
37
31
|
resources,
|
|
38
|
-
affinity,
|
|
39
|
-
tolerations,
|
|
40
32
|
envs,
|
|
41
33
|
secrets,
|
|
42
34
|
profile,
|
|
43
|
-
runtime_class,
|
|
44
|
-
priority_class,
|
|
45
35
|
**kwargs,
|
|
46
36
|
)
|
|
47
37
|
self.replicas = replicas
|
|
@@ -54,11 +44,11 @@ class TaskValidatorPythonServe(TaskValidatorFunction):
|
|
|
54
44
|
TaskValidatorPythonServe validator.
|
|
55
45
|
"""
|
|
56
46
|
|
|
57
|
-
replicas: int = Field(default=None, ge=1)
|
|
47
|
+
replicas: int | None = Field(default=None, ge=1)
|
|
58
48
|
"""Number of replicas."""
|
|
59
49
|
|
|
60
|
-
service_type: CoreServiceType = None
|
|
50
|
+
service_type: CoreServiceType | None = None
|
|
61
51
|
"""Service type."""
|
|
62
52
|
|
|
63
|
-
service_name: str = None
|
|
53
|
+
service_name: str | None = None
|
|
64
54
|
"""Service name."""
|
|
@@ -13,7 +13,7 @@ from digitalhub.utils.logger import LOGGER
|
|
|
13
13
|
from digitalhub_runtime_python.entities._commons.enums import EntityKinds
|
|
14
14
|
from digitalhub_runtime_python.utils.configuration import import_function_from_source
|
|
15
15
|
from digitalhub_runtime_python.utils.inputs import compose_inputs
|
|
16
|
-
from digitalhub_runtime_python.utils.outputs import
|
|
16
|
+
from digitalhub_runtime_python.utils.outputs import build_new_status, parse_outputs
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class RuntimePython(Runtime):
|
|
@@ -83,9 +83,9 @@ class RuntimePython(Runtime):
|
|
|
83
83
|
else:
|
|
84
84
|
exec_result = self._execute(fnc, **fnc_args)
|
|
85
85
|
LOGGER.info("Collecting outputs.")
|
|
86
|
-
results = parse_outputs(exec_result,
|
|
86
|
+
results = parse_outputs(exec_result, project, run_key)
|
|
87
87
|
|
|
88
|
-
status =
|
|
88
|
+
status = build_new_status(project, results)
|
|
89
89
|
|
|
90
90
|
# Return run status
|
|
91
91
|
LOGGER.info("Task completed, returning run status.")
|