peak-sdk 1.0.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.
- peak/__init__.py +36 -0
- peak/_version.py +21 -0
- peak/auth.py +22 -0
- peak/base_client.py +52 -0
- peak/cli/__init_.py +20 -0
- peak/cli/args.py +84 -0
- peak/cli/cli.py +56 -0
- peak/cli/helpers.py +187 -0
- peak/cli/press/__init__.py +21 -0
- peak/cli/press/apps/__init__.py +40 -0
- peak/cli/press/apps/deployments.py +238 -0
- peak/cli/press/apps/specs.py +387 -0
- peak/cli/press/blocks/__init__.py +40 -0
- peak/cli/press/blocks/deployments.py +240 -0
- peak/cli/press/blocks/specs.py +492 -0
- peak/cli/press/deployments.py +78 -0
- peak/cli/press/specs.py +131 -0
- peak/cli/resources/__init__.py +21 -0
- peak/cli/resources/artifacts.py +310 -0
- peak/cli/resources/images.py +886 -0
- peak/cli/resources/webapps.py +356 -0
- peak/cli/resources/workflows.py +703 -0
- peak/cli/ruff.toml +11 -0
- peak/cli/version.py +49 -0
- peak/compression.py +162 -0
- peak/config.py +24 -0
- peak/constants.py +105 -0
- peak/exceptions.py +217 -0
- peak/handler.py +358 -0
- peak/helpers.py +184 -0
- peak/logger.py +48 -0
- peak/press/__init__.py +28 -0
- peak/press/apps.py +669 -0
- peak/press/blocks.py +707 -0
- peak/press/deployments.py +145 -0
- peak/press/specs.py +260 -0
- peak/py.typed +0 -0
- peak/resources/__init__.py +28 -0
- peak/resources/artifacts.py +343 -0
- peak/resources/images.py +675 -0
- peak/resources/webapps.py +278 -0
- peak/resources/workflows.py +625 -0
- peak/session.py +259 -0
- peak/telemetry.py +201 -0
- peak/template.py +231 -0
- peak/validators.py +48 -0
- peak_sdk-1.0.0.dist-info/LICENSE +201 -0
- peak_sdk-1.0.0.dist-info/METADATA +199 -0
- peak_sdk-1.0.0.dist-info/RECORD +51 -0
- peak_sdk-1.0.0.dist-info/WHEEL +4 -0
- peak_sdk-1.0.0.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,886 @@
|
|
1
|
+
#
|
2
|
+
# # Copyright © 2023 Peak AI Limited. or its affiliates. All Rights Reserved.
|
3
|
+
# #
|
4
|
+
# # Licensed under the Apache License, Version 2.0 (the "License"). You
|
5
|
+
# # may not use this file except in compliance with the License. A copy of
|
6
|
+
# # the License is located at:
|
7
|
+
# #
|
8
|
+
# # https://github.com/PeakBI/peak-sdk/blob/main/LICENSE
|
9
|
+
# #
|
10
|
+
# # or in the "license" file accompanying this file. This file is
|
11
|
+
# # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
12
|
+
# # ANY KIND, either express or implied. See the License for the specific
|
13
|
+
# # language governing permissions and limitations under the License.
|
14
|
+
# #
|
15
|
+
# # This file is part of the peak-sdk.
|
16
|
+
# # see (https://github.com/PeakBI/peak-sdk)
|
17
|
+
# #
|
18
|
+
# # You should have received a copy of the APACHE LICENSE, VERSION 2.0
|
19
|
+
# # along with this program. If not, see <https://apache.org/licenses/LICENSE-2.0>
|
20
|
+
#
|
21
|
+
"""Peak Images service commands."""
|
22
|
+
from typing import Any, Dict, List, Optional
|
23
|
+
|
24
|
+
import typer
|
25
|
+
from peak.cli import args, helpers
|
26
|
+
from peak.helpers import combine_dictionaries, map_user_options, parse_list_of_strings, variables_to_dict
|
27
|
+
from peak.resources.images import Image
|
28
|
+
from rich.console import Console
|
29
|
+
from typing_extensions import Annotated
|
30
|
+
|
31
|
+
app = typer.Typer(
|
32
|
+
help="Create Docker images that Workflows, Workspaces, and other services use.",
|
33
|
+
short_help="Create and manage Images.",
|
34
|
+
)
|
35
|
+
console = Console()
|
36
|
+
|
37
|
+
_IMAGE_ID = typer.Argument(..., help="ID of the image to be used in this operation.")
|
38
|
+
|
39
|
+
_COUNT = typer.Option(None, help="Number of builds required.")
|
40
|
+
|
41
|
+
_BUILD_STATUS = typer.Option(None, help="List of build status to filter image builds.")
|
42
|
+
|
43
|
+
_VERSIONS = typer.Option(None, help="List of version ids to filter image builds.")
|
44
|
+
|
45
|
+
_IMAGE_LIST_NAME = typer.Option(None, help="Image Name or version to search for.")
|
46
|
+
|
47
|
+
_IMAGE_LIST_STATUS = typer.Option(
|
48
|
+
None,
|
49
|
+
help="List of status of the latest version to filter the images by.",
|
50
|
+
)
|
51
|
+
|
52
|
+
_IMAGE_LIST_SCOPE = typer.Option(None, help="List of type of image to filter the images by.")
|
53
|
+
|
54
|
+
_IMAGE_LIST_BUILD_STATUS = typer.Option(
|
55
|
+
None,
|
56
|
+
help="List of build status of the latest version to filter the images by.",
|
57
|
+
)
|
58
|
+
|
59
|
+
_IMAGE_LIST_TAGS = typer.Option(None, help="List of tags on the latest version to filter the images by.")
|
60
|
+
|
61
|
+
_VERSION_LIST_VERSION = typer.Option(None, help="Version to search for.")
|
62
|
+
|
63
|
+
_VERSION_LIST_STATUS = typer.Option(None, help="List of statuses to filter the versions by.")
|
64
|
+
|
65
|
+
_VERSION_LIST_BUILD_STATUS = typer.Option(None, help="List of build statuses to filter the versions by.")
|
66
|
+
|
67
|
+
_VERSION_LIST_TAGS = typer.Option(None, help="List of tags to filter the versions by.")
|
68
|
+
_NAME = typer.Option(None, help="Name of the image.")
|
69
|
+
|
70
|
+
_VERSION = typer.Option(None, help="A valid semantic image version.")
|
71
|
+
|
72
|
+
_TYPE = typer.Option(None, help="Type of the image.")
|
73
|
+
|
74
|
+
_DESCRIPTION = typer.Option(None, help="Description of the image.")
|
75
|
+
|
76
|
+
_ARTIFACT_PATH = typer.Option(None, help="Path to the artifact.")
|
77
|
+
|
78
|
+
_ARTIFACT_IGNORE_FILES = typer.Option(None, help="Ignore files to use when creating artifact.")
|
79
|
+
|
80
|
+
_BUILD_DETAILS = typer.Option(None, help="Build details of the image. To be passed in stringified json format.")
|
81
|
+
|
82
|
+
_SOURCE = typer.Option(None, help="The source via which the image is to be created.")
|
83
|
+
|
84
|
+
_DOCKERFILE = typer.Option(None, help="The dockerfile to be used to create the image.")
|
85
|
+
|
86
|
+
_DOCKERFILE_PATH = typer.Option(None, help="Path to the dockerfile.")
|
87
|
+
|
88
|
+
_CONTEXT = typer.Option(None, help="The path within the artifact to the code to be executed by the Dockerfile.")
|
89
|
+
|
90
|
+
_REPOSITORY = typer.Option(None, help="When source is github, the repository where the Dockerfile content is stored.")
|
91
|
+
|
92
|
+
_BRANCH = typer.Option(None, help="When source is github, the Branch that contains the Dockerfile.")
|
93
|
+
|
94
|
+
_TOKEN = typer.Option(None, help="When source is github, the token to be used to clone the required repository.")
|
95
|
+
|
96
|
+
_USE_CACHE = typer.Option(None, help="Whether to enable image caching to reduce build time.")
|
97
|
+
|
98
|
+
_BUILD_ARGUMENTS = typer.Option(None, help="List of build arguments in the format arg1=value1.")
|
99
|
+
|
100
|
+
_SECRETS = typer.Option(None, help="List of secret names to be passed as build arguments.")
|
101
|
+
|
102
|
+
MAPPING = {
|
103
|
+
"source": "buildDetails",
|
104
|
+
"dockerfile": "buildDetails",
|
105
|
+
"dockerfilePath": "buildDetails",
|
106
|
+
"context": "buildDetails",
|
107
|
+
"repository": "buildDetails",
|
108
|
+
"branch": "buildDetails",
|
109
|
+
"token": "buildDetails",
|
110
|
+
"useCache": "buildDetails",
|
111
|
+
"buildArguments": "buildDetails",
|
112
|
+
"secrets": "buildDetails", # pragma: allowlist secret
|
113
|
+
}
|
114
|
+
|
115
|
+
|
116
|
+
@app.command(short_help="Create a new image.")
|
117
|
+
def create(
|
118
|
+
ctx: typer.Context,
|
119
|
+
file: Annotated[
|
120
|
+
Optional[str],
|
121
|
+
typer.Argument(
|
122
|
+
...,
|
123
|
+
help="Path to the file that defines the body for this operation, supports both `yaml` file or a `jinja` template.",
|
124
|
+
),
|
125
|
+
] = None,
|
126
|
+
params_file: str = args.TEMPLATE_PARAMS_FILE,
|
127
|
+
params: List[str] = args.TEMPLATE_PARAMS,
|
128
|
+
name: Optional[str] = _NAME,
|
129
|
+
version: Optional[str] = _VERSION,
|
130
|
+
type: Optional[str] = _TYPE, # noqa: A002
|
131
|
+
description: Optional[str] = _DESCRIPTION,
|
132
|
+
artifact_path: Optional[str] = _ARTIFACT_PATH,
|
133
|
+
artifact_ignore_files: Optional[List[str]] = _ARTIFACT_IGNORE_FILES,
|
134
|
+
build_details: Optional[str] = _BUILD_DETAILS,
|
135
|
+
source: Optional[str] = _SOURCE,
|
136
|
+
dockerfile: Optional[str] = _DOCKERFILE,
|
137
|
+
dockerfile_path: Optional[str] = _DOCKERFILE_PATH,
|
138
|
+
context: Optional[str] = _CONTEXT,
|
139
|
+
repository: Optional[str] = _REPOSITORY,
|
140
|
+
branch: Optional[str] = _BRANCH,
|
141
|
+
token: Optional[str] = _TOKEN,
|
142
|
+
use_cache: Optional[bool] = _USE_CACHE,
|
143
|
+
build_arguments: Optional[List[str]] = _BUILD_ARGUMENTS,
|
144
|
+
secrets: Optional[List[str]] = _SECRETS,
|
145
|
+
) -> None:
|
146
|
+
"""***Create*** a new image. This also adds the first version in the image.
|
147
|
+
|
148
|
+
\b
|
149
|
+
🧩 ***Input file schema(yaml):***<br/>
|
150
|
+
```yaml
|
151
|
+
body (map):
|
152
|
+
name (str): Name of the image.
|
153
|
+
version (str | required: false): A valid semantic image version. If not provided, the version will be set to 0.0.1.
|
154
|
+
type (str): Type of the image.
|
155
|
+
description (str | required: false): Description of the image.
|
156
|
+
buildDetails (map):
|
157
|
+
source (str): The source via which the image is to be created.
|
158
|
+
useCache (boolean | required: false): Whether to enable image caching to reduce build time, is enabled by default.
|
159
|
+
buildArguments (list(map) | required: false):
|
160
|
+
name (str): Name of the build argument.
|
161
|
+
value (str): Value of the build argument.
|
162
|
+
secrets (list(str)) | required: false): List of secret names to be passed as build arguments.
|
163
|
+
context (str | required: false): The path within the artifact to the code to be executed by the Dockerfile.
|
164
|
+
dockerfilePath (str | required: false): Path to the Dockerfile inside artifact or the repository.
|
165
|
+
repository (str | required: false): When source is github, the repository where the Dockerfile content is stored.
|
166
|
+
branch (str | required: false): When source is github, the Branch that contains the Dockerfile.
|
167
|
+
token (str | required: false): When source is github, the token to be used to clone the required repository.
|
168
|
+
dockerfile (str | required: false): When source is dockerfile, this represents the content of Dockerfile to build the image from.
|
169
|
+
artifact (map | required: false):
|
170
|
+
path (str): Path to the artifact.
|
171
|
+
ignore_files (list(str) | required: false) : Ignore files to use when creating artifact.
|
172
|
+
```
|
173
|
+
|
174
|
+
\b
|
175
|
+
📝 ***Example usage:***
|
176
|
+
```bash
|
177
|
+
peak images create '/path/to/image.yaml' --params-file '/path/to/values.yaml'
|
178
|
+
```
|
179
|
+
|
180
|
+
We can also provide the required parameters from the command line or combine the YAML template and command line arguments in which case the command line arguments will take precedence.
|
181
|
+
|
182
|
+
\b
|
183
|
+
📝 ***Example usage without yaml:***
|
184
|
+
```bash
|
185
|
+
peak images create --name <name> --type <type> --description <description> --version <version> --source <source> --dockerfile <dockerfile> --secrets <secret_1> --secrets <secret_2>
|
186
|
+
```
|
187
|
+
|
188
|
+
\b
|
189
|
+
🆗 ***Response:***
|
190
|
+
```json
|
191
|
+
{
|
192
|
+
"buildId": "build-image-mock:2198c71e-22c5-aca3eac3a55e",
|
193
|
+
"imageId": 9999,
|
194
|
+
"versionId": 1,
|
195
|
+
}
|
196
|
+
```
|
197
|
+
|
198
|
+
🔗 [**API Documentation**](https://service.peak.ai/image-management/api-docs/index.htm#/images/post_api_v2_images)
|
199
|
+
"""
|
200
|
+
image_client: Image = ctx.obj["client"]
|
201
|
+
|
202
|
+
user_options: Dict[str, Any] = variables_to_dict(
|
203
|
+
name,
|
204
|
+
description,
|
205
|
+
type,
|
206
|
+
version,
|
207
|
+
build_details,
|
208
|
+
source,
|
209
|
+
dockerfile,
|
210
|
+
repository,
|
211
|
+
branch,
|
212
|
+
token,
|
213
|
+
dockerfile_path,
|
214
|
+
context,
|
215
|
+
use_cache,
|
216
|
+
build_arguments,
|
217
|
+
secrets,
|
218
|
+
)
|
219
|
+
|
220
|
+
user_options = map_user_options(user_options, MAPPING, dict_type_keys=["buildDetails"])
|
221
|
+
|
222
|
+
body: Dict[str, Any] = {}
|
223
|
+
if file:
|
224
|
+
body = helpers.template_handler(file=file, params_file=params_file, params=params)
|
225
|
+
body = helpers.remove_unknown_args(body, image_client.create_image)
|
226
|
+
|
227
|
+
updated_body = combine_dictionaries(body.get("body") or {}, user_options)
|
228
|
+
artifact = helpers.get_updated_artifacts(body, artifact_path, artifact_ignore_files)
|
229
|
+
|
230
|
+
if build_arguments:
|
231
|
+
updated_body["buildDetails"]["buildArguments"] = helpers.parse_build_arguments(build_arguments)
|
232
|
+
|
233
|
+
if secrets:
|
234
|
+
updated_body["buildDetails"]["secrets"] = parse_list_of_strings(secrets)
|
235
|
+
|
236
|
+
response: Dict[str, Any] = image_client.create_image(body=updated_body, artifact=artifact) # type: ignore # noqa: PGH003
|
237
|
+
console.print(response)
|
238
|
+
|
239
|
+
|
240
|
+
@app.command(short_help="Create a new image version.")
|
241
|
+
def create_version(
|
242
|
+
ctx: typer.Context,
|
243
|
+
image_id: int = _IMAGE_ID,
|
244
|
+
file: Annotated[
|
245
|
+
Optional[str],
|
246
|
+
typer.Argument(
|
247
|
+
...,
|
248
|
+
help="Path to the file that defines the body for this operation, supports both `yaml` file or a `jinja` template.",
|
249
|
+
),
|
250
|
+
] = None,
|
251
|
+
params_file: str = args.TEMPLATE_PARAMS_FILE,
|
252
|
+
params: List[str] = args.TEMPLATE_PARAMS,
|
253
|
+
version: Optional[str] = _VERSION,
|
254
|
+
description: Optional[str] = _DESCRIPTION,
|
255
|
+
artifact_path: Optional[str] = _ARTIFACT_PATH,
|
256
|
+
artifact_ignore_files: Optional[List[str]] = _ARTIFACT_IGNORE_FILES,
|
257
|
+
build_details: Optional[str] = _BUILD_DETAILS,
|
258
|
+
source: Optional[str] = _SOURCE,
|
259
|
+
dockerfile: Optional[str] = _DOCKERFILE,
|
260
|
+
dockerfile_path: Optional[str] = _DOCKERFILE_PATH,
|
261
|
+
context: Optional[str] = _CONTEXT,
|
262
|
+
repository: Optional[str] = _REPOSITORY,
|
263
|
+
branch: Optional[str] = _BRANCH,
|
264
|
+
token: Optional[str] = _TOKEN,
|
265
|
+
use_cache: Optional[bool] = _USE_CACHE,
|
266
|
+
build_arguments: Optional[List[str]] = _BUILD_ARGUMENTS,
|
267
|
+
secrets: Optional[List[str]] = _SECRETS,
|
268
|
+
) -> None:
|
269
|
+
"""***Create*** a new version in an existing image.
|
270
|
+
|
271
|
+
\b
|
272
|
+
🧩 ***Input file schema(yaml):***<br/>
|
273
|
+
```yaml
|
274
|
+
body (map):
|
275
|
+
version (str | required: false): A valid semantic image version. If not provided, the next patch version of the latest version will be used.
|
276
|
+
description (str | required: false): Description of the image version.
|
277
|
+
buildDetails (map):
|
278
|
+
source (str): Source via which image version can be created.
|
279
|
+
useCache (boolean | required: false): Whether to enable image caching to reduce build time, is enabled by default.
|
280
|
+
buildArguments (list(map) | required: false):
|
281
|
+
name (str): Name of the build argument.
|
282
|
+
value (str): Value of the build argument.
|
283
|
+
secrets (list(str) | required: false): List of secret names to be passed as build arguments.
|
284
|
+
context (str | required: false): The path within the artifact to code to be executed by the Dockerfile.
|
285
|
+
dockerfilePath (str | required: false): Path to the Dockerfile inside artifact or repository.
|
286
|
+
repository (str | required: false): When source is github, the repository where the Dockerfile content is stored.
|
287
|
+
branch (str | required: false): When source is github, the Branch that contains the Dockerfile.
|
288
|
+
token (str | required: false): When source is github, the token to be used to clone the required repository.
|
289
|
+
dockerfile (str | required: false): When source is dockerfile, this represents the content of Dockerfile to build the image from.
|
290
|
+
autodeployResources (list(map) | required: false): A list of resources that should be redeployed when the build completes.
|
291
|
+
entityId (str): The id of the resource to be redeployed.
|
292
|
+
entityType (str): The type of the resource to be redeployed. Allowed values are 'workflow', 'workspace', 'api' and 'webapp'.
|
293
|
+
artifact (map | required: false):
|
294
|
+
path (str): Path to the artifact.
|
295
|
+
ignore_files (list(str) | required: false) : Ignore files to use when creating artifact.
|
296
|
+
```
|
297
|
+
|
298
|
+
\b
|
299
|
+
📝 ***Example usage:***
|
300
|
+
```bash
|
301
|
+
peak images create-version <imageId> '/path/to/file.yaml' -v '/path/to/parmas.yaml'
|
302
|
+
```
|
303
|
+
|
304
|
+
We can also provide the required parameters from the command line or combine the YAML template and command line arguments in which case the command line arguments will take precedence.
|
305
|
+
|
306
|
+
\b
|
307
|
+
📝 ***Example usage without yaml:***
|
308
|
+
```bash
|
309
|
+
peak images create-version <image_id> --description <description> --version <version> --source <source> --dockerfile <dockerfile> --secrets <secret_1>,<secret_2>
|
310
|
+
```
|
311
|
+
|
312
|
+
\b
|
313
|
+
🆗 ***Response:***
|
314
|
+
```json
|
315
|
+
{
|
316
|
+
"buildId": "build-image-mock:2198c71e-22c5-aca3eac3a55e",
|
317
|
+
"versionId": 101,
|
318
|
+
"autodeploymentId": "0a12abcd-11ab-22d2-123a-a1234b333abc"
|
319
|
+
}
|
320
|
+
```
|
321
|
+
|
322
|
+
🔗 [**API Documentation**](https://service.peak.ai/image-management/api-docs/index.htm#/versions/post_api_v2_images__imageId__versions)
|
323
|
+
"""
|
324
|
+
image_client: Image = ctx.obj["client"]
|
325
|
+
|
326
|
+
user_options: Dict[str, Any] = variables_to_dict(
|
327
|
+
description,
|
328
|
+
version,
|
329
|
+
build_details,
|
330
|
+
source,
|
331
|
+
dockerfile,
|
332
|
+
repository,
|
333
|
+
branch,
|
334
|
+
token,
|
335
|
+
dockerfile_path,
|
336
|
+
context,
|
337
|
+
use_cache,
|
338
|
+
build_arguments,
|
339
|
+
secrets,
|
340
|
+
)
|
341
|
+
|
342
|
+
user_options = map_user_options(user_options, MAPPING, dict_type_keys=["buildDetails"])
|
343
|
+
|
344
|
+
body: Dict[str, Any] = {}
|
345
|
+
if file:
|
346
|
+
body = helpers.template_handler(file=file, params_file=params_file, params=params)
|
347
|
+
body = helpers.remove_unknown_args(body, image_client.create_version)
|
348
|
+
|
349
|
+
updated_body = combine_dictionaries(
|
350
|
+
body.get("body") or {},
|
351
|
+
user_options,
|
352
|
+
)
|
353
|
+
artifact = helpers.get_updated_artifacts(body, artifact_path, artifact_ignore_files)
|
354
|
+
|
355
|
+
if build_arguments:
|
356
|
+
updated_body["buildDetails"]["buildArguments"] = helpers.parse_build_arguments(build_arguments)
|
357
|
+
|
358
|
+
if secrets:
|
359
|
+
updated_body["buildDetails"]["secrets"] = parse_list_of_strings(secrets)
|
360
|
+
|
361
|
+
response: Dict[str, Any] = image_client.create_version(image_id=image_id, body=updated_body, artifact=artifact) # type: ignore # noqa: PGH003
|
362
|
+
console.print(response)
|
363
|
+
|
364
|
+
|
365
|
+
@app.command(short_help="Create a new image/version or Update and existing version.")
|
366
|
+
def create_or_update(
|
367
|
+
ctx: typer.Context,
|
368
|
+
file: Annotated[
|
369
|
+
Optional[str],
|
370
|
+
typer.Argument(
|
371
|
+
...,
|
372
|
+
help="Path to the file that defines the body for this operation, supports both `yaml` file or a `jinja` template.",
|
373
|
+
),
|
374
|
+
] = None,
|
375
|
+
params_file: str = args.TEMPLATE_PARAMS_FILE,
|
376
|
+
params: List[str] = args.TEMPLATE_PARAMS,
|
377
|
+
name: Optional[str] = _NAME,
|
378
|
+
version: Optional[str] = _VERSION,
|
379
|
+
type: Optional[str] = _TYPE, # noqa: A002
|
380
|
+
description: Optional[str] = _DESCRIPTION,
|
381
|
+
artifact_path: Optional[str] = _ARTIFACT_PATH,
|
382
|
+
artifact_ignore_files: Optional[List[str]] = _ARTIFACT_IGNORE_FILES,
|
383
|
+
build_details: Optional[str] = _BUILD_DETAILS,
|
384
|
+
source: Optional[str] = _SOURCE,
|
385
|
+
dockerfile: Optional[str] = _DOCKERFILE,
|
386
|
+
dockerfile_path: Optional[str] = _DOCKERFILE_PATH,
|
387
|
+
context: Optional[str] = _CONTEXT,
|
388
|
+
repository: Optional[str] = _REPOSITORY,
|
389
|
+
branch: Optional[str] = _BRANCH,
|
390
|
+
token: Optional[str] = _TOKEN,
|
391
|
+
use_cache: Optional[bool] = _USE_CACHE,
|
392
|
+
build_arguments: Optional[List[str]] = _BUILD_ARGUMENTS,
|
393
|
+
secrets: Optional[List[str]] = _SECRETS,
|
394
|
+
) -> None:
|
395
|
+
"""***Create*** a new image if it doesn't exist. This also adds the first version in the image. In case image exists, it will add a new version to the image. ***Update*** a version if exists.
|
396
|
+
|
397
|
+
\b
|
398
|
+
🧩 ***Input file schema(yaml):***<br/>
|
399
|
+
```yaml
|
400
|
+
body (map):
|
401
|
+
name (str): Name of the image.
|
402
|
+
version (str | required: false): A valid semantic image version. If not provided, the next patch version of the latest version will be used.
|
403
|
+
type (str): Type of the image.
|
404
|
+
description (str | required: false): Description of the image.
|
405
|
+
buildDetails (map):
|
406
|
+
source (str): The source via which the image is to be created.
|
407
|
+
useCache (boolean | required: false): Whether to enable image caching to reduce build time, is enabled by default.
|
408
|
+
buildArguments (list(map) | required: false):
|
409
|
+
name (str): Name of the build argument.
|
410
|
+
value (str): Value of the build argument.
|
411
|
+
secrets (list(str)) | required: false): List of secret names to be passed as build arguments.
|
412
|
+
context (str | required: false): The path within the artifact to the code to be executed by the Dockerfile.
|
413
|
+
dockerfilePath (str | required: false): Path to the Dockerfile inside artifact or the repository.
|
414
|
+
repository (str | required: false): When source is github, the repository where the Dockerfile content is stored.
|
415
|
+
branch (str | required: false): When source is github, the Branch that contains the Dockerfile.
|
416
|
+
token (str | required: false): When source is github, the token to be used to clone the required repository.
|
417
|
+
dockerfile (str | required: false): When source is dockerfile, this represents the content of Dockerfile to build the image from.
|
418
|
+
artifact (map | required: false):
|
419
|
+
path (str): Path to the artifact.
|
420
|
+
ignore_files (list(str) | required: false) : Ignore files to use when creating artifact.
|
421
|
+
```
|
422
|
+
|
423
|
+
\b
|
424
|
+
📝 ***Example usage:***
|
425
|
+
```bash
|
426
|
+
peak images create-or-update '/path/to/image.yaml' --params-file '/path/to/values.yaml'
|
427
|
+
```
|
428
|
+
|
429
|
+
\b
|
430
|
+
We can also provide the required parameters from the command line or combine the YAML template and command line arguments in which case the command line arguments will take precedence.
|
431
|
+
|
432
|
+
\b
|
433
|
+
📝 ***Example usage without yaml:***
|
434
|
+
```bash
|
435
|
+
peak images create-or-update --name <name> --type <type> --description <description> --version <version> --source <source> --dockerfile <dockerfile> --secrets <secret_1> --secrets <secret_2>
|
436
|
+
```
|
437
|
+
|
438
|
+
\b
|
439
|
+
🆗 ***Response:***
|
440
|
+
```json
|
441
|
+
{
|
442
|
+
"buildId": "build-image-mock:2198c71e-22c5-aca3eac3a55e",
|
443
|
+
"imageId": 9999,
|
444
|
+
"versionId": 1,
|
445
|
+
}
|
446
|
+
```
|
447
|
+
|
448
|
+
🔗 [**API Documentation**](https://service.peak.ai/image-management/api-docs/index.htm#/images/post_api_v2_images)
|
449
|
+
"""
|
450
|
+
image_client: Image = ctx.obj["client"]
|
451
|
+
|
452
|
+
user_options: Dict[str, Any] = variables_to_dict(
|
453
|
+
name,
|
454
|
+
description,
|
455
|
+
type,
|
456
|
+
version,
|
457
|
+
build_details,
|
458
|
+
source,
|
459
|
+
dockerfile,
|
460
|
+
repository,
|
461
|
+
branch,
|
462
|
+
token,
|
463
|
+
dockerfile_path,
|
464
|
+
context,
|
465
|
+
use_cache,
|
466
|
+
build_arguments,
|
467
|
+
secrets,
|
468
|
+
)
|
469
|
+
|
470
|
+
user_options = map_user_options(user_options, MAPPING, dict_type_keys=["buildDetails"])
|
471
|
+
|
472
|
+
body: Dict[str, Any] = {}
|
473
|
+
if file:
|
474
|
+
body = helpers.template_handler(file=file, params_file=params_file, params=params)
|
475
|
+
body = helpers.remove_unknown_args(body, image_client.create_or_update_image_version)
|
476
|
+
|
477
|
+
updated_body = combine_dictionaries(body.get("body") or {}, user_options)
|
478
|
+
artifact = helpers.get_updated_artifacts(body, artifact_path, artifact_ignore_files)
|
479
|
+
|
480
|
+
if build_arguments:
|
481
|
+
updated_body["buildDetails"]["buildArguments"] = helpers.parse_build_arguments(build_arguments)
|
482
|
+
|
483
|
+
if secrets:
|
484
|
+
updated_body["buildDetails"]["secrets"] = parse_list_of_strings(secrets)
|
485
|
+
|
486
|
+
response: Dict[str, Any] = image_client.create_or_update_image_version(body=updated_body, artifact=artifact) # type: ignore # noqa: PGH003
|
487
|
+
console.print(response)
|
488
|
+
|
489
|
+
|
490
|
+
@app.command("list", short_help="List images.")
|
491
|
+
def list_images(
|
492
|
+
ctx: typer.Context,
|
493
|
+
page_size: Optional[int] = args.PAGE_SIZE,
|
494
|
+
page_number: Optional[int] = args.PAGE_NUMBER,
|
495
|
+
name: Optional[str] = _IMAGE_LIST_NAME,
|
496
|
+
status: Optional[List[str]] = _IMAGE_LIST_STATUS,
|
497
|
+
scope: Optional[List[str]] = _IMAGE_LIST_SCOPE,
|
498
|
+
last_build_status: Optional[List[str]] = _IMAGE_LIST_BUILD_STATUS,
|
499
|
+
tags: Optional[List[str]] = _IMAGE_LIST_TAGS,
|
500
|
+
) -> None:
|
501
|
+
"""***List*** all images that exists in the tenant along with details about their latest version.
|
502
|
+
|
503
|
+
\b
|
504
|
+
📝 ***Example usage:***<br/>
|
505
|
+
```bash
|
506
|
+
peak images list --page-size 10 --page-number 1 --name "test" --status "ready,in-use" --scope "custom" --last-build-status "building" --tags "tag1"
|
507
|
+
```
|
508
|
+
|
509
|
+
\b
|
510
|
+
🆗 ***Response:***
|
511
|
+
```
|
512
|
+
{
|
513
|
+
"imageCount": 1,
|
514
|
+
"images": [...],
|
515
|
+
"pageCount": 1,
|
516
|
+
"pageNumber": 1,
|
517
|
+
"pageSize": 25
|
518
|
+
}
|
519
|
+
```
|
520
|
+
|
521
|
+
🔗 [**API Documentation**](https://service.peak.ai/image-management/api-docs/index.htm#/images/get_api_v2_images)
|
522
|
+
"""
|
523
|
+
image_client: Image = ctx.obj["client"]
|
524
|
+
|
525
|
+
response = image_client.list_images(
|
526
|
+
page_size=page_size,
|
527
|
+
page_number=page_number,
|
528
|
+
return_iterator=False,
|
529
|
+
name=name,
|
530
|
+
status=parse_list_of_strings(status),
|
531
|
+
scope=parse_list_of_strings(scope),
|
532
|
+
last_build_status=parse_list_of_strings(last_build_status),
|
533
|
+
tags=parse_list_of_strings(tags),
|
534
|
+
)
|
535
|
+
console.print(response)
|
536
|
+
|
537
|
+
|
538
|
+
@app.command("list-versions", short_help="List image versions.")
|
539
|
+
def list_image_versions(
|
540
|
+
ctx: typer.Context,
|
541
|
+
image_id: int = _IMAGE_ID,
|
542
|
+
page_size: Optional[int] = args.PAGE_SIZE,
|
543
|
+
page_number: Optional[int] = args.PAGE_NUMBER,
|
544
|
+
version: Optional[str] = _VERSION_LIST_VERSION,
|
545
|
+
status: Optional[List[str]] = _VERSION_LIST_STATUS,
|
546
|
+
last_build_status: Optional[List[str]] = _VERSION_LIST_BUILD_STATUS,
|
547
|
+
tags: Optional[List[str]] = _VERSION_LIST_TAGS,
|
548
|
+
) -> None:
|
549
|
+
"""***List*** all versions for an image.
|
550
|
+
|
551
|
+
\b
|
552
|
+
📝 ***Example usage:***<br/>
|
553
|
+
```bash
|
554
|
+
peak images list-versions 9999 --page-size 10 --page-number 1 --version "0.0.1" --status "ready,in-use" --last-build-status "failed" --tags "tag1,tag2"
|
555
|
+
```
|
556
|
+
|
557
|
+
\b
|
558
|
+
🆗 ***Response:***
|
559
|
+
```
|
560
|
+
{
|
561
|
+
"versionCount": 1,
|
562
|
+
"versions": [...],
|
563
|
+
"pageCount": 1,
|
564
|
+
"pageNumber": 1,
|
565
|
+
"pageSize": 25
|
566
|
+
}
|
567
|
+
```
|
568
|
+
|
569
|
+
🔗 [**API Documentation**](https://service.peak.ai/image-management/api-docs/index.htm#/versions/get_api_v2_images__imageId__versions)
|
570
|
+
"""
|
571
|
+
image_client: Image = ctx.obj["client"]
|
572
|
+
response: Dict[str, Any] = image_client.list_image_versions(
|
573
|
+
image_id=image_id,
|
574
|
+
page_size=page_size,
|
575
|
+
page_number=page_number,
|
576
|
+
return_iterator=False,
|
577
|
+
version=version,
|
578
|
+
status=parse_list_of_strings(status),
|
579
|
+
last_build_status=parse_list_of_strings(last_build_status),
|
580
|
+
tags=parse_list_of_strings(tags),
|
581
|
+
)
|
582
|
+
console.print(response)
|
583
|
+
|
584
|
+
|
585
|
+
@app.command(short_help="Describe details of a specific image.")
|
586
|
+
def describe(ctx: typer.Context, image_id: int = _IMAGE_ID) -> None:
|
587
|
+
"""***Describe*** details of a specific image and its latest version.
|
588
|
+
|
589
|
+
\b
|
590
|
+
📝 ***Example usage:***<br/>
|
591
|
+
```bash
|
592
|
+
peak images describe 9999
|
593
|
+
```
|
594
|
+
|
595
|
+
\b
|
596
|
+
🆗 ***Response:***
|
597
|
+
```
|
598
|
+
{
|
599
|
+
"id": 1,
|
600
|
+
"name": "awesome-image",
|
601
|
+
"type": "workflow",
|
602
|
+
"scope": "custom",
|
603
|
+
"createdAt": "2020-01-01T18:00:00.000Z",
|
604
|
+
"createdBy": "someone@peak.ai",
|
605
|
+
"latestVersion": {...}
|
606
|
+
}
|
607
|
+
```
|
608
|
+
|
609
|
+
🔗 [**API Documentation**](https://service.peak.ai/image-management/api-docs/index.htm#/images/get_api_v2_images__imageId_)
|
610
|
+
"""
|
611
|
+
image_client: Image = ctx.obj["client"]
|
612
|
+
response = image_client.describe_image(image_id=image_id)
|
613
|
+
console.print(response)
|
614
|
+
|
615
|
+
|
616
|
+
@app.command(short_help="Describe details of a specific version.")
|
617
|
+
def describe_version(
|
618
|
+
ctx: typer.Context,
|
619
|
+
image_id: int = args.IMAGE_ID,
|
620
|
+
version_id: int = args.VERSION_ID,
|
621
|
+
) -> None:
|
622
|
+
"""***Describe*** details of a specific version.
|
623
|
+
|
624
|
+
\b
|
625
|
+
📝 ***Example usage:***<br/>
|
626
|
+
```bash
|
627
|
+
peak images describe-version --image-id 9999 --version-id 101
|
628
|
+
```
|
629
|
+
|
630
|
+
\b
|
631
|
+
🆗 ***Response:***
|
632
|
+
```
|
633
|
+
{
|
634
|
+
"imageName": "awesome-image",
|
635
|
+
"imageType": "Workflow",
|
636
|
+
"id": 101,
|
637
|
+
"version": "0.0.1-python3.9",
|
638
|
+
"description": "This is an awesome image",
|
639
|
+
"status": "not-ready",
|
640
|
+
"createdAt": "2020-01-01T18:00:00.000Z",
|
641
|
+
"createdBy": "someone@peak.ai",
|
642
|
+
"updatedAt": "2020-01-01T18:00:00.000Z",
|
643
|
+
"updatedBy": "someone@peak.ai",
|
644
|
+
"pullUrl": "<image-url>",
|
645
|
+
"lastBuildStatus": "building",
|
646
|
+
"lastBuildAt": "2020-01-01T18:00:00.000Z",
|
647
|
+
"buildDetails": {...},
|
648
|
+
"tags": [...]
|
649
|
+
}
|
650
|
+
```
|
651
|
+
|
652
|
+
🔗 [**API Documentation**](https://service.peak.ai/image-management/api-docs/index.htm#/versions/get_api_v2_images__imageId__versions__versionId_)
|
653
|
+
"""
|
654
|
+
image_client: Image = ctx.obj["client"]
|
655
|
+
response: Dict[str, Any] = image_client.describe_version(image_id=image_id, version_id=version_id)
|
656
|
+
console.print(response)
|
657
|
+
|
658
|
+
|
659
|
+
@app.command(short_help="Update an image version.")
|
660
|
+
def update_version(
|
661
|
+
ctx: typer.Context,
|
662
|
+
image_id: int = args.IMAGE_ID,
|
663
|
+
version_id: int = args.VERSION_ID,
|
664
|
+
file: Annotated[
|
665
|
+
Optional[str],
|
666
|
+
typer.Argument(
|
667
|
+
...,
|
668
|
+
help="Path to the file that defines the body for this operation, supports both `yaml` file or a `jinja` template.",
|
669
|
+
),
|
670
|
+
] = None,
|
671
|
+
params_file: str = args.TEMPLATE_PARAMS_FILE,
|
672
|
+
params: List[str] = args.TEMPLATE_PARAMS,
|
673
|
+
description: Optional[str] = _DESCRIPTION,
|
674
|
+
artifact_path: Optional[str] = _ARTIFACT_PATH,
|
675
|
+
artifact_ignore_files: Optional[List[str]] = _ARTIFACT_IGNORE_FILES,
|
676
|
+
build_details: Optional[str] = _BUILD_DETAILS,
|
677
|
+
source: Optional[str] = _SOURCE,
|
678
|
+
dockerfile: Optional[str] = _DOCKERFILE,
|
679
|
+
dockerfile_path: Optional[str] = _DOCKERFILE_PATH,
|
680
|
+
context: Optional[str] = _CONTEXT,
|
681
|
+
repository: Optional[str] = _REPOSITORY,
|
682
|
+
branch: Optional[str] = _BRANCH,
|
683
|
+
token: Optional[str] = _TOKEN,
|
684
|
+
use_cache: Optional[bool] = _USE_CACHE,
|
685
|
+
build_arguments: Optional[List[str]] = _BUILD_ARGUMENTS,
|
686
|
+
secrets: Optional[List[str]] = _SECRETS,
|
687
|
+
) -> None:
|
688
|
+
"""***Update*** an image version. Only the versions that are in `not-ready` state can be updated and you can not update their version while updating them.
|
689
|
+
|
690
|
+
\b
|
691
|
+
🧩 ***Input file schema(yaml):***<br/>
|
692
|
+
```yaml
|
693
|
+
body (map):
|
694
|
+
description (str | required: false): Description of the image version.
|
695
|
+
buildDetails (map):
|
696
|
+
source (str): Source via which image version can be created.
|
697
|
+
useCache (boolean | required: false): Whether to enable image caching to reduce build time, is enabled by default.
|
698
|
+
buildArguments (list(map) | required: false):
|
699
|
+
name (str): Name of the build argument.
|
700
|
+
value (str): Value of the build argument.
|
701
|
+
secrets (list(str) | required: false): List of secret names to be passed as build arguments.
|
702
|
+
context (str | required: false): The path within the artifact to code to be executed by the Dockerfile.
|
703
|
+
dockerfilePath (str | required: false): Path to the Dockerfile inside artifact or repository.
|
704
|
+
repository (str | required: false): When source is github, the repository where the Dockerfile content is stored.
|
705
|
+
branch (str | required: false): When source is github, the Branch that contains the Dockerfile.
|
706
|
+
token (str | required: false): When source is github, the token to be used to clone the required repository.
|
707
|
+
dockerfile (str | required: false): When source is dockerfile, this represents the content of Dockerfile to build the image from.
|
708
|
+
autodeployResources (list(map) | required: false): A list of resources that should be redeployed when the build completes.
|
709
|
+
entityId (str): The id of the resource to be redeployed.
|
710
|
+
entityType (str): The type of the resource to be redeployed. Allowed values are 'workflow', 'workspace', 'api' and 'webapp'.
|
711
|
+
artifact (map | required: false):
|
712
|
+
path (str): Path to the artifact.
|
713
|
+
ignore_files (list(str) | required: false) : Ignore files to use when creating artifact.
|
714
|
+
```
|
715
|
+
|
716
|
+
\b
|
717
|
+
📝 ***Example usage:***
|
718
|
+
```bash
|
719
|
+
peak images update-version --image-id 9999 --version-id 101 '/path/to/file.yaml' -v '/path/to/parmas.yaml'
|
720
|
+
```
|
721
|
+
|
722
|
+
We can also provide the required parameters from the command line or combine the YAML template and command line arguments in which case the command line arguments will take precedence.
|
723
|
+
|
724
|
+
\b
|
725
|
+
📝 ***Example usage without yaml:***
|
726
|
+
```bash
|
727
|
+
peak images update-version --image-id <image_id> --version-id <version_id> --description <description> --source <source> --dockerfile <dockerfile> --secrets <secret_1>,<secret_2>
|
728
|
+
```
|
729
|
+
|
730
|
+
\b
|
731
|
+
🆗 ***Response:***
|
732
|
+
```json
|
733
|
+
{
|
734
|
+
"buildId": "build-image-mock:2198c71e-22c5-aca3eac3a55e",
|
735
|
+
"versionId": 101,
|
736
|
+
"autodeploymentId": "0a12abcd-11ab-22d2-123a-a1234b333abc"
|
737
|
+
}
|
738
|
+
```
|
739
|
+
|
740
|
+
🔗 [**API Documentation**](https://service.peak.ai/image-management/api-docs/index.htm#/versions/patch_api_v2_images__imageId__versions__versionId_)
|
741
|
+
"""
|
742
|
+
image_client: Image = ctx.obj["client"]
|
743
|
+
|
744
|
+
user_options: Dict[str, Any] = variables_to_dict(
|
745
|
+
description,
|
746
|
+
build_details,
|
747
|
+
source,
|
748
|
+
dockerfile,
|
749
|
+
repository,
|
750
|
+
branch,
|
751
|
+
token,
|
752
|
+
dockerfile_path,
|
753
|
+
context,
|
754
|
+
use_cache,
|
755
|
+
build_arguments,
|
756
|
+
secrets,
|
757
|
+
)
|
758
|
+
|
759
|
+
user_options = map_user_options(user_options, MAPPING, dict_type_keys=["buildDetails"])
|
760
|
+
|
761
|
+
body: Dict[str, Any] = {}
|
762
|
+
if file:
|
763
|
+
body = helpers.template_handler(file=file, params_file=params_file, params=params)
|
764
|
+
body = helpers.remove_unknown_args(body, image_client.update_version)
|
765
|
+
|
766
|
+
updated_body = combine_dictionaries(
|
767
|
+
body.get("body") or {},
|
768
|
+
user_options,
|
769
|
+
)
|
770
|
+
artifact = helpers.get_updated_artifacts(body, artifact_path, artifact_ignore_files)
|
771
|
+
|
772
|
+
if build_arguments:
|
773
|
+
updated_body["buildDetails"]["buildArguments"] = helpers.parse_build_arguments(build_arguments)
|
774
|
+
|
775
|
+
if secrets:
|
776
|
+
updated_body["buildDetails"]["secrets"] = parse_list_of_strings(secrets)
|
777
|
+
|
778
|
+
response: Dict[str, str] = image_client.update_version(
|
779
|
+
image_id=image_id,
|
780
|
+
version_id=version_id,
|
781
|
+
body=updated_body,
|
782
|
+
artifact=artifact, # type: ignore # noqa: PGH003
|
783
|
+
)
|
784
|
+
console.print(response)
|
785
|
+
|
786
|
+
|
787
|
+
@app.command(short_help="Delete an image.")
|
788
|
+
def delete(
|
789
|
+
ctx: typer.Context,
|
790
|
+
image_id: int = _IMAGE_ID,
|
791
|
+
) -> None:
|
792
|
+
"""***Delete*** an image. If multiple versions are present in the image, this will delete only the ***latest version***.
|
793
|
+
|
794
|
+
\b
|
795
|
+
📝 ***Example usage:***<br/>
|
796
|
+
```bash
|
797
|
+
peak images delete 9999
|
798
|
+
```
|
799
|
+
|
800
|
+
\b
|
801
|
+
🆗 ***Response:***
|
802
|
+
```json
|
803
|
+
{}
|
804
|
+
```
|
805
|
+
|
806
|
+
🔗 [**API Documentation**](https://service.peak.ai/image-management/api-docs/index.htm#/images/delete_api_v1_images__imageId_)
|
807
|
+
"""
|
808
|
+
image_client: Image = ctx.obj["client"]
|
809
|
+
response = image_client.delete_image(image_id=image_id)
|
810
|
+
console.print(response)
|
811
|
+
|
812
|
+
|
813
|
+
@app.command(short_help="Delete an image version.")
|
814
|
+
def delete_version(
|
815
|
+
ctx: typer.Context,
|
816
|
+
image_id: int = args.IMAGE_ID,
|
817
|
+
version_id: int = args.VERSION_ID,
|
818
|
+
) -> None:
|
819
|
+
"""***Delete*** an image version. An image cannot be deleted if it is being used by any other resource.
|
820
|
+
|
821
|
+
\b
|
822
|
+
📝 ***Example usage:***<br/>
|
823
|
+
```bash
|
824
|
+
peak images delete-version --image-id 9999 --version-id 1
|
825
|
+
```
|
826
|
+
|
827
|
+
\b
|
828
|
+
🆗 ***Response:***
|
829
|
+
```json
|
830
|
+
{}
|
831
|
+
```
|
832
|
+
|
833
|
+
🔗 [**API Documentation**](https://service.peak.ai/image-management/api-docs/index.htm#/versions/delete_api_v2_images__imageId__versions__versionId_)
|
834
|
+
"""
|
835
|
+
image_client: Image = ctx.obj["client"]
|
836
|
+
response: Dict[None, None] = image_client.delete_version(image_id=image_id, version_id=version_id)
|
837
|
+
console.print(response)
|
838
|
+
|
839
|
+
|
840
|
+
@app.command(short_help="List image builds.")
|
841
|
+
def list_builds(
|
842
|
+
ctx: typer.Context,
|
843
|
+
image_id: int = _IMAGE_ID,
|
844
|
+
count: Optional[int] = _COUNT,
|
845
|
+
version_ids: Optional[List[str]] = _VERSIONS,
|
846
|
+
build_status: Optional[List[str]] = _BUILD_STATUS,
|
847
|
+
date_from: Optional[str] = args.DATE_FROM,
|
848
|
+
date_to: Optional[str] = args.DATE_TO,
|
849
|
+
page_size: Optional[int] = args.PAGE_SIZE,
|
850
|
+
page_number: Optional[int] = args.PAGE_NUMBER,
|
851
|
+
) -> None:
|
852
|
+
"""***List*** image builds for a specific image. If you want to view builds for a specific version you can pass in Version's ID to the command.
|
853
|
+
|
854
|
+
\b
|
855
|
+
📝 ***Example usage:***<br/>
|
856
|
+
```bash
|
857
|
+
peak images list-builds 9999 --version-ids 1,2,3 --page-size 10 --page-number 1
|
858
|
+
```
|
859
|
+
|
860
|
+
\b
|
861
|
+
🆗 ***Response:***
|
862
|
+
```
|
863
|
+
{
|
864
|
+
"buildCount": 1,
|
865
|
+
"builds": [...],
|
866
|
+
"pageCount": 1,
|
867
|
+
"pageNumber": 1,
|
868
|
+
"pageSize": 25
|
869
|
+
}
|
870
|
+
```
|
871
|
+
|
872
|
+
🔗 [**API Documentation**](https://service.peak.ai/image-management/api-docs/index.htm#/builds/get_api_v2_images__imageId__builds)
|
873
|
+
"""
|
874
|
+
image_client: Image = ctx.obj["client"]
|
875
|
+
response = image_client.list_image_builds(
|
876
|
+
image_id=image_id,
|
877
|
+
count=count,
|
878
|
+
build_status=parse_list_of_strings(build_status),
|
879
|
+
version_ids=parse_list_of_strings(version_ids),
|
880
|
+
date_from=date_from,
|
881
|
+
date_to=date_to,
|
882
|
+
page_size=page_size,
|
883
|
+
page_number=page_number,
|
884
|
+
return_iterator=False,
|
885
|
+
)
|
886
|
+
console.print(response)
|