holoscan 2.6.0__cp312-cp312-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 (126) hide show
  1. holoscan-2.6.0.data/purelib/holoscan/__init__.py +133 -0
  2. holoscan-2.6.0.data/purelib/holoscan/cli/__init__.py +32 -0
  3. holoscan-2.6.0.data/purelib/holoscan/cli/__main__.py +159 -0
  4. holoscan-2.6.0.data/purelib/holoscan/cli/common/argparse_types.py +153 -0
  5. holoscan-2.6.0.data/purelib/holoscan/cli/common/artifact_sources.py +149 -0
  6. holoscan-2.6.0.data/purelib/holoscan/cli/common/constants.py +119 -0
  7. holoscan-2.6.0.data/purelib/holoscan/cli/common/dockerutils.py +509 -0
  8. holoscan-2.6.0.data/purelib/holoscan/cli/common/enum_types.py +52 -0
  9. holoscan-2.6.0.data/purelib/holoscan/cli/common/exceptions.py +130 -0
  10. holoscan-2.6.0.data/purelib/holoscan/cli/common/sdk_utils.py +180 -0
  11. holoscan-2.6.0.data/purelib/holoscan/cli/common/utils.py +130 -0
  12. holoscan-2.6.0.data/purelib/holoscan/cli/logging.json +37 -0
  13. holoscan-2.6.0.data/purelib/holoscan/cli/nics/__init__.py +18 -0
  14. holoscan-2.6.0.data/purelib/holoscan/cli/nics/nics.py +34 -0
  15. holoscan-2.6.0.data/purelib/holoscan/cli/packager/__init__.py +18 -0
  16. holoscan-2.6.0.data/purelib/holoscan/cli/packager/arguments.py +137 -0
  17. holoscan-2.6.0.data/purelib/holoscan/cli/packager/config_reader.py +181 -0
  18. holoscan-2.6.0.data/purelib/holoscan/cli/packager/container_builder.py +368 -0
  19. holoscan-2.6.0.data/purelib/holoscan/cli/packager/manifest_files.py +220 -0
  20. holoscan-2.6.0.data/purelib/holoscan/cli/packager/models.py +93 -0
  21. holoscan-2.6.0.data/purelib/holoscan/cli/packager/package_command.py +189 -0
  22. holoscan-2.6.0.data/purelib/holoscan/cli/packager/packager.py +122 -0
  23. holoscan-2.6.0.data/purelib/holoscan/cli/packager/parameters.py +558 -0
  24. holoscan-2.6.0.data/purelib/holoscan/cli/packager/platforms.py +402 -0
  25. holoscan-2.6.0.data/purelib/holoscan/cli/packager/templates/Dockerfile.jinja2 +470 -0
  26. holoscan-2.6.0.data/purelib/holoscan/cli/packager/templates/dockerignore +93 -0
  27. holoscan-2.6.0.data/purelib/holoscan/cli/packager/templates/tools.sh +416 -0
  28. holoscan-2.6.0.data/purelib/holoscan/cli/py.typed +0 -0
  29. holoscan-2.6.0.data/purelib/holoscan/cli/runner/__init__.py +18 -0
  30. holoscan-2.6.0.data/purelib/holoscan/cli/runner/resources.py +174 -0
  31. holoscan-2.6.0.data/purelib/holoscan/cli/runner/run_command.py +203 -0
  32. holoscan-2.6.0.data/purelib/holoscan/cli/runner/runner.py +306 -0
  33. holoscan-2.6.0.data/purelib/holoscan/cli/version/__init__.py +18 -0
  34. holoscan-2.6.0.data/purelib/holoscan/cli/version/version.py +50 -0
  35. holoscan-2.6.0.data/purelib/holoscan/conditions/__init__.py +57 -0
  36. holoscan-2.6.0.data/purelib/holoscan/core/__init__.py +430 -0
  37. holoscan-2.6.0.data/purelib/holoscan/decorator.py +592 -0
  38. holoscan-2.6.0.data/purelib/holoscan/executors/__init__.py +26 -0
  39. holoscan-2.6.0.data/purelib/holoscan/graphs/__init__.py +32 -0
  40. holoscan-2.6.0.data/purelib/holoscan/gxf/__init__.py +57 -0
  41. holoscan-2.6.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_holoscan_wrapper.so +0 -0
  42. holoscan-2.6.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_holoscan_wrapper_lib.so +0 -0
  43. holoscan-2.6.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_ucx_holoscan.so +0 -0
  44. holoscan-2.6.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_ucx_holoscan_lib.so +0 -0
  45. holoscan-2.6.0.data/purelib/holoscan/lib/libgxf_app.so +0 -0
  46. holoscan-2.6.0.data/purelib/holoscan/lib/libgxf_core.so +0 -0
  47. holoscan-2.6.0.data/purelib/holoscan/lib/libgxf_cuda.so +0 -0
  48. holoscan-2.6.0.data/purelib/holoscan/lib/libgxf_logger.so +0 -0
  49. holoscan-2.6.0.data/purelib/holoscan/lib/libgxf_multimedia.so +0 -0
  50. holoscan-2.6.0.data/purelib/holoscan/lib/libgxf_rmm.so +0 -0
  51. holoscan-2.6.0.data/purelib/holoscan/lib/libgxf_sample.so +0 -0
  52. holoscan-2.6.0.data/purelib/holoscan/lib/libgxf_serialization.so +0 -0
  53. holoscan-2.6.0.data/purelib/holoscan/lib/libgxf_std.so +0 -0
  54. holoscan-2.6.0.data/purelib/holoscan/lib/libgxf_ucx.so +0 -0
  55. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_core.so.2.6.0 +0 -0
  56. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_infer.so.2.6.0 +0 -0
  57. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_infer_onnx_runtime.so.2.6.0 +0 -0
  58. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_infer_torch.so.2.6.0 +0 -0
  59. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_infer_utils.so.2.6.0 +0 -0
  60. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_logger.so.2.6.0 +0 -0
  61. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_aja.so.2.6.0 +0 -0
  62. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_async_ping_rx.so.2.6.0 +0 -0
  63. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_async_ping_tx.so.2.6.0 +0 -0
  64. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_bayer_demosaic.so.2.6.0 +0 -0
  65. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_format_converter.so.2.6.0 +0 -0
  66. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_gxf_codelet.so.2.6.0 +0 -0
  67. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_holoviz.so.2.6.0 +0 -0
  68. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_inference.so.2.6.0 +0 -0
  69. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_inference_processor.so.2.6.0 +0 -0
  70. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_ping_rx.so.2.6.0 +0 -0
  71. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_ping_tensor_rx.so.2.6.0 +0 -0
  72. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_ping_tensor_tx.so.2.6.0 +0 -0
  73. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_ping_tx.so.2.6.0 +0 -0
  74. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_segmentation_postprocessor.so.2.6.0 +0 -0
  75. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_v4l2.so.2.6.0 +0 -0
  76. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_video_stream_recorder.so.2.6.0 +0 -0
  77. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_op_video_stream_replayer.so.2.6.0 +0 -0
  78. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_profiler.so.2.6.0 +0 -0
  79. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_spdlog_logger.so.2.6.0 +0 -0
  80. holoscan-2.6.0.data/purelib/holoscan/lib/libholoscan_viz.so.2.6.0 +0 -0
  81. holoscan-2.6.0.data/purelib/holoscan/lib/libucm.so.0.0.0 +0 -0
  82. holoscan-2.6.0.data/purelib/holoscan/lib/libucp.so.0.0.0 +0 -0
  83. holoscan-2.6.0.data/purelib/holoscan/lib/libucs.so.0.0.0 +0 -0
  84. holoscan-2.6.0.data/purelib/holoscan/lib/libucs_signal.so.0.0.0 +0 -0
  85. holoscan-2.6.0.data/purelib/holoscan/lib/libuct.so.0.0.0 +0 -0
  86. holoscan-2.6.0.data/purelib/holoscan/lib/libyaml-cpp.so.0.7.0 +0 -0
  87. holoscan-2.6.0.data/purelib/holoscan/lib/ucx/libucm_cuda.so.0.0.0 +0 -0
  88. holoscan-2.6.0.data/purelib/holoscan/lib/ucx/libucs_fuse.so.0.0.0 +0 -0
  89. holoscan-2.6.0.data/purelib/holoscan/lib/ucx/libuct_cma.so.0.0.0 +0 -0
  90. holoscan-2.6.0.data/purelib/holoscan/lib/ucx/libuct_cuda.so.0.0.0 +0 -0
  91. holoscan-2.6.0.data/purelib/holoscan/lib/ucx/libuct_cuda_gdrcopy.so.0.0.0 +0 -0
  92. holoscan-2.6.0.data/purelib/holoscan/lib/ucx/libuct_ib.so.0.0.0 +0 -0
  93. holoscan-2.6.0.data/purelib/holoscan/lib/ucx/libuct_rdmacm.so.0.0.0 +0 -0
  94. holoscan-2.6.0.data/purelib/holoscan/lib/ucx/libuct_xpmem.so.0.0.0 +0 -0
  95. holoscan-2.6.0.data/purelib/holoscan/lib/ucx/libucx_perftest_cuda.so.0.0.0 +0 -0
  96. holoscan-2.6.0.data/purelib/holoscan/logger/__init__.py +37 -0
  97. holoscan-2.6.0.data/purelib/holoscan/network_contexts/__init__.py +28 -0
  98. holoscan-2.6.0.data/purelib/holoscan/operators/__init__.py +97 -0
  99. holoscan-2.6.0.data/purelib/holoscan/operators/aja_source/__init__.py +22 -0
  100. holoscan-2.6.0.data/purelib/holoscan/operators/bayer_demosaic/__init__.py +24 -0
  101. holoscan-2.6.0.data/purelib/holoscan/operators/format_converter/__init__.py +23 -0
  102. holoscan-2.6.0.data/purelib/holoscan/operators/gxf_codelet/__init__.py +67 -0
  103. holoscan-2.6.0.data/purelib/holoscan/operators/holoviz/__init__.py +424 -0
  104. holoscan-2.6.0.data/purelib/holoscan/operators/inference/__init__.py +23 -0
  105. holoscan-2.6.0.data/purelib/holoscan/operators/inference_processor/__init__.py +23 -0
  106. holoscan-2.6.0.data/purelib/holoscan/operators/ping_rx/__init__.py +45 -0
  107. holoscan-2.6.0.data/purelib/holoscan/operators/ping_tensor_rx/__init__.py +22 -0
  108. holoscan-2.6.0.data/purelib/holoscan/operators/ping_tensor_tx/__init__.py +22 -0
  109. holoscan-2.6.0.data/purelib/holoscan/operators/ping_tx/__init__.py +46 -0
  110. holoscan-2.6.0.data/purelib/holoscan/operators/segmentation_postprocessor/__init__.py +23 -0
  111. holoscan-2.6.0.data/purelib/holoscan/operators/v4l2_video_capture/__init__.py +23 -0
  112. holoscan-2.6.0.data/purelib/holoscan/operators/video_stream_recorder/__init__.py +22 -0
  113. holoscan-2.6.0.data/purelib/holoscan/operators/video_stream_replayer/__init__.py +22 -0
  114. holoscan-2.6.0.data/purelib/holoscan/resources/__init__.py +147 -0
  115. holoscan-2.6.0.data/purelib/holoscan/schedulers/__init__.py +32 -0
  116. holoscan-2.6.0.data/purelib/holoscan-2.6.0.pth +1 -0
  117. holoscan-2.6.0.dist-info/LICENSE.txt +202 -0
  118. holoscan-2.6.0.dist-info/METADATA +125 -0
  119. holoscan-2.6.0.dist-info/NOTICE.txt +174 -0
  120. holoscan-2.6.0.dist-info/NVIDIA-AI-PRODUCT-EULA.txt +243 -0
  121. holoscan-2.6.0.dist-info/RECORD +126 -0
  122. holoscan-2.6.0.dist-info/WHEEL +5 -0
  123. holoscan-2.6.0.dist-info/axle.lck +0 -0
  124. holoscan-2.6.0.dist-info/entry_points.txt +3 -0
  125. holoscan-2.6.0.dist-info/symlinks.txt +82 -0
  126. holoscan-2.6.0.dist-info/top_level.txt +3 -0
@@ -0,0 +1,220 @@
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
+ from pathlib import Path
19
+ from typing import Any
20
+
21
+
22
+ class ApplicationManifest:
23
+ def __init__(self):
24
+ self._data = {}
25
+ self._data["apiVersion"] = None
26
+ self._data["command"] = None
27
+ self._data["environment"] = None
28
+ self._data["input"] = None
29
+ self._data["liveness"] = None
30
+ self._data["output"] = None
31
+ self._data["readiness"] = None
32
+ self._data["sdk"] = None
33
+ self._data["sdkVersion"] = None
34
+ self._data["timeout"] = None
35
+ self._data["version"] = None
36
+ self._data["workingDirectory"] = None
37
+
38
+ @property
39
+ def api_version(self) -> str:
40
+ return self._data["apiVersion"]
41
+
42
+ @api_version.setter
43
+ def api_version(self, value: str):
44
+ self._data["apiVersion"] = value
45
+
46
+ @property
47
+ def command(self) -> str:
48
+ return self._data["command"]
49
+
50
+ @command.setter
51
+ def command(self, value: str):
52
+ self._data["command"] = value
53
+
54
+ @property
55
+ def environment(self) -> dict[str, str]:
56
+ return self._data["environment"]
57
+
58
+ @environment.setter
59
+ def environment(self, value: dict[str, str]):
60
+ self._data["environment"] = value
61
+
62
+ @property
63
+ def input(self) -> dict[str, str]: # noqa: A003
64
+ return self._data["input"]
65
+
66
+ @input.setter
67
+ def input(self, value: dict[str, str]): # noqa: A003
68
+ self._data["input"] = value
69
+
70
+ @property
71
+ def liveness(self) -> Any:
72
+ return self._data["liveness"]
73
+
74
+ @liveness.setter
75
+ def liveness(self, value: Any):
76
+ self._data["liveness"] = value
77
+
78
+ @property
79
+ def output(self) -> dict[str, str]:
80
+ return self._data["output"]
81
+
82
+ @output.setter
83
+ def output(self, value: dict[str, str]):
84
+ self._data["output"] = value
85
+
86
+ @property
87
+ def readiness(self) -> Any:
88
+ return self._data["readiness"]
89
+
90
+ @readiness.setter
91
+ def readiness(self, value: Any):
92
+ self._data["readiness"] = value
93
+
94
+ @property
95
+ def sdk(self) -> str:
96
+ return self._data["sdk"]
97
+
98
+ @sdk.setter
99
+ def sdk(self, value: str):
100
+ self._data["sdk"] = value
101
+
102
+ @property
103
+ def sdk_version(self) -> str:
104
+ return self._data["sdkVersion"]
105
+
106
+ @sdk_version.setter
107
+ def sdk_version(self, value: str):
108
+ self._data["sdkVersion"] = value
109
+
110
+ @property
111
+ def timeout(self) -> int:
112
+ return self._data["timeout"]
113
+
114
+ @timeout.setter
115
+ def timeout(self, value: int):
116
+ self._data["timeout"] = value
117
+
118
+ @property
119
+ def version(self) -> str:
120
+ return self._data["version"]
121
+
122
+ @version.setter
123
+ def version(self, value: str):
124
+ self._data["version"] = value
125
+
126
+ @property
127
+ def working_directory(self) -> str:
128
+ return self._data["workingDirectory"]
129
+
130
+ @working_directory.setter
131
+ def working_directory(self, value: str):
132
+ if isinstance(value, Path):
133
+ self._data["workingDirectory"] = str(value)
134
+ else:
135
+ self._data["workingDirectory"] = value
136
+
137
+ @property
138
+ def data(self) -> dict[str, Any]:
139
+ """Returns all values for serializing to JSON"""
140
+ return self._data
141
+
142
+
143
+ class PackageManifest:
144
+ def __init__(self):
145
+ self._data = {}
146
+ self._data["apiVersion"] = None
147
+ self._data["applicationRoot"] = None
148
+ self._data["modelRoot"] = None
149
+ self._data["models"] = None
150
+ self._data["resources"] = None
151
+ self._data["version"] = None
152
+ self._data["platformConfig"] = None
153
+
154
+ @property
155
+ def platform_config(self) -> str:
156
+ return self._data["platformConfig"]
157
+
158
+ @platform_config.setter
159
+ def platform_config(self, value: str):
160
+ self._data["platformConfig"] = value
161
+
162
+ @property
163
+ def api_version(self) -> str:
164
+ return self._data["apiVersion"]
165
+
166
+ @api_version.setter
167
+ def api_version(self, value: str):
168
+ self._data["apiVersion"] = value
169
+
170
+ @property
171
+ def application_root(self) -> str:
172
+ return self._data["applicationRoot"]
173
+
174
+ @application_root.setter
175
+ def application_root(self, value: str):
176
+ if isinstance(value, Path):
177
+ self._data["applicationRoot"] = str(value)
178
+ else:
179
+ self._data["applicationRoot"] = value
180
+
181
+ @property
182
+ def model_root(self) -> str:
183
+ return self._data["modelRoot"]
184
+
185
+ @model_root.setter
186
+ def model_root(self, value: str):
187
+ if isinstance(value, Path):
188
+ self._data["modelRoot"] = str(value)
189
+ else:
190
+ self._data["modelRoot"] = value
191
+
192
+ @property
193
+ def models(self) -> dict[str, str]:
194
+ return self._data["models"]
195
+
196
+ @models.setter
197
+ def models(self, value: dict[str, str]):
198
+ self._data["models"] = value
199
+
200
+ @property
201
+ def resources(self) -> Any:
202
+ return self._data["resources"]
203
+
204
+ @resources.setter
205
+ def resources(self, value: Any):
206
+ """Resources are copied from application configuration file directly."""
207
+ self._data["resources"] = value
208
+
209
+ @property
210
+ def version(self) -> str:
211
+ return self._data["version"]
212
+
213
+ @version.setter
214
+ def version(self, value: str):
215
+ self._data["version"] = value
216
+
217
+ @property
218
+ def data(self) -> dict[str, Any]:
219
+ """Returns all values for serializing to JSON"""
220
+ return self._data
@@ -0,0 +1,93 @@
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
+ from pathlib import Path
21
+ from typing import Optional
22
+
23
+ logger = logging.getLogger("packager")
24
+
25
+
26
+ class Models:
27
+ """
28
+ Builds model list from a given path where the path could be a model file, a directory that
29
+ contains a model or a directory with multiple models where each model contains within its own
30
+ subdirectory.
31
+ """
32
+
33
+ def build(self, models_path: Path) -> Optional[dict[str, Path]]:
34
+ """Checks if the given path is a file or a directory.
35
+
36
+ Args:
37
+ models_path (Path): A user given path that contains one or more models.
38
+ Returns:
39
+ Optional[Dict[str, Path]]: Returns None if no path is given. Otherwise, returns a
40
+ dictionary where the key is the name of the model and the value contains the path
41
+ to the model.
42
+ """
43
+ if models_path is not None:
44
+ logger.info(f"Scanning for models in {models_path}...")
45
+ models: dict[str, Path] = {}
46
+ if models_path.is_file():
47
+ self._configure_model_file(models_path, models)
48
+ elif models_path.is_dir():
49
+ self._configure_model_dir(models_path, models)
50
+
51
+ return models
52
+ else:
53
+ return None
54
+
55
+ def _configure_model_dir(self, models_path: Path, models: dict[str, Path]):
56
+ """
57
+ Iterate through the given directory to scan for models.
58
+ If files are found within the directory, we simply assume that all files within the given
59
+ directory contains a model and sets the name of the model to the name of the given
60
+ directory.
61
+
62
+ Any subdirectories found within the given directory are treated as a separate model and the
63
+ name of the subdirectory is set to be the name of the model.
64
+
65
+ Args:
66
+ models_path (Path): Path to the model file.
67
+ models (Dict[str, Path]): Where models are added to.
68
+ """
69
+ model_dirs = os.listdir(models_path)
70
+
71
+ for model_dir in model_dirs:
72
+ if os.path.isfile(models_path / model_dir):
73
+ model_name = models_path.resolve().stem
74
+ models[model_name] = models_path
75
+ logger.debug(f"Model {model_name}={models_path} added.")
76
+ elif os.path.isdir(models_path / model_dir):
77
+ model_path = models_path / model_dir
78
+ model_name = model_dir
79
+ models[model_name] = model_path
80
+ logger.debug(f"Model {model_name}={model_path} added.")
81
+
82
+ def _configure_model_file(self, models_path: Path, models: dict[str, Path]):
83
+ """
84
+ Adds a new model to 'models' object where the model name is the name of the given file,
85
+ and the value is the path to the given model file.
86
+
87
+ Args:
88
+ models_path (Path): Path to the model file.
89
+ models (Dict[str, Path]): Where the model is added to.
90
+ """
91
+ model_name = models_path.stem
92
+ models[model_name] = models_path
93
+ logger.debug(f"Model file {model_name}={models[model_name]} added.")
@@ -0,0 +1,189 @@
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 argparse
19
+ import logging
20
+ from argparse import ArgumentParser, _SubParsersAction
21
+
22
+ from packaging.version import Version
23
+
24
+ from ..common.argparse_types import (
25
+ valid_dir_path,
26
+ valid_existing_dir_path,
27
+ valid_existing_path,
28
+ valid_platform_config,
29
+ valid_platforms,
30
+ valid_sdk_type,
31
+ )
32
+ from ..common.constants import SDK
33
+
34
+ logger = logging.getLogger("packager")
35
+
36
+
37
+ def create_package_parser(
38
+ subparser: _SubParsersAction, command: str, parents: list[ArgumentParser]
39
+ ) -> ArgumentParser:
40
+ parser: ArgumentParser = subparser.add_parser(
41
+ command, formatter_class=argparse.HelpFormatter, parents=parents, add_help=False
42
+ )
43
+
44
+ parser.add_argument(
45
+ "application",
46
+ type=valid_existing_path,
47
+ help="Holoscan application path: Python application directory with __main__.py, "
48
+ "Python file, C++ source directory with CMakeLists.txt, or path to an executable.",
49
+ )
50
+ parser.add_argument(
51
+ "--config",
52
+ "-c",
53
+ required=True,
54
+ type=valid_existing_path,
55
+ help="Holoscan application configuration file (.yaml)",
56
+ )
57
+ parser.add_argument(
58
+ "--docs",
59
+ "-d",
60
+ type=valid_existing_dir_path,
61
+ help="path to a directory containing user documentation and/or licenses.",
62
+ )
63
+ parser.add_argument(
64
+ "--models",
65
+ "-m",
66
+ type=valid_existing_path,
67
+ help="path to a model file or a directory containing all models as subdirectories",
68
+ )
69
+ parser.add_argument(
70
+ "--platform",
71
+ type=valid_platforms,
72
+ required=True,
73
+ help="target platform(s) for the build output separated by comma. "
74
+ f"Valid values: {str.join(', ', SDK.PLATFORMS)}.",
75
+ )
76
+ parser.add_argument(
77
+ "--platform-config",
78
+ type=valid_platform_config,
79
+ help="target platform configuration for the build output. "
80
+ f"Valid values: {str.join(', ', SDK.PLATFORM_CONFIGS)}.",
81
+ )
82
+ parser.add_argument("--timeout", type=int, help="override default application timeout")
83
+ parser.add_argument("--version", type=Version, help="set the version of the application")
84
+
85
+ advanced_group = parser.add_argument_group(title="advanced build options")
86
+ advanced_group.add_argument(
87
+ "--base-image",
88
+ type=str,
89
+ help="base image name for the packaged application.",
90
+ )
91
+ advanced_group.add_argument(
92
+ "--build-image",
93
+ type=str,
94
+ help="container image name for building the C++ application.",
95
+ )
96
+ advanced_group.add_argument(
97
+ "--includes",
98
+ nargs="*",
99
+ default=[],
100
+ choices=["debug", "holoviz", "torch", "onnx"],
101
+ help="additional packages to include in the container.",
102
+ )
103
+ advanced_group.add_argument(
104
+ "--build-cache",
105
+ type=valid_dir_path,
106
+ default="~/.holoscan_build_cache",
107
+ help="path of the local directory where build cache gets stored.",
108
+ )
109
+ advanced_group.add_argument(
110
+ "--cmake-args",
111
+ type=str,
112
+ help='additional CMAKE build arguments. E.g. "-DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_ARG=VALUE"',
113
+ )
114
+ advanced_group.add_argument(
115
+ "--holoscan-sdk-file",
116
+ type=valid_existing_path,
117
+ help="path to the Holoscan SDK Debian or PyPI package. "
118
+ "If not specified, the packager downloads "
119
+ "the SDK file from the internet based on the SDK version.",
120
+ )
121
+ advanced_group.add_argument(
122
+ "--monai-deploy-sdk-file",
123
+ type=valid_existing_path,
124
+ help="path to the MONAI Deploy App SDK PyPI package. "
125
+ "If not specified, the packager downloads "
126
+ "the SDK file from the internet based on the SDK version.",
127
+ )
128
+ advanced_group.add_argument(
129
+ "--no-cache",
130
+ "-n",
131
+ dest="no_cache",
132
+ action="store_true",
133
+ help="do not use cache when building image",
134
+ )
135
+ advanced_group.add_argument(
136
+ "--sdk",
137
+ type=valid_sdk_type,
138
+ help="SDK for building the application: Holoscan or MONAI-Deploy. "
139
+ f"Valid values: {str.join(', ', SDK.SDKS)}.",
140
+ )
141
+ advanced_group.add_argument(
142
+ "--source",
143
+ type=str,
144
+ help="override Debian package, build container image and run container image from a "
145
+ "JSON formatted file or a secured web server (HTTPS).",
146
+ )
147
+ advanced_group.add_argument(
148
+ "--sdk-version",
149
+ type=Version,
150
+ help="set the version of the SDK that is used to build and package the application. "
151
+ "If not specified, the packager attempts to detect the installed version.",
152
+ )
153
+
154
+ output_group = parser.add_argument_group(title="output options")
155
+ output_group.add_argument(
156
+ "--output",
157
+ "-o",
158
+ type=valid_existing_dir_path,
159
+ help="output directory where result images will be written.",
160
+ )
161
+ output_group.add_argument(
162
+ "--tag",
163
+ "-t",
164
+ required=True,
165
+ type=str,
166
+ help="name of the image and a optional tag (format: name[:tag]).",
167
+ )
168
+
169
+ user_group = parser.add_argument_group(title="security options")
170
+ user_group.add_argument(
171
+ "--username",
172
+ type=str,
173
+ default="holoscan",
174
+ help="username to be created in the container execution context.",
175
+ )
176
+ user_group.add_argument(
177
+ "--uid",
178
+ type=str,
179
+ default=1000,
180
+ help="UID associated with the username. (default:1000)",
181
+ )
182
+ user_group.add_argument(
183
+ "--gid",
184
+ type=str,
185
+ default=1000,
186
+ help="GID associated with the username. (default:1000)",
187
+ )
188
+ parser.set_defaults(no_cache=False)
189
+ return parser
@@ -0,0 +1,122 @@
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 json
19
+ import logging
20
+ import os
21
+ import tempfile
22
+ from argparse import Namespace
23
+
24
+ from ..common.enum_types import ApplicationType
25
+ from ..common.utils import print_manifest_json
26
+ from .arguments import PackagingArguments
27
+ from .container_builder import CppAppBuilder, PythonAppBuilder
28
+ from .manifest_files import ApplicationManifest, PackageManifest
29
+ from .parameters import PlatformBuildResults
30
+
31
+ logger = logging.getLogger("packager")
32
+
33
+
34
+ def _build_image(args: PackagingArguments, temp_dir: str) -> list[PlatformBuildResults]:
35
+ """Creates dockerfile and builds HAP/MONAI Application Package (HAP/MAP) image
36
+ Args:
37
+ args (dict): Input arguments for Packager
38
+ temp_dir (str): Temporary directory to build MAP
39
+ """
40
+ if (
41
+ args.build_parameters.application_type == ApplicationType.PythonFile
42
+ or args.build_parameters.application_type == ApplicationType.PythonModule
43
+ ):
44
+ builder = PythonAppBuilder(args.build_parameters, temp_dir)
45
+ elif (
46
+ args.build_parameters.application_type == ApplicationType.Binary
47
+ or args.build_parameters.application_type == ApplicationType.CppCMake
48
+ ):
49
+ builder = CppAppBuilder(args.build_parameters, temp_dir)
50
+
51
+ results = [builder.build(platform) for platform in args.platforms]
52
+ return results
53
+
54
+
55
+ def _create_app_manifest(manifest: ApplicationManifest, temp_dir: str):
56
+ """Creates Application manifest .json file
57
+ Args:
58
+ manifest (Dict): Input arguments for Packager
59
+ temp_dir (str): Temporary directory to build MAP
60
+ """
61
+ map_folder_path = os.path.join(temp_dir, "map")
62
+ os.makedirs(map_folder_path, exist_ok=True)
63
+ with open(os.path.join(map_folder_path, "app.json"), "w") as app_manifest_file:
64
+ app_manifest_file.write(json.dumps(manifest.data))
65
+
66
+ print_manifest_json(manifest.data, "app.json")
67
+
68
+
69
+ def _create_package_manifest(manifest: PackageManifest, temp_dir: str):
70
+ """Creates package manifest .json file
71
+ Args:
72
+ manifest (Dict): Input arguments for Packager
73
+ temp_dir (str): Temporary directory to build MAP
74
+ """
75
+ map_folder_path = os.path.join(temp_dir, "map")
76
+ os.makedirs(map_folder_path, exist_ok=True)
77
+ with open(os.path.join(temp_dir, "map", "pkg.json"), "w") as package_manifest_file:
78
+ package_manifest_file.write(json.dumps(manifest.data))
79
+
80
+ print_manifest_json(manifest.data, "pkg.json")
81
+
82
+
83
+ def _package_application(args: Namespace):
84
+ """Driver function for invoking all functions for creating and
85
+ building the Holoscan Application package image
86
+ Args:
87
+ args (Namespace): Input arguments for Packager from CLI
88
+ """
89
+ # Initialize arguments for package
90
+ with tempfile.TemporaryDirectory(prefix="holoscan_tmp", dir=tempfile.gettempdir()) as temp_dir:
91
+ packaging_args = PackagingArguments(args, temp_dir)
92
+
93
+ # Create Manifest Files
94
+ _create_app_manifest(packaging_args.application_manifest, temp_dir)
95
+ _create_package_manifest(packaging_args.package_manifest, temp_dir)
96
+
97
+ results = _build_image(packaging_args, temp_dir)
98
+
99
+ logger.info("Build Summary:")
100
+ for result in results:
101
+ if result.succeeded:
102
+ print(
103
+ f"""\nPlatform: {result.parameters.platform.value}/{result.parameters.platform_config.value}
104
+ Status: Succeeded
105
+ Docker Tag: {result.docker_tag if result.docker_tag is not None else "N/A"}
106
+ Tarball: {result.tarball_filenaem}""" # noqa: E501
107
+ )
108
+ else:
109
+ print(
110
+ f"""\nPlatform: {result.parameters.platform.value}/{result.parameters.platform_config.value}
111
+ Status: Failure
112
+ Error: {result.error}
113
+ """ # noqa: E501
114
+ )
115
+
116
+
117
+ def execute_package_command(args: Namespace):
118
+ try:
119
+ _package_application(args)
120
+ except Exception as e:
121
+ logger.debug(e, exc_info=True)
122
+ logger.error(f"Error packaging application:\n\n{str(e)}")