holoscan-cli 2.9.0__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.
- holoscan_cli/__init__.py +35 -0
- holoscan_cli/__main__.py +164 -0
- holoscan_cli/common/argparse_types.py +156 -0
- holoscan_cli/common/artifact_sources.py +160 -0
- holoscan_cli/common/constants.py +119 -0
- holoscan_cli/common/dockerutils.py +521 -0
- holoscan_cli/common/enum_types.py +49 -0
- holoscan_cli/common/exceptions.py +126 -0
- holoscan_cli/common/sdk_utils.py +195 -0
- holoscan_cli/common/utils.py +137 -0
- holoscan_cli/logging.json +37 -0
- holoscan_cli/nics/__init__.py +15 -0
- holoscan_cli/nics/nics.py +33 -0
- holoscan_cli/package-source.json +32 -0
- holoscan_cli/packager/__init__.py +15 -0
- holoscan_cli/packager/arguments.py +148 -0
- holoscan_cli/packager/config_reader.py +180 -0
- holoscan_cli/packager/container_builder.py +426 -0
- holoscan_cli/packager/manifest_files.py +217 -0
- holoscan_cli/packager/models.py +90 -0
- holoscan_cli/packager/package_command.py +197 -0
- holoscan_cli/packager/packager.py +124 -0
- holoscan_cli/packager/parameters.py +603 -0
- holoscan_cli/packager/platforms.py +426 -0
- holoscan_cli/packager/templates/Dockerfile.jinja2 +479 -0
- holoscan_cli/packager/templates/dockerignore +92 -0
- holoscan_cli/packager/templates/tools.sh +414 -0
- holoscan_cli/py.typed +14 -0
- holoscan_cli/runner/__init__.py +15 -0
- holoscan_cli/runner/resources.py +185 -0
- holoscan_cli/runner/run_command.py +207 -0
- holoscan_cli/runner/runner.py +340 -0
- holoscan_cli/version/__init__.py +15 -0
- holoscan_cli/version/version.py +53 -0
- holoscan_cli-2.9.0.dist-info/LICENSE +201 -0
- holoscan_cli-2.9.0.dist-info/METADATA +102 -0
- holoscan_cli-2.9.0.dist-info/RECORD +39 -0
- holoscan_cli-2.9.0.dist-info/WHEEL +4 -0
- holoscan_cli-2.9.0.dist-info/entry_points.txt +4 -0
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
import logging
|
|
16
|
+
import os
|
|
17
|
+
import platform
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import Any, Optional
|
|
20
|
+
|
|
21
|
+
from ..common.constants import SDK, Constants, DefaultValues
|
|
22
|
+
from ..common.dockerutils import parse_docker_image_name_and_tag
|
|
23
|
+
from ..common.enum_types import (
|
|
24
|
+
ApplicationType,
|
|
25
|
+
Arch,
|
|
26
|
+
Platform,
|
|
27
|
+
PlatformConfiguration,
|
|
28
|
+
SdkType,
|
|
29
|
+
)
|
|
30
|
+
from ..common.exceptions import InvalidTagValueError, UnknownApplicationTypeError
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class PlatformParameters:
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
platform: Platform,
|
|
37
|
+
platform_config: PlatformConfiguration,
|
|
38
|
+
tag: str,
|
|
39
|
+
version: str,
|
|
40
|
+
) -> None:
|
|
41
|
+
self._logger = logging.getLogger("platform.parameters")
|
|
42
|
+
self._platform: Platform = platform
|
|
43
|
+
self._platform_config: PlatformConfiguration = platform_config
|
|
44
|
+
self._arch: Arch = SDK.PLATFORM_MAPPINGS[platform]
|
|
45
|
+
self._tag_prefix: Optional[str]
|
|
46
|
+
self._version: Optional[str]
|
|
47
|
+
|
|
48
|
+
(self._tag_prefix, self._version) = parse_docker_image_name_and_tag(tag)
|
|
49
|
+
|
|
50
|
+
if self._tag_prefix is None:
|
|
51
|
+
raise InvalidTagValueError(
|
|
52
|
+
f"'{tag}' is not a valid Docker tag. Format: name[:tag]"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
if self._version is None:
|
|
56
|
+
self._version = version
|
|
57
|
+
|
|
58
|
+
self._data: dict[str, Any] = {}
|
|
59
|
+
self._data["tag"] = tag
|
|
60
|
+
self._data["base_image"] = None
|
|
61
|
+
self._data["build_image"] = None
|
|
62
|
+
self._data["holoscan_sdk_file"] = None
|
|
63
|
+
self._data["holoscan_sdk_filename"] = None
|
|
64
|
+
self._data["monai_deploy_sdk_file"] = None
|
|
65
|
+
self._data["monai_deploy_sdk_filename"] = None
|
|
66
|
+
self._data["custom_base_image"] = False
|
|
67
|
+
self._data["custom_holoscan_sdk"] = False
|
|
68
|
+
self._data["custom_monai_deploy_sdk"] = False
|
|
69
|
+
self._data["target_arch"] = "aarch64" if self._arch == Arch.arm64 else "x86_64"
|
|
70
|
+
self._data["cuda_deb_arch"] = "sbsa" if self._arch == Arch.arm64 else "x86_64"
|
|
71
|
+
self._data["holoscan_deb_arch"] = (
|
|
72
|
+
"arm64" if self._arch == Arch.arm64 else "amd64"
|
|
73
|
+
)
|
|
74
|
+
self._data["gpu_type"] = self.platform_config.value
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def tag(self) -> str:
|
|
78
|
+
return (
|
|
79
|
+
f"{self._tag_prefix}-"
|
|
80
|
+
f"{self.platform.value}-"
|
|
81
|
+
f"{self.platform_config.value}-"
|
|
82
|
+
f"{self.platform_arch.value}:"
|
|
83
|
+
f"{self.version}"
|
|
84
|
+
).replace("/", "-")
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def tag_prefix(self) -> str:
|
|
88
|
+
return self._tag_prefix
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def custom_base_image(self) -> Optional[str]:
|
|
92
|
+
return self._data["custom_base_image"]
|
|
93
|
+
|
|
94
|
+
@custom_base_image.setter
|
|
95
|
+
def custom_base_image(self, value: str):
|
|
96
|
+
self._data["custom_base_image"] = value
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def custom_holoscan_sdk(self) -> Optional[str]:
|
|
100
|
+
return self._data["custom_holoscan_sdk"]
|
|
101
|
+
|
|
102
|
+
@custom_holoscan_sdk.setter
|
|
103
|
+
def custom_holoscan_sdk(self, value: str):
|
|
104
|
+
self._data["custom_holoscan_sdk"] = value
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def custom_monai_deploy_sdk(self) -> Optional[str]:
|
|
108
|
+
return self._data["custom_monai_deploy_sdk"]
|
|
109
|
+
|
|
110
|
+
@custom_monai_deploy_sdk.setter
|
|
111
|
+
def custom_monai_deploy_sdk(self, value: str):
|
|
112
|
+
self._data["custom_monai_deploy_sdk"] = value
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def base_image(self) -> Optional[str]:
|
|
116
|
+
return self._data["base_image"]
|
|
117
|
+
|
|
118
|
+
@base_image.setter
|
|
119
|
+
def base_image(self, value: str):
|
|
120
|
+
self._data["base_image"] = value
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def build_image(self) -> Optional[str]:
|
|
124
|
+
return self._data["build_image"]
|
|
125
|
+
|
|
126
|
+
@build_image.setter
|
|
127
|
+
def build_image(self, value: str):
|
|
128
|
+
self._data["build_image"] = value
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def holoscan_sdk_file(self) -> Optional[Path]:
|
|
132
|
+
return self._data["holoscan_sdk_file"]
|
|
133
|
+
|
|
134
|
+
@holoscan_sdk_file.setter
|
|
135
|
+
def holoscan_sdk_file(self, value: Path):
|
|
136
|
+
self._data["holoscan_sdk_file"] = value
|
|
137
|
+
if value is not None and hasattr(value, "name"):
|
|
138
|
+
self._data["holoscan_sdk_filename"] = value.name
|
|
139
|
+
elif value is not None:
|
|
140
|
+
self._data["holoscan_sdk_filename"] = value
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def monai_deploy_sdk_file(self) -> Optional[Path]:
|
|
144
|
+
return self._data["monai_deploy_sdk_file"]
|
|
145
|
+
|
|
146
|
+
@monai_deploy_sdk_file.setter
|
|
147
|
+
def monai_deploy_sdk_file(self, value: Path):
|
|
148
|
+
self._data["monai_deploy_sdk_file"] = value
|
|
149
|
+
if value is not None and hasattr(value, "name"):
|
|
150
|
+
self._data["monai_deploy_sdk_filename"] = value.name
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def version(self) -> str:
|
|
154
|
+
return self._version
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def health_probe(self) -> Optional[Path]:
|
|
158
|
+
return self._data.get("health_probe", None)
|
|
159
|
+
|
|
160
|
+
@health_probe.setter
|
|
161
|
+
def health_probe(self, value: Optional[Path]):
|
|
162
|
+
self._data["health_probe"] = value
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def platform_arch(self) -> Arch:
|
|
166
|
+
return self._arch
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def docker_arch(self) -> str:
|
|
170
|
+
return self._arch.value
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def platform(self) -> Platform:
|
|
174
|
+
return self._platform
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def platform_config(self) -> PlatformConfiguration:
|
|
178
|
+
return self._platform_config
|
|
179
|
+
|
|
180
|
+
@property
|
|
181
|
+
def to_jinja(self) -> dict[str, Any]:
|
|
182
|
+
return self._data
|
|
183
|
+
|
|
184
|
+
@property
|
|
185
|
+
def same_arch_as_system(self) -> bool:
|
|
186
|
+
return (platform.machine() == "aarch64" and self._arch == Arch.arm64) or (
|
|
187
|
+
platform.machine() == "x86_64" and self._arch == Arch.amd64
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def cuda_deb_arch(self) -> str:
|
|
192
|
+
return self._data["cuda_deb_arch"]
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def holoscan_deb_arch(self) -> str:
|
|
196
|
+
return self._data["holoscan_deb_arch"]
|
|
197
|
+
|
|
198
|
+
@property
|
|
199
|
+
def target_arch(self) -> str:
|
|
200
|
+
return self._data["target_arch"]
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class PlatformBuildResults:
|
|
204
|
+
def __init__(self, parameters: PlatformParameters):
|
|
205
|
+
self._parameters = parameters
|
|
206
|
+
self._docker_tag: Optional[str] = None
|
|
207
|
+
self._tarball_filenaem: Optional[str] = None
|
|
208
|
+
self._succeeded = False
|
|
209
|
+
self._error: Optional[str] = None
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def parameters(self) -> PlatformParameters:
|
|
213
|
+
return self._parameters
|
|
214
|
+
|
|
215
|
+
@property
|
|
216
|
+
def error(self) -> Optional[str]:
|
|
217
|
+
return self._error
|
|
218
|
+
|
|
219
|
+
@error.setter
|
|
220
|
+
def error(self, value: Optional[str]):
|
|
221
|
+
self._error = value
|
|
222
|
+
|
|
223
|
+
@property
|
|
224
|
+
def docker_tag(self) -> Optional[str]:
|
|
225
|
+
return self._docker_tag
|
|
226
|
+
|
|
227
|
+
@docker_tag.setter
|
|
228
|
+
def docker_tag(self, value: Optional[str]):
|
|
229
|
+
self._docker_tag = value
|
|
230
|
+
|
|
231
|
+
@property
|
|
232
|
+
def tarball_filenaem(self) -> Optional[str]:
|
|
233
|
+
return self._tarball_filenaem
|
|
234
|
+
|
|
235
|
+
@tarball_filenaem.setter
|
|
236
|
+
def tarball_filenaem(self, value: Optional[str]):
|
|
237
|
+
self._tarball_filenaem = value
|
|
238
|
+
|
|
239
|
+
@property
|
|
240
|
+
def succeeded(self) -> bool:
|
|
241
|
+
return self._succeeded
|
|
242
|
+
|
|
243
|
+
@succeeded.setter
|
|
244
|
+
def succeeded(self, value: bool):
|
|
245
|
+
self._succeeded = value
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
class PackageBuildParameters:
|
|
249
|
+
"""
|
|
250
|
+
Parameters required for building the Docker image with Jinja template.
|
|
251
|
+
"""
|
|
252
|
+
|
|
253
|
+
def __init__(self):
|
|
254
|
+
self._logger = logging.getLogger("packager.parameters")
|
|
255
|
+
self._data = {}
|
|
256
|
+
self._data["app_dir"] = DefaultValues.HOLOSCAN_APP_DIR
|
|
257
|
+
self._data["lib_dir"] = DefaultValues.HOLOSCAN_LIB_DIR
|
|
258
|
+
self._data["config_file_path"] = DefaultValues.HOLOSCAN_CONFIG_PATH
|
|
259
|
+
self._data["docs_dir"] = DefaultValues.HOLOSCAN_DOCS_DIR
|
|
260
|
+
self._data["logs_dir"] = DefaultValues.HOLOSCAN_LOGS_DIR
|
|
261
|
+
self._data["full_input_path"] = DefaultValues.WORK_DIR / DefaultValues.INPUT_DIR
|
|
262
|
+
self._data["full_output_path"] = (
|
|
263
|
+
DefaultValues.WORK_DIR / DefaultValues.OUTPUT_DIR
|
|
264
|
+
)
|
|
265
|
+
self._data["input_dir"] = DefaultValues.INPUT_DIR
|
|
266
|
+
self._data["models_dir"] = DefaultValues.MODELS_DIR
|
|
267
|
+
self._data["output_dir"] = DefaultValues.OUTPUT_DIR
|
|
268
|
+
self._data["timeout"] = DefaultValues.TIMEOUT
|
|
269
|
+
self._data["working_dir"] = DefaultValues.WORK_DIR
|
|
270
|
+
self._data["app_json"] = DefaultValues.APP_MANIFEST_PATH
|
|
271
|
+
self._data["pkg_json"] = DefaultValues.PKG_MANIFEST_PATH
|
|
272
|
+
self._data["username"] = DefaultValues.USERNAME
|
|
273
|
+
self._data["build_cache"] = DefaultValues.BUILD_CACHE_DIR
|
|
274
|
+
self._data["uid"] = os.getuid()
|
|
275
|
+
self._data["gid"] = os.getgid()
|
|
276
|
+
self._data["tarball_output"] = None
|
|
277
|
+
self._data["cmake_args"] = ""
|
|
278
|
+
self._data["includes"] = []
|
|
279
|
+
self._data["additional_lib_paths"] = ""
|
|
280
|
+
|
|
281
|
+
self._data["application_directory"] = None
|
|
282
|
+
self._data["application_type"] = None
|
|
283
|
+
self._data["application"] = None
|
|
284
|
+
self._data["app_config_file_path"] = None
|
|
285
|
+
self._data["command"] = None
|
|
286
|
+
self._data["no_cache"] = False
|
|
287
|
+
self._data["pip_packages"] = None
|
|
288
|
+
self._data["requirements_file_path"] = None
|
|
289
|
+
self._data["holoscan_sdk_version"] = None
|
|
290
|
+
self._data["monai_deploy_app_sdk_version"] = None
|
|
291
|
+
self._data["title"] = None
|
|
292
|
+
self._data["version"] = None
|
|
293
|
+
|
|
294
|
+
self._additional_libs = []
|
|
295
|
+
|
|
296
|
+
@property
|
|
297
|
+
def build_cache(self) -> int:
|
|
298
|
+
return self._data["build_cache"]
|
|
299
|
+
|
|
300
|
+
@build_cache.setter
|
|
301
|
+
def build_cache(self, value: int):
|
|
302
|
+
self._data["build_cache"] = value
|
|
303
|
+
|
|
304
|
+
@property
|
|
305
|
+
def full_input_path(self) -> str:
|
|
306
|
+
return self._data["full_input_path"]
|
|
307
|
+
|
|
308
|
+
@property
|
|
309
|
+
def full_output_path(self) -> str:
|
|
310
|
+
return self._data["full_output_path"]
|
|
311
|
+
|
|
312
|
+
@property
|
|
313
|
+
def docs_dir(self) -> str:
|
|
314
|
+
return self._data["docs_dir"]
|
|
315
|
+
|
|
316
|
+
@property
|
|
317
|
+
def logs_dir(self) -> str:
|
|
318
|
+
return self._data["logs_dir"]
|
|
319
|
+
|
|
320
|
+
@property
|
|
321
|
+
def tarball_output(self) -> int:
|
|
322
|
+
return self._data["tarball_output"]
|
|
323
|
+
|
|
324
|
+
@tarball_output.setter
|
|
325
|
+
def tarball_output(self, value: int):
|
|
326
|
+
self._data["tarball_output"] = value
|
|
327
|
+
|
|
328
|
+
@property
|
|
329
|
+
def cmake_args(self) -> str:
|
|
330
|
+
return self._data["cmake_args"]
|
|
331
|
+
|
|
332
|
+
@cmake_args.setter
|
|
333
|
+
def cmake_args(self, value: str):
|
|
334
|
+
self._data["cmake_args"] = value.strip('"') if value is not None else ""
|
|
335
|
+
|
|
336
|
+
@property
|
|
337
|
+
def gid(self) -> int:
|
|
338
|
+
return self._data["gid"]
|
|
339
|
+
|
|
340
|
+
@gid.setter
|
|
341
|
+
def gid(self, value: int):
|
|
342
|
+
self._data["gid"] = value
|
|
343
|
+
|
|
344
|
+
@property
|
|
345
|
+
def uid(self) -> int:
|
|
346
|
+
return self._data["uid"]
|
|
347
|
+
|
|
348
|
+
@uid.setter
|
|
349
|
+
def uid(self, value: int):
|
|
350
|
+
self._data["uid"] = value
|
|
351
|
+
|
|
352
|
+
@property
|
|
353
|
+
def username(self) -> str:
|
|
354
|
+
return self._data["username"]
|
|
355
|
+
|
|
356
|
+
@username.setter
|
|
357
|
+
def username(self, value: str):
|
|
358
|
+
self._data["username"] = value
|
|
359
|
+
|
|
360
|
+
@property
|
|
361
|
+
def app_manifest_path(self):
|
|
362
|
+
return self._data["app_json"]
|
|
363
|
+
|
|
364
|
+
@property
|
|
365
|
+
def package_manifest_path(self):
|
|
366
|
+
return self._data["pkg_json"]
|
|
367
|
+
|
|
368
|
+
@property
|
|
369
|
+
def title(self):
|
|
370
|
+
return self._data["title"]
|
|
371
|
+
|
|
372
|
+
@title.setter
|
|
373
|
+
def title(self, value):
|
|
374
|
+
self._data["title"] = value
|
|
375
|
+
|
|
376
|
+
@property
|
|
377
|
+
def docs(self) -> Path:
|
|
378
|
+
return self._data.get("docs", None)
|
|
379
|
+
|
|
380
|
+
@docs.setter
|
|
381
|
+
def docs(self, value: Path):
|
|
382
|
+
if value is not None:
|
|
383
|
+
self._data["docs"] = value
|
|
384
|
+
|
|
385
|
+
@property
|
|
386
|
+
def models(self) -> dict[str, Path]:
|
|
387
|
+
return self._data.get("models", None)
|
|
388
|
+
|
|
389
|
+
@models.setter
|
|
390
|
+
def models(self, value: dict[str, Path]):
|
|
391
|
+
if value is not None:
|
|
392
|
+
self._data["models"] = value
|
|
393
|
+
|
|
394
|
+
@property
|
|
395
|
+
def pip_packages(self):
|
|
396
|
+
return self._data["pip_packages"]
|
|
397
|
+
|
|
398
|
+
@pip_packages.setter
|
|
399
|
+
def pip_packages(self, value):
|
|
400
|
+
self._data["pip_packages"] = value
|
|
401
|
+
|
|
402
|
+
@property
|
|
403
|
+
def no_cache(self):
|
|
404
|
+
return self._data["no_cache"]
|
|
405
|
+
|
|
406
|
+
@no_cache.setter
|
|
407
|
+
def no_cache(self, value):
|
|
408
|
+
self._data["no_cache"] = value
|
|
409
|
+
|
|
410
|
+
@property
|
|
411
|
+
def config_file_path(self):
|
|
412
|
+
return self._data["config_file_path"]
|
|
413
|
+
|
|
414
|
+
@property
|
|
415
|
+
def app_config_file_path(self):
|
|
416
|
+
return self._data["app_config_file_path"]
|
|
417
|
+
|
|
418
|
+
@app_config_file_path.setter
|
|
419
|
+
def app_config_file_path(self, value):
|
|
420
|
+
self._data["app_config_file_path"] = value
|
|
421
|
+
|
|
422
|
+
@property
|
|
423
|
+
def app_dir(self):
|
|
424
|
+
return self._data["app_dir"]
|
|
425
|
+
|
|
426
|
+
@property
|
|
427
|
+
def application(self) -> Path:
|
|
428
|
+
return self._data["application"]
|
|
429
|
+
|
|
430
|
+
@application.setter
|
|
431
|
+
def application(self, value: Path):
|
|
432
|
+
self._data["application"] = value
|
|
433
|
+
self._logger.info(f"Application: {self.application}")
|
|
434
|
+
self._application_type = self._detect_application_type()
|
|
435
|
+
self._data["application_type"] = self._application_type.name
|
|
436
|
+
self._logger.info(f"Detected application type: {self.application_type.value}")
|
|
437
|
+
self._data["application_directory"] = (
|
|
438
|
+
self.application
|
|
439
|
+
if os.path.isdir(self.application)
|
|
440
|
+
else Path(os.path.dirname(self.application))
|
|
441
|
+
)
|
|
442
|
+
requirements_file_path = self.application_directory / "requirements.txt"
|
|
443
|
+
if os.path.exists(requirements_file_path):
|
|
444
|
+
self._data["requirements_file_path"] = requirements_file_path
|
|
445
|
+
else:
|
|
446
|
+
self._data["requirements_file_path"] = None
|
|
447
|
+
self._data["command"] = self._set_app_command()
|
|
448
|
+
self._data["command_filename"] = os.path.basename(self.application)
|
|
449
|
+
|
|
450
|
+
@property
|
|
451
|
+
def command_filename(self) -> str:
|
|
452
|
+
return self._data["command_filename"]
|
|
453
|
+
|
|
454
|
+
@property
|
|
455
|
+
def command(self) -> str:
|
|
456
|
+
return self._data["command"]
|
|
457
|
+
|
|
458
|
+
@property
|
|
459
|
+
def application_directory(self) -> Path:
|
|
460
|
+
return self._data["application_directory"]
|
|
461
|
+
|
|
462
|
+
@property
|
|
463
|
+
def requirements_file_path(self) -> Path:
|
|
464
|
+
return self._data["requirements_file_path"]
|
|
465
|
+
|
|
466
|
+
@property
|
|
467
|
+
def version(self) -> str:
|
|
468
|
+
return self._data["version"]
|
|
469
|
+
|
|
470
|
+
@version.setter
|
|
471
|
+
def version(self, value: str):
|
|
472
|
+
self._data["version"] = value
|
|
473
|
+
|
|
474
|
+
@property
|
|
475
|
+
def timeout(self) -> int:
|
|
476
|
+
return self._data["timeout"]
|
|
477
|
+
|
|
478
|
+
@timeout.setter
|
|
479
|
+
def timeout(self, value: int):
|
|
480
|
+
self._data["timeout"] = value
|
|
481
|
+
|
|
482
|
+
@property
|
|
483
|
+
def working_dir(self) -> Path:
|
|
484
|
+
return self._data["working_dir"]
|
|
485
|
+
|
|
486
|
+
@property
|
|
487
|
+
def models_dir(self) -> Path:
|
|
488
|
+
return self._data["models_dir"]
|
|
489
|
+
|
|
490
|
+
@models_dir.setter
|
|
491
|
+
def models_dir(self, value: Path):
|
|
492
|
+
self._data["models_dir"] = value
|
|
493
|
+
|
|
494
|
+
@property
|
|
495
|
+
def input_dir(self) -> str:
|
|
496
|
+
return self._data["input_dir"]
|
|
497
|
+
|
|
498
|
+
@property
|
|
499
|
+
def output_dir(self) -> str:
|
|
500
|
+
return self._data["output_dir"]
|
|
501
|
+
|
|
502
|
+
@property
|
|
503
|
+
def application_type(self) -> ApplicationType:
|
|
504
|
+
return self._application_type
|
|
505
|
+
|
|
506
|
+
@property
|
|
507
|
+
def sdk(self) -> SdkType:
|
|
508
|
+
return self._data["sdk"]
|
|
509
|
+
|
|
510
|
+
@sdk.setter
|
|
511
|
+
def sdk(self, value: SdkType):
|
|
512
|
+
self._data["sdk"] = value
|
|
513
|
+
self._data["sdk_type"] = value.value
|
|
514
|
+
|
|
515
|
+
@property
|
|
516
|
+
def holoscan_sdk_version(self) -> str:
|
|
517
|
+
return self._data["holoscan_sdk_version"]
|
|
518
|
+
|
|
519
|
+
@holoscan_sdk_version.setter
|
|
520
|
+
def holoscan_sdk_version(self, value: str):
|
|
521
|
+
self._data["holoscan_sdk_version"] = value
|
|
522
|
+
|
|
523
|
+
@property
|
|
524
|
+
def monai_deploy_app_sdk_version(self) -> str:
|
|
525
|
+
return self._data["monai_deploy_app_sdk_version"]
|
|
526
|
+
|
|
527
|
+
@monai_deploy_app_sdk_version.setter
|
|
528
|
+
def monai_deploy_app_sdk_version(self, value: str):
|
|
529
|
+
self._data["monai_deploy_app_sdk_version"] = value
|
|
530
|
+
|
|
531
|
+
@property
|
|
532
|
+
def includes(self) -> str:
|
|
533
|
+
return self._data["includes"]
|
|
534
|
+
|
|
535
|
+
@includes.setter
|
|
536
|
+
def includes(self, value: str):
|
|
537
|
+
self._data["includes"] = value
|
|
538
|
+
|
|
539
|
+
@property
|
|
540
|
+
def additional_lib_paths(self) -> str:
|
|
541
|
+
"""
|
|
542
|
+
Additional libraries that user wants to include in the package.
|
|
543
|
+
Stores the post-processed values to be injected into LD_LIBRARY_PATH and PYTHONPATH in the
|
|
544
|
+
Jinja2 template.
|
|
545
|
+
"""
|
|
546
|
+
return self._data["additional_lib_paths"]
|
|
547
|
+
|
|
548
|
+
@additional_lib_paths.setter
|
|
549
|
+
def additional_lib_paths(self, value: str):
|
|
550
|
+
self._data["additional_lib_paths"] = value
|
|
551
|
+
|
|
552
|
+
@property
|
|
553
|
+
def additional_libs(self) -> list[str]:
|
|
554
|
+
"""
|
|
555
|
+
Additional libraries that user wants to include in the package.
|
|
556
|
+
Stores paths entered from the command line before processing.
|
|
557
|
+
"""
|
|
558
|
+
return self._additional_libs
|
|
559
|
+
|
|
560
|
+
@additional_libs.setter
|
|
561
|
+
def additional_libs(self, value: list[str]):
|
|
562
|
+
self._additional_libs = value
|
|
563
|
+
|
|
564
|
+
@property
|
|
565
|
+
def to_jinja(self) -> dict[str, Any]:
|
|
566
|
+
return self._data
|
|
567
|
+
|
|
568
|
+
def _detect_application_type(self) -> ApplicationType:
|
|
569
|
+
if os.path.isdir(self.application):
|
|
570
|
+
if os.path.exists(self.application / Constants.PYTHON_MAIN_FILE):
|
|
571
|
+
return ApplicationType.PythonModule
|
|
572
|
+
elif os.path.exists(self.application / Constants.CPP_CMAKELIST_FILE):
|
|
573
|
+
return ApplicationType.CppCMake
|
|
574
|
+
elif os.path.isfile(self.application):
|
|
575
|
+
if Path(self.application).suffix == ".py":
|
|
576
|
+
return ApplicationType.PythonFile
|
|
577
|
+
elif os.access(self.application, os.X_OK):
|
|
578
|
+
return ApplicationType.Binary
|
|
579
|
+
|
|
580
|
+
raise UnknownApplicationTypeError(
|
|
581
|
+
f"""\n\nUnable to determine application type. Please ensure the application path
|
|
582
|
+
contains one of the following:
|
|
583
|
+
\t- Python directory/module with '{Constants.PYTHON_MAIN_FILE}'
|
|
584
|
+
\t- Python file
|
|
585
|
+
\t- C++ source directory with '{Constants.CPP_CMAKELIST_FILE}'
|
|
586
|
+
\t- Binary file"""
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
def _set_app_command(self) -> str:
|
|
590
|
+
if self.application_type == ApplicationType.PythonFile:
|
|
591
|
+
return (
|
|
592
|
+
f'["{Constants.PYTHON_EXECUTABLE}", '
|
|
593
|
+
+ f'"{os.path.join(self._data["app_dir"], os.path.basename(self.application))}"]'
|
|
594
|
+
)
|
|
595
|
+
elif self.application_type == ApplicationType.PythonModule:
|
|
596
|
+
return f'["{Constants.PYTHON_EXECUTABLE}", "{self._data["app_dir"]}"]'
|
|
597
|
+
elif self.application_type in [
|
|
598
|
+
ApplicationType.CppCMake,
|
|
599
|
+
ApplicationType.Binary,
|
|
600
|
+
]:
|
|
601
|
+
return f'["{os.path.join(self._data["app_dir"], os.path.basename(self.application))}"]'
|
|
602
|
+
|
|
603
|
+
raise UnknownApplicationTypeError("Unsupported application type.")
|