holoscan 2.1.0__cp38-cp38-manylinux_2_35_aarch64.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.
Files changed (138) hide show
  1. holoscan-2.1.0.data/purelib/holoscan/__init__.py +121 -0
  2. holoscan-2.1.0.data/purelib/holoscan/cli/__init__.py +32 -0
  3. holoscan-2.1.0.data/purelib/holoscan/cli/__main__.py +159 -0
  4. holoscan-2.1.0.data/purelib/holoscan/cli/common/argparse_types.py +154 -0
  5. holoscan-2.1.0.data/purelib/holoscan/cli/common/artifact_sources.py +144 -0
  6. holoscan-2.1.0.data/purelib/holoscan/cli/common/constants.py +120 -0
  7. holoscan-2.1.0.data/purelib/holoscan/cli/common/dockerutils.py +506 -0
  8. holoscan-2.1.0.data/purelib/holoscan/cli/common/enum_types.py +52 -0
  9. holoscan-2.1.0.data/purelib/holoscan/cli/common/exceptions.py +132 -0
  10. holoscan-2.1.0.data/purelib/holoscan/cli/common/sdk_utils.py +180 -0
  11. holoscan-2.1.0.data/purelib/holoscan/cli/common/utils.py +131 -0
  12. holoscan-2.1.0.data/purelib/holoscan/cli/logging.json +37 -0
  13. holoscan-2.1.0.data/purelib/holoscan/cli/nics/__init__.py +18 -0
  14. holoscan-2.1.0.data/purelib/holoscan/cli/nics/nics.py +34 -0
  15. holoscan-2.1.0.data/purelib/holoscan/cli/packager/__init__.py +18 -0
  16. holoscan-2.1.0.data/purelib/holoscan/cli/packager/arguments.py +137 -0
  17. holoscan-2.1.0.data/purelib/holoscan/cli/packager/config_reader.py +181 -0
  18. holoscan-2.1.0.data/purelib/holoscan/cli/packager/container_builder.py +349 -0
  19. holoscan-2.1.0.data/purelib/holoscan/cli/packager/manifest_files.py +220 -0
  20. holoscan-2.1.0.data/purelib/holoscan/cli/packager/models.py +93 -0
  21. holoscan-2.1.0.data/purelib/holoscan/cli/packager/package_command.py +183 -0
  22. holoscan-2.1.0.data/purelib/holoscan/cli/packager/packager.py +123 -0
  23. holoscan-2.1.0.data/purelib/holoscan/cli/packager/parameters.py +534 -0
  24. holoscan-2.1.0.data/purelib/holoscan/cli/packager/platforms.py +405 -0
  25. holoscan-2.1.0.data/purelib/holoscan/cli/packager/sdk_downloader.py +147 -0
  26. holoscan-2.1.0.data/purelib/holoscan/cli/packager/templates/Dockerfile.jinja2 +191 -0
  27. holoscan-2.1.0.data/purelib/holoscan/cli/packager/templates/dockerignore +93 -0
  28. holoscan-2.1.0.data/purelib/holoscan/cli/packager/templates/tools.sh +416 -0
  29. holoscan-2.1.0.data/purelib/holoscan/cli/py.typed +0 -0
  30. holoscan-2.1.0.data/purelib/holoscan/cli/runner/__init__.py +18 -0
  31. holoscan-2.1.0.data/purelib/holoscan/cli/runner/resources.py +174 -0
  32. holoscan-2.1.0.data/purelib/holoscan/cli/runner/run_command.py +204 -0
  33. holoscan-2.1.0.data/purelib/holoscan/cli/runner/runner.py +306 -0
  34. holoscan-2.1.0.data/purelib/holoscan/cli/version/__init__.py +18 -0
  35. holoscan-2.1.0.data/purelib/holoscan/cli/version/version.py +50 -0
  36. holoscan-2.1.0.data/purelib/holoscan/conditions/__init__.py +45 -0
  37. holoscan-2.1.0.data/purelib/holoscan/conditions/_conditions.cpython-38-aarch64-linux-gnu.so +0 -0
  38. holoscan-2.1.0.data/purelib/holoscan/core/__init__.py +367 -0
  39. holoscan-2.1.0.data/purelib/holoscan/core/_core.cpython-38-aarch64-linux-gnu.so +0 -0
  40. holoscan-2.1.0.data/purelib/holoscan/executors/__init__.py +26 -0
  41. holoscan-2.1.0.data/purelib/holoscan/executors/_executors.cpython-38-aarch64-linux-gnu.so +0 -0
  42. holoscan-2.1.0.data/purelib/holoscan/graphs/__init__.py +32 -0
  43. holoscan-2.1.0.data/purelib/holoscan/graphs/_graphs.cpython-38-aarch64-linux-gnu.so +0 -0
  44. holoscan-2.1.0.data/purelib/holoscan/gxf/__init__.py +57 -0
  45. holoscan-2.1.0.data/purelib/holoscan/gxf/_gxf.cpython-38-aarch64-linux-gnu.so +0 -0
  46. holoscan-2.1.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_holoscan_wrapper.so +0 -0
  47. holoscan-2.1.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_holoscan_wrapper_lib.so +0 -0
  48. holoscan-2.1.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_ucx_holoscan.so +0 -0
  49. holoscan-2.1.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_ucx_holoscan_lib.so +0 -0
  50. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_app.so +0 -0
  51. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_core.so +0 -0
  52. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_cuda.so +0 -0
  53. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_logger.so +0 -0
  54. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_multimedia.so +0 -0
  55. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_sample.so +0 -0
  56. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_serialization.so +0 -0
  57. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_std.so +0 -0
  58. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_ucx.so +0 -0
  59. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_core.so.2.1.0 +0 -0
  60. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_infer.so.2.1.0 +0 -0
  61. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_infer_onnx_runtime.so.2.1.0 +0 -0
  62. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_infer_torch.so.2.1.0 +0 -0
  63. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_infer_utils.so.2.1.0 +0 -0
  64. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_logger.so.2.1.0 +0 -0
  65. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_aja.so.2.1.0 +0 -0
  66. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_async_ping_rx.so.2.1.0 +0 -0
  67. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_async_ping_tx.so.2.1.0 +0 -0
  68. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_bayer_demosaic.so.2.1.0 +0 -0
  69. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_format_converter.so.2.1.0 +0 -0
  70. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_gxf_codelet.so.2.1.0 +0 -0
  71. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_holoviz.so.2.1.0 +0 -0
  72. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_inference.so.2.1.0 +0 -0
  73. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_inference_processor.so.2.1.0 +0 -0
  74. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_ping_rx.so.2.1.0 +0 -0
  75. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_ping_tx.so.2.1.0 +0 -0
  76. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_segmentation_postprocessor.so.2.1.0 +0 -0
  77. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_v4l2.so.2.1.0 +0 -0
  78. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_video_stream_recorder.so.2.1.0 +0 -0
  79. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_video_stream_replayer.so.2.1.0 +0 -0
  80. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_spdlog_logger.so.2.1.0 +0 -0
  81. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_viz.so.2.1.0 +0 -0
  82. holoscan-2.1.0.data/purelib/holoscan/lib/libucm.so.0.0.0 +0 -0
  83. holoscan-2.1.0.data/purelib/holoscan/lib/libucp.so.0.0.0 +0 -0
  84. holoscan-2.1.0.data/purelib/holoscan/lib/libucs.so.0.0.0 +0 -0
  85. holoscan-2.1.0.data/purelib/holoscan/lib/libucs_signal.so.0.0.0 +0 -0
  86. holoscan-2.1.0.data/purelib/holoscan/lib/libuct.so.0.0.0 +0 -0
  87. holoscan-2.1.0.data/purelib/holoscan/lib/libyaml-cpp.so.0.7.0 +0 -0
  88. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libucm_cuda.so.0.0.0 +0 -0
  89. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libuct_cma.so.0.0.0 +0 -0
  90. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libuct_cuda.so.0.0.0 +0 -0
  91. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libuct_cuda_gdrcopy.so.0.0.0 +0 -0
  92. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libuct_ib.so.0.0.0 +0 -0
  93. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libuct_rdmacm.so.0.0.0 +0 -0
  94. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libucx_perftest_cuda.so.0.0.0 +0 -0
  95. holoscan-2.1.0.data/purelib/holoscan/logger/__init__.py +37 -0
  96. holoscan-2.1.0.data/purelib/holoscan/logger/_logger.cpython-38-aarch64-linux-gnu.so +0 -0
  97. holoscan-2.1.0.data/purelib/holoscan/network_contexts/__init__.py +28 -0
  98. holoscan-2.1.0.data/purelib/holoscan/network_contexts/_network_contexts.cpython-38-aarch64-linux-gnu.so +0 -0
  99. holoscan-2.1.0.data/purelib/holoscan/operators/__init__.py +93 -0
  100. holoscan-2.1.0.data/purelib/holoscan/operators/aja_source/__init__.py +22 -0
  101. holoscan-2.1.0.data/purelib/holoscan/operators/aja_source/_aja_source.cpython-38-aarch64-linux-gnu.so +0 -0
  102. holoscan-2.1.0.data/purelib/holoscan/operators/bayer_demosaic/__init__.py +24 -0
  103. holoscan-2.1.0.data/purelib/holoscan/operators/bayer_demosaic/_bayer_demosaic.cpython-38-aarch64-linux-gnu.so +0 -0
  104. holoscan-2.1.0.data/purelib/holoscan/operators/format_converter/__init__.py +23 -0
  105. holoscan-2.1.0.data/purelib/holoscan/operators/format_converter/_format_converter.cpython-38-aarch64-linux-gnu.so +0 -0
  106. holoscan-2.1.0.data/purelib/holoscan/operators/gxf_codelet/__init__.py +67 -0
  107. holoscan-2.1.0.data/purelib/holoscan/operators/gxf_codelet/_gxf_codelet.cpython-38-aarch64-linux-gnu.so +0 -0
  108. holoscan-2.1.0.data/purelib/holoscan/operators/holoviz/__init__.py +230 -0
  109. holoscan-2.1.0.data/purelib/holoscan/operators/holoviz/_holoviz.cpython-38-aarch64-linux-gnu.so +0 -0
  110. holoscan-2.1.0.data/purelib/holoscan/operators/inference/__init__.py +23 -0
  111. holoscan-2.1.0.data/purelib/holoscan/operators/inference/_inference.cpython-38-aarch64-linux-gnu.so +0 -0
  112. holoscan-2.1.0.data/purelib/holoscan/operators/inference_processor/__init__.py +23 -0
  113. holoscan-2.1.0.data/purelib/holoscan/operators/inference_processor/_inference_processor.cpython-38-aarch64-linux-gnu.so +0 -0
  114. holoscan-2.1.0.data/purelib/holoscan/operators/ping_rx/__init__.py +45 -0
  115. holoscan-2.1.0.data/purelib/holoscan/operators/ping_tx/__init__.py +46 -0
  116. holoscan-2.1.0.data/purelib/holoscan/operators/segmentation_postprocessor/__init__.py +23 -0
  117. holoscan-2.1.0.data/purelib/holoscan/operators/segmentation_postprocessor/_segmentation_postprocessor.cpython-38-aarch64-linux-gnu.so +0 -0
  118. holoscan-2.1.0.data/purelib/holoscan/operators/v4l2_video_capture/__init__.py +23 -0
  119. holoscan-2.1.0.data/purelib/holoscan/operators/v4l2_video_capture/_v4l2_video_capture.cpython-38-aarch64-linux-gnu.so +0 -0
  120. holoscan-2.1.0.data/purelib/holoscan/operators/video_stream_recorder/__init__.py +22 -0
  121. holoscan-2.1.0.data/purelib/holoscan/operators/video_stream_recorder/_video_stream_recorder.cpython-38-aarch64-linux-gnu.so +0 -0
  122. holoscan-2.1.0.data/purelib/holoscan/operators/video_stream_replayer/__init__.py +22 -0
  123. holoscan-2.1.0.data/purelib/holoscan/operators/video_stream_replayer/_video_stream_replayer.cpython-38-aarch64-linux-gnu.so +0 -0
  124. holoscan-2.1.0.data/purelib/holoscan/resources/__init__.py +138 -0
  125. holoscan-2.1.0.data/purelib/holoscan/resources/_resources.cpython-38-aarch64-linux-gnu.so +0 -0
  126. holoscan-2.1.0.data/purelib/holoscan/schedulers/__init__.py +32 -0
  127. holoscan-2.1.0.data/purelib/holoscan/schedulers/_schedulers.cpython-38-aarch64-linux-gnu.so +0 -0
  128. holoscan-2.1.0.data/purelib/holoscan-2.1.0.pth +1 -0
  129. holoscan-2.1.0.dist-info/LICENSE.txt +202 -0
  130. holoscan-2.1.0.dist-info/METADATA +111 -0
  131. holoscan-2.1.0.dist-info/NOTICE.txt +170 -0
  132. holoscan-2.1.0.dist-info/NVIDIA-AI-PRODUCT-EULA.txt +243 -0
  133. holoscan-2.1.0.dist-info/RECORD +138 -0
  134. holoscan-2.1.0.dist-info/WHEEL +5 -0
  135. holoscan-2.1.0.dist-info/axle.lck +0 -0
  136. holoscan-2.1.0.dist-info/entry_points.txt +3 -0
  137. holoscan-2.1.0.dist-info/symlinks.txt +72 -0
  138. holoscan-2.1.0.dist-info/top_level.txt +3 -0
@@ -0,0 +1,405 @@
1
+ """
2
+ SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
+ SPDX-License-Identifier: Apache-2.0
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ """ # noqa: E501
17
+
18
+ import logging
19
+ from argparse import Namespace
20
+ from pathlib import Path
21
+ from typing import List, Optional, Tuple, Union
22
+
23
+ from ..common.artifact_sources import ArtifactSources
24
+ from ..common.constants import Constants
25
+ from ..common.dockerutils import image_exists
26
+ from ..common.enum_types import ApplicationType, SdkType
27
+ from ..common.exceptions import IncompatiblePlatformConfigurationError, InvalidSdkError
28
+ from ..common.sdk_utils import detect_sdk, detect_sdk_version
29
+ from .parameters import PlatformParameters
30
+ from .sdk_downloader import download_sdk_debian_file
31
+
32
+
33
+ class Platform:
34
+ def __init__(self, artifact_sources: ArtifactSources) -> None:
35
+ """
36
+ Args:
37
+ args (Namespace): Input arguments for Packager from CLI
38
+ """
39
+ self._logger = logging.getLogger("packager")
40
+ self._artifact_sources = artifact_sources
41
+
42
+ def configure_platforms(
43
+ self,
44
+ args: Namespace,
45
+ temp_dir: str,
46
+ version: str,
47
+ application_type: ApplicationType,
48
+ ) -> Tuple[SdkType, str, str, List[PlatformParameters]]:
49
+ """Configures a list of platforms that need to be built.
50
+ 1. Detect the SDK to use
51
+ 2. Detect the version of the SDK to use
52
+ 3. Ensure user provided arguments are valid and do not conflict
53
+ 4. Builds a list of platforms to be built where each platform includes the following:
54
+ a. SDK distribution file(s) to use
55
+ b. Base image to use
56
+ c. Build image to use if application type is C++
57
+
58
+ Args:
59
+ args (Namespace): user provided arguments
60
+ temp_dir (str): temporary path for storing downloaded artifacts
61
+ version (str): application version
62
+ application_type (ApplicationType): application type
63
+
64
+ Returns:
65
+ Tuple[SdkType, str, str, List[PlatformParameters]]: A tuple contains SDK, Holoscan SDK
66
+ version, MONAI Deploy App SDK version and list of platforms to be built
67
+ """
68
+ sdk = detect_sdk(args.sdk)
69
+ holoscan_sdk_version, monai_deploy_app_sdk_version = detect_sdk_version(
70
+ sdk, self._artifact_sources, args.sdk_version
71
+ )
72
+
73
+ self._validate_platform_options(args, sdk)
74
+
75
+ platforms = []
76
+ for platform in args.platform:
77
+ platform_config = args.platform_config
78
+
79
+ platform_parameters = PlatformParameters(platform, platform_config, args.tag, version)
80
+
81
+ (
82
+ platform_parameters.custom_base_image,
83
+ platform_parameters.base_image,
84
+ ) = self._find_base_image(platform_parameters, holoscan_sdk_version, args.base_image)
85
+
86
+ platform_parameters.build_image = self._find_build_image(
87
+ platform_parameters, holoscan_sdk_version, application_type, args.build_image
88
+ )
89
+
90
+ (
91
+ (
92
+ platform_parameters.custom_holoscan_sdk,
93
+ platform_parameters.holoscan_sdk_file,
94
+ ),
95
+ (
96
+ platform_parameters.custom_monai_deploy_sdk,
97
+ platform_parameters.monai_deploy_sdk_file,
98
+ ),
99
+ ) = self._select_sdk_file(
100
+ platform_parameters,
101
+ temp_dir,
102
+ sdk,
103
+ holoscan_sdk_version,
104
+ monai_deploy_app_sdk_version,
105
+ application_type,
106
+ args.holoscan_sdk_file,
107
+ args.monai_deploy_sdk_file,
108
+ )
109
+
110
+ if sdk is SdkType.Holoscan:
111
+ platform_parameters.health_probe = self._artifact_sources.health_probe(
112
+ holoscan_sdk_version
113
+ )[platform_parameters.platform_arch.value]
114
+
115
+ platforms.append(platform_parameters)
116
+
117
+ return (sdk, holoscan_sdk_version, monai_deploy_app_sdk_version, platforms)
118
+
119
+ def _validate_platform_options(self, args: Namespace, sdk: SdkType):
120
+ """Validates user requests.
121
+ - Packager accepts a single SDK distribution file, if user requests to build x64 and arm64
122
+ at the same time, raise exception
123
+ - If Packager was called using 'holoscan' command while user provides a MONAI Deploy APP
124
+ SDK file, raise exception
125
+
126
+ Args:
127
+ args (Namespace): user provided arguments
128
+ sdk (SdkType): SDK type
129
+
130
+ Raises:
131
+ IncompatiblePlatformConfigurationError: when validation fails
132
+ """
133
+ if (args.holoscan_sdk_file is not None or args.monai_deploy_sdk_file is not None) and len(
134
+ args.platform
135
+ ) > 1:
136
+ raise IncompatiblePlatformConfigurationError(
137
+ "Validation error: '--sdk-file' cannot be used with multiple platforms."
138
+ )
139
+ if sdk == SdkType.Holoscan and args.monai_deploy_sdk_file is not None:
140
+ raise IncompatiblePlatformConfigurationError(
141
+ "--monai-deploy-sdk-file was used. Did you mean to use "
142
+ "'monai-deploy package' command instead?"
143
+ )
144
+
145
+ def _find_base_image(
146
+ self,
147
+ platform_parameters: PlatformParameters,
148
+ sdk_version: str,
149
+ base_image: Optional[str] = None,
150
+ ) -> Tuple[bool, str]:
151
+ """
152
+ Ensure user provided base image exists in Docker or locate the base image to use based on
153
+ request platform.
154
+
155
+ Args:
156
+ platform_parameters (PlatformParameters): target platform parameters
157
+ sdk_version (str): SDK version
158
+ base_image (Optional[str]): user provided base image
159
+
160
+ Returns:
161
+ (Tuple(bool, str)): bool: True if using user provided image.
162
+ str: base image for building the image based on the given
163
+ platform and SDK version.
164
+ """
165
+ if base_image is not None:
166
+ if image_exists(base_image):
167
+ return (True, base_image)
168
+ else:
169
+ raise InvalidSdkError(f"Specified base image cannot be found: {base_image}")
170
+
171
+ try:
172
+ return (
173
+ False,
174
+ self._artifact_sources.base_images(sdk_version)[
175
+ platform_parameters.platform_config.value
176
+ ][platform_parameters.platform.value],
177
+ )
178
+ except Exception as ex:
179
+ raise IncompatiblePlatformConfigurationError(
180
+ f"""No base image found for the selected configuration:
181
+ Platform: {platform_parameters.platform}
182
+ Configuration: {platform_parameters.platform_config}
183
+ Version: {sdk_version}"""
184
+ ) from ex
185
+
186
+ def _find_build_image(
187
+ self,
188
+ platform_parameters: PlatformParameters,
189
+ sdk_version: str,
190
+ application_type: ApplicationType,
191
+ build_image: Optional[str] = None,
192
+ ) -> Optional[str]:
193
+ """
194
+ Ensure user provided build image exists or locate the build image to use based on the
195
+ requested platform.
196
+
197
+ Args:
198
+ platform_parameters (PlatformParameters): target platform parameters
199
+ sdk_version (str): SDK version
200
+ application_type (ApplicationType): application type
201
+ build_image (Optional[str]): user provided build image
202
+
203
+ Returns:
204
+ (str): build image for building the image based on the given platform and SDK version.
205
+ """
206
+ if build_image is not None:
207
+ if image_exists(build_image):
208
+ return build_image
209
+ else:
210
+ raise InvalidSdkError(f"Specified build image cannot be found: {build_image}")
211
+
212
+ if application_type == ApplicationType.CppCMake:
213
+ try:
214
+ return self._artifact_sources.build_images(sdk_version)[
215
+ platform_parameters.platform_config.value
216
+ ][platform_parameters.platform.value]
217
+ except Exception as ex:
218
+ raise IncompatiblePlatformConfigurationError(
219
+ f"No build image found for the selected configuration:"
220
+ f"\n Platform: {platform_parameters.platform.value}"
221
+ f"\n Configuration: {platform_parameters.platform_config.value}"
222
+ f"\n Version: {sdk_version}"
223
+ ) from ex
224
+ else:
225
+ return None
226
+
227
+ def _select_sdk_file(
228
+ self,
229
+ platform_parameters: PlatformParameters,
230
+ temp_dir: str,
231
+ sdk: SdkType,
232
+ holoscan_sdk_version: str,
233
+ monai_deploy_app_sdk_version: Optional[str],
234
+ application_type: ApplicationType,
235
+ holoscan_sdk_file: Optional[Path] = None,
236
+ monai_deploy_sdk_file: Optional[Path] = None,
237
+ ) -> Tuple[Tuple[bool, Union[Path, str]], Tuple[Union[Path, str, None]]]:
238
+ """
239
+ Detects the SDK distributable to use based on internal mapping or user input.
240
+
241
+ - C++ & binary applications, attempt to download the SDK file.
242
+ - Python application, use Holoscan or MONAI Deploy App SDK PyPI package.
243
+
244
+ Args:
245
+ platform_parameters (PlatformParameters): target platform parameters
246
+ temp_dir (str): temporary location for storing downloaded files.
247
+ sdk (SdkType): SDK to use
248
+ holoscan_sdk_version (str): Holoscan SDK version
249
+ monai_deploy_app_sdk_version (Optional[str]): MONAI Deploy SDK version
250
+ application_type (ApplicationType): application type
251
+ holoscan_sdk_file (Optional[Path]): path to the user specified Holoscan SDK file
252
+ monai_deploy_sdk_file (Optional[Path]): path to the user specified MONAI Deploy
253
+ App SDK file
254
+
255
+ Returns:
256
+ (Tuple[Union[Path, str], Union[Path, str, None]]): A tuple where the first value
257
+ contains Holoscan SDK and the second value contains MONAI Deploy App SDK.
258
+
259
+ Raises:
260
+ InvalidSdkError: when user specified SDK file does not pass validation.
261
+ """
262
+ if sdk == SdkType.Holoscan:
263
+ return (
264
+ self._get_holoscan_sdk(
265
+ platform_parameters,
266
+ temp_dir,
267
+ SdkType.Holoscan,
268
+ holoscan_sdk_version,
269
+ application_type,
270
+ holoscan_sdk_file,
271
+ ),
272
+ (None, None),
273
+ )
274
+ elif sdk == SdkType.MonaiDeploy:
275
+ if monai_deploy_app_sdk_version is None:
276
+ raise InvalidSdkError("MONAI Deploy App SDK version missing")
277
+ return (
278
+ self._get_holoscan_sdk(
279
+ platform_parameters,
280
+ temp_dir,
281
+ SdkType.Holoscan,
282
+ holoscan_sdk_version,
283
+ application_type,
284
+ holoscan_sdk_file,
285
+ ),
286
+ self._get_monai_deploy_sdk(monai_deploy_app_sdk_version, monai_deploy_sdk_file),
287
+ )
288
+ return (None, None)
289
+
290
+ def _get_holoscan_sdk(
291
+ self,
292
+ platform_parameters: PlatformParameters,
293
+ temp_dir: str,
294
+ sdk: SdkType,
295
+ sdk_version: str,
296
+ application_type: ApplicationType,
297
+ sdk_file: Optional[Path] = None,
298
+ ) -> Tuple[bool, Union[Path, str]]:
299
+ """
300
+ Validates Holoscan SDK redistributable file if specified.
301
+ Otherwise, attempt to download the SDK file from internet.
302
+
303
+ Args:
304
+ platform_parameters (PlatformParameters): Platform parameters
305
+ temp_dir (str): Temporary location for storing downloaded distribution files.
306
+ sdk (SdkType): SDK for building the application
307
+ sdk_version (str): SDK version. Defaults to None.
308
+ application_type (ApplicationType): application type
309
+ sdk_file (Optional[Path], optional): SDK file from user input. Defaults to None.
310
+
311
+ Raises:
312
+ InvalidSdkError: when an invalid SDK file is provided or unable to find matching SDK
313
+ file.
314
+
315
+ Returns:
316
+ Tuple[bool, Union[Path, str]]:
317
+ bool: True when user provides SDk file. Otherwise, False.
318
+ Union[Path, str]: Path to the SDK redistributable file.
319
+ """
320
+ assert sdk is SdkType.Holoscan
321
+
322
+ if sdk_file is not None:
323
+ if application_type in [
324
+ ApplicationType.PythonModule,
325
+ ApplicationType.PythonFile,
326
+ ]:
327
+ if sdk_file.suffix not in Constants.PYPI_FILE_EXTENSIONS:
328
+ raise InvalidSdkError(
329
+ "Invalid SDK file format, must be a PyPI wheel file with .whl file "
330
+ "extension."
331
+ )
332
+ return (True, sdk_file)
333
+ elif application_type in [
334
+ ApplicationType.CppCMake,
335
+ ApplicationType.Binary,
336
+ ]:
337
+ if sdk_file.suffix != Constants.DEBIAN_FILE_EXTENSION:
338
+ raise InvalidSdkError(
339
+ "Invalid SDK file format, must be a Debian package file with .deb "
340
+ "file extension."
341
+ )
342
+ return (True, sdk_file)
343
+
344
+ raise InvalidSdkError(f"Unknown application type: {application_type.value}")
345
+ else:
346
+ if application_type in [
347
+ ApplicationType.PythonModule,
348
+ ApplicationType.PythonFile,
349
+ ]:
350
+ return (False, Constants.PYPI_INSTALL_SOURCE)
351
+ elif application_type in [
352
+ ApplicationType.CppCMake,
353
+ ApplicationType.Binary,
354
+ ]:
355
+ debian_package_source = self._artifact_sources.debian_packages(
356
+ sdk_version,
357
+ platform_parameters.platform_arch,
358
+ platform_parameters.platform_config,
359
+ )
360
+ if debian_package_source is not None:
361
+ return (
362
+ False,
363
+ download_sdk_debian_file(
364
+ debian_package_source,
365
+ sdk_version,
366
+ platform_parameters.platform_arch,
367
+ temp_dir,
368
+ self._logger,
369
+ self._artifact_sources,
370
+ ),
371
+ )
372
+ else:
373
+ raise InvalidSdkError(
374
+ f"No match Debian packages found for Holoscan SDK v{sdk_version}. Try "
375
+ "using `--sdk-file` instead."
376
+ )
377
+
378
+ raise InvalidSdkError(f"Unknown application type: {application_type.value}")
379
+
380
+ def _get_monai_deploy_sdk(
381
+ self, monai_deploy_app_sdk_version: Optional[str], sdk_file: Optional[Path] = None
382
+ ) -> Tuple[Union[Path, str]]:
383
+ """
384
+ Validates MONAI Deploy SDK redistributable file if specified.
385
+ Otherwise, Docker build stage will install the SDK from PyPI.
386
+
387
+ Args:
388
+ sdk_file (Optional[Path], optional): SDK file from user input. Defaults to None.
389
+ monai_deploy_app_sdk_version: (Optional[str]): MONAI Deploy App SDK version
390
+ Raises:
391
+ InvalidSdkError: when an invalid SDK file is provided or unable to find matching SDK
392
+ file.
393
+
394
+ Returns:
395
+ Union[Path, str]: Path to the SDK redistributable file.
396
+ """
397
+
398
+ if sdk_file is not None:
399
+ if sdk_file.suffix not in Constants.PYPI_FILE_EXTENSIONS:
400
+ raise InvalidSdkError(
401
+ "Invalid SDK file format, must be a PyPI wheel file with .whl file extension."
402
+ )
403
+ return (True, sdk_file)
404
+
405
+ return (False, None)
@@ -0,0 +1,147 @@
1
+ """
2
+ SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
+ SPDX-License-Identifier: Apache-2.0
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ """ # noqa: E501
17
+
18
+ import logging
19
+ import os
20
+ import zipfile
21
+ from io import BytesIO
22
+ from pathlib import Path
23
+
24
+ import requests
25
+
26
+ from ..common.artifact_sources import ArtifactSources
27
+ from ..common.enum_types import Arch
28
+ from ..common.exceptions import ExternalAssetDownloadError, InvalidSdkError
29
+
30
+
31
+ def download_health_probe_file(
32
+ sdk_version: str,
33
+ arch: Arch,
34
+ temp_dir: str,
35
+ logger: logging.Logger,
36
+ artifact_sources: ArtifactSources,
37
+ ) -> Path:
38
+ """Download gRPC health probe for the specified architecture.
39
+
40
+ Args:
41
+ sdk_version (str): SDK version
42
+ arch (Arch): binary architecture to download
43
+ temp_dir (str): temporary location for storing downloaded file
44
+ logger (logging.Logger): logger
45
+ artifact_sources (ArtifactSources): artifact source
46
+
47
+ Raises:
48
+ ExternalAssetDownloadError: when unable to download gRPC health probe
49
+
50
+ Returns:
51
+ Path: path to the downloaded file
52
+ """
53
+ target_dir = os.path.join(temp_dir, arch.name)
54
+ target_file = os.path.join(target_dir, "grpc_health_probe")
55
+ if os.path.exists(target_file) and os.path.isfile(target_file):
56
+ return Path(target_file)
57
+
58
+ if not os.path.exists(target_dir):
59
+ os.mkdir(target_dir)
60
+
61
+ try:
62
+ download_url = artifact_sources.health_probe(sdk_version)[arch.value]
63
+ logger.info(f"Downloading gRPC health probe from {download_url}...")
64
+ response = requests.get(download_url)
65
+ if not response.ok:
66
+ raise ExternalAssetDownloadError(
67
+ f"failed to download health probe utility from {download_url} with "
68
+ "HTTP status {response.status_code}."
69
+ )
70
+ except Exception as e:
71
+ raise ExternalAssetDownloadError(f"error downloading health probe: {e}") from e
72
+
73
+ try:
74
+ logger.info(f"Saving gRPC health probe to {target_file}...")
75
+ with open(target_file, "wb") as f:
76
+ f.write(response.content)
77
+ return Path(target_file)
78
+ except Exception as e:
79
+ raise ExternalAssetDownloadError(f"error saving health probe: {e}") from e
80
+
81
+
82
+ def download_sdk_debian_file(
83
+ debian_package_source: str,
84
+ sdk_version: str,
85
+ arch: Arch,
86
+ temp_dir: str,
87
+ logger: logging.Logger,
88
+ artifact_sources: ArtifactSources,
89
+ ) -> Path:
90
+ """Download Holoscan SDK Debian package for the specified SDK version and architecture.
91
+
92
+ Args:
93
+ debian_package_source(str): URI to download the Debian package from
94
+ sdk_version (str): SDK version
95
+ arch (Arch): Architecture
96
+ temp_dir (str): temporary location for storing downloaded file
97
+ logger (logging.Logger): logger
98
+ artifact_sources (ArtifactSources): artifact source
99
+
100
+ Raises:
101
+ InvalidSdkError: when unable to download the Holoscan SDK Debian package
102
+
103
+ Returns:
104
+ Path: path to the downloaded file
105
+ """
106
+ try:
107
+ logger.info(
108
+ f"Downloading Holoscan Debian package ({arch.name}) from {debian_package_source}..."
109
+ )
110
+ response = requests.get(debian_package_source)
111
+ if not response.ok:
112
+ raise InvalidSdkError(
113
+ f"failed to download SDK from {debian_package_source} with "
114
+ "HTTP status {response.status_code}."
115
+ )
116
+ except Exception as ex:
117
+ raise InvalidSdkError(
118
+ f"failed to download SDK from {debian_package_source}: {response.reason}."
119
+ ) from ex
120
+
121
+ if debian_package_source.endswith(".deb"):
122
+ filename = Path(debian_package_source).name
123
+ output_dir = os.path.join(temp_dir, f"{sdk_version}_{arch.name}")
124
+ os.mkdir(output_dir)
125
+ file_path = os.path.join(output_dir, filename)
126
+ with open(file_path, "wb") as f:
127
+ f.write(response.content)
128
+ logger.info(f"Debian package for {arch.name} downloaded to {file_path}")
129
+ return Path(file_path)
130
+ else:
131
+ try:
132
+ z = zipfile.ZipFile(BytesIO(response.content))
133
+ unzip_dir = os.path.join(temp_dir, f"{sdk_version}_{arch.name}")
134
+ logger.info(f"Extracting Debian Package to {unzip_dir}...")
135
+ z.extractall(unzip_dir)
136
+ except Exception as ex:
137
+ raise InvalidSdkError(
138
+ f"failed to unzip SDK from {debian_package_source}: {response.reason}."
139
+ ) from ex
140
+
141
+ for file in os.listdir(unzip_dir):
142
+ if file.endswith(".deb"):
143
+ file_path = os.path.join(unzip_dir, file)
144
+ logger.info(f"Debian package for {arch.name} downloaded to {file_path}")
145
+ return Path(file_path)
146
+
147
+ raise InvalidSdkError(f"Debian package not found in {debian_package_source}")