oracle-ads 2.11.15__py3-none-any.whl → 2.11.17__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.
Files changed (44) hide show
  1. ads/aqua/app.py +5 -6
  2. ads/aqua/common/entities.py +17 -0
  3. ads/aqua/common/enums.py +14 -1
  4. ads/aqua/common/utils.py +160 -3
  5. ads/aqua/config/config.py +1 -1
  6. ads/aqua/config/deployment_config_defaults.json +29 -1
  7. ads/aqua/config/resource_limit_names.json +1 -0
  8. ads/aqua/constants.py +6 -1
  9. ads/aqua/evaluation/entities.py +0 -1
  10. ads/aqua/evaluation/evaluation.py +47 -14
  11. ads/aqua/extension/common_handler.py +75 -5
  12. ads/aqua/extension/common_ws_msg_handler.py +57 -0
  13. ads/aqua/extension/deployment_handler.py +16 -13
  14. ads/aqua/extension/deployment_ws_msg_handler.py +54 -0
  15. ads/aqua/extension/errors.py +1 -1
  16. ads/aqua/extension/evaluation_ws_msg_handler.py +28 -6
  17. ads/aqua/extension/model_handler.py +134 -8
  18. ads/aqua/extension/models/ws_models.py +78 -3
  19. ads/aqua/extension/models_ws_msg_handler.py +49 -0
  20. ads/aqua/extension/ui_websocket_handler.py +7 -1
  21. ads/aqua/model/entities.py +28 -0
  22. ads/aqua/model/model.py +544 -129
  23. ads/aqua/modeldeployment/deployment.py +102 -43
  24. ads/aqua/modeldeployment/entities.py +9 -20
  25. ads/aqua/ui.py +152 -28
  26. ads/common/object_storage_details.py +2 -5
  27. ads/common/serializer.py +2 -3
  28. ads/jobs/builders/infrastructure/dsc_job.py +41 -12
  29. ads/jobs/builders/infrastructure/dsc_job_runtime.py +74 -27
  30. ads/jobs/builders/runtimes/container_runtime.py +83 -4
  31. ads/opctl/operator/lowcode/anomaly/const.py +1 -0
  32. ads/opctl/operator/lowcode/anomaly/model/base_model.py +23 -7
  33. ads/opctl/operator/lowcode/anomaly/operator_config.py +1 -0
  34. ads/opctl/operator/lowcode/anomaly/schema.yaml +4 -0
  35. ads/opctl/operator/lowcode/common/errors.py +6 -0
  36. ads/opctl/operator/lowcode/forecast/model/arima.py +3 -1
  37. ads/opctl/operator/lowcode/forecast/model/base_model.py +21 -13
  38. ads/opctl/operator/lowcode/forecast/model_evaluator.py +11 -2
  39. ads/pipeline/ads_pipeline_run.py +13 -2
  40. {oracle_ads-2.11.15.dist-info → oracle_ads-2.11.17.dist-info}/METADATA +2 -1
  41. {oracle_ads-2.11.15.dist-info → oracle_ads-2.11.17.dist-info}/RECORD +44 -40
  42. {oracle_ads-2.11.15.dist-info → oracle_ads-2.11.17.dist-info}/LICENSE.txt +0 -0
  43. {oracle_ads-2.11.15.dist-info → oracle_ads-2.11.17.dist-info}/WHEEL +0 -0
  44. {oracle_ads-2.11.15.dist-info → oracle_ads-2.11.17.dist-info}/entry_points.txt +0 -0
@@ -3,9 +3,10 @@
3
3
  # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
4
4
 
5
5
  import logging
6
- from typing import Dict, List, Union
6
+ from typing import Dict, List, Optional, Union
7
7
 
8
8
  from ads.aqua.app import AquaApp, logger
9
+ from ads.aqua.common.entities import ContainerSpec
9
10
  from ads.aqua.common.enums import (
10
11
  InferenceContainerTypeFamily,
11
12
  Tags,
@@ -25,6 +26,7 @@ from ads.aqua.common.utils import (
25
26
  load_config,
26
27
  )
27
28
  from ads.aqua.constants import (
29
+ AQUA_MODEL_ARTIFACT_FILE,
28
30
  AQUA_MODEL_TYPE_CUSTOM,
29
31
  AQUA_MODEL_TYPE_SERVICE,
30
32
  MODEL_BY_REFERENCE_OSS_PATH_KEY,
@@ -37,8 +39,8 @@ from ads.aqua.model import AquaModelApp
37
39
  from ads.aqua.modeldeployment.entities import (
38
40
  AquaDeployment,
39
41
  AquaDeploymentDetail,
40
- ContainerSpec,
41
42
  )
43
+ from ads.aqua.ui import ModelFormat
42
44
  from ads.common.object_storage_details import ObjectStorageDetails
43
45
  from ads.common.utils import get_log_links
44
46
  from ads.config import (
@@ -85,23 +87,26 @@ class AquaDeploymentApp(AquaApp):
85
87
 
86
88
  @telemetry(entry_point="plugin=deployment&action=create", name="aqua")
87
89
  def create(
88
- self,
89
- model_id: str,
90
- instance_shape: str,
91
- display_name: str,
92
- instance_count: int = None,
93
- log_group_id: str = None,
94
- access_log_id: str = None,
95
- predict_log_id: str = None,
96
- compartment_id: str = None,
97
- project_id: str = None,
98
- description: str = None,
99
- bandwidth_mbps: int = None,
100
- web_concurrency: int = None,
101
- server_port: int = None,
102
- health_check_port: int = None,
103
- env_var: Dict = None,
104
- container_family: str = None,
90
+ self,
91
+ model_id: str,
92
+ instance_shape: str,
93
+ display_name: str,
94
+ instance_count: int = None,
95
+ log_group_id: str = None,
96
+ access_log_id: str = None,
97
+ predict_log_id: str = None,
98
+ compartment_id: str = None,
99
+ project_id: str = None,
100
+ description: str = None,
101
+ bandwidth_mbps: int = None,
102
+ web_concurrency: int = None,
103
+ server_port: int = None,
104
+ health_check_port: int = None,
105
+ env_var: Dict = None,
106
+ container_family: str = None,
107
+ memory_in_gbs: Optional[float] = None,
108
+ ocpus: Optional[float] = None,
109
+ model_file: Optional[str] = None,
105
110
  ) -> "AquaDeployment":
106
111
  """
107
112
  Creates a new Aqua deployment
@@ -142,6 +147,12 @@ class AquaDeploymentApp(AquaApp):
142
147
  Environment variable for the deployment, by default None.
143
148
  container_family: str
144
149
  The image family of model deployment container runtime. Required for unverified Aqua models.
150
+ memory_in_gbs: float
151
+ The memory in gbs for the shape selected.
152
+ ocpus: float
153
+ The ocpu count for the shape selected.
154
+ model_file: str
155
+ The file used for model deployment.
145
156
  Returns
146
157
  -------
147
158
  AquaDeployment
@@ -239,7 +250,7 @@ class AquaDeploymentApp(AquaApp):
239
250
  try:
240
251
  # Check if the container override flag is set. If set, then the user has chosen custom image
241
252
  if aqua_model.custom_metadata_list.get(
242
- AQUA_DEPLOYMENT_CONTAINER_OVERRIDE_FLAG_METADATA_NAME
253
+ AQUA_DEPLOYMENT_CONTAINER_OVERRIDE_FLAG_METADATA_NAME
243
254
  ).value:
244
255
  is_custom_container = True
245
256
  except Exception:
@@ -258,8 +269,36 @@ class AquaDeploymentApp(AquaApp):
258
269
  f"Aqua Image used for deploying {aqua_model.id} : {container_image}"
259
270
  )
260
271
 
272
+ model_formats_str = aqua_model.freeform_tags.get(
273
+ Tags.MODEL_FORMAT, ModelFormat.SAFETENSORS.value
274
+ ).upper()
275
+ model_format = model_formats_str.split(",")
276
+
277
+ # Figure out a better way to handle this in future release
278
+ if ModelFormat.GGUF.value in model_format and container_type_key.lower() == InferenceContainerTypeFamily.AQUA_LLAMA_CPP_CONTAINER_FAMILY:
279
+ if model_file is not None:
280
+ logger.info(
281
+ f"Overriding {model_file} as model_file for model {aqua_model.id}."
282
+ )
283
+ else:
284
+ try:
285
+ model_file = aqua_model.custom_metadata_list.get(
286
+ AQUA_MODEL_ARTIFACT_FILE
287
+ ).value
288
+ except ValueError as err:
289
+ raise AquaValueError(
290
+ f"{AQUA_MODEL_ARTIFACT_FILE} key is not available in the custom metadata field "
291
+ f"for model {aqua_model.id}. Either register the model with a default model_file or pass "
292
+ f"as a parameter when creating a deployment."
293
+ ) from err
294
+
295
+ env_var.update({"BASE_MODEL_FILE": f"{model_file}"})
296
+ tags.update({Tags.MODEL_ARTIFACT_FILE: model_file})
297
+
298
+ # todo: use AquaContainerConfig.from_container_index_json instead.
261
299
  # Fetch the startup cli command for the container
262
- # container_index.json will have "containerSpec" section which will provide the cli params for a given container family
300
+ # container_index.json will have "containerSpec" section which will provide the cli params for
301
+ # a given container family
263
302
  container_config = get_container_config()
264
303
  container_spec = container_config.get(ContainerSpec.CONTAINER_SPEC, {}).get(
265
304
  container_type_key, {}
@@ -285,6 +324,18 @@ class AquaDeploymentApp(AquaApp):
285
324
  # validate user provided params
286
325
  user_params = env_var.get("PARAMS", UNKNOWN)
287
326
  if user_params:
327
+ # todo: remove this check in the future version, logic to be moved to container_index
328
+ if (
329
+ container_type_key.lower()
330
+ == InferenceContainerTypeFamily.AQUA_LLAMA_CPP_CONTAINER_FAMILY
331
+ ):
332
+ # AQUA_LLAMA_CPP_CONTAINER_FAMILY container uses uvicorn that required model/server params
333
+ # to be set as env vars
334
+ raise AquaValueError(
335
+ f"Currently, parameters cannot be overridden for the container: {container_image}. Please proceed "
336
+ f"with deployment without parameter overrides."
337
+ )
338
+
288
339
  restricted_params = self._find_restricted_params(
289
340
  params, user_params, container_type_key
290
341
  )
@@ -296,13 +347,15 @@ class AquaDeploymentApp(AquaApp):
296
347
 
297
348
  deployment_params = get_combined_params(config_params, user_params)
298
349
 
299
- if deployment_params:
300
- params = f"{params} {deployment_params}"
350
+ params = f"{params} {deployment_params}".strip()
351
+ if params:
352
+ env_var.update({"PARAMS": params})
301
353
 
302
- env_var.update({"PARAMS": params})
303
354
  for env in container_spec.get(ContainerSpec.ENV_VARS, []):
304
355
  if isinstance(env, dict):
305
- env_var.update(env)
356
+ for key, _items in env.items():
357
+ if key not in env_var:
358
+ env_var.update(env)
306
359
 
307
360
  logging.info(f"Env vars used for deploying {aqua_model.id} :{env_var}")
308
361
 
@@ -325,6 +378,11 @@ class AquaDeploymentApp(AquaApp):
325
378
  log_id=predict_log_id,
326
379
  )
327
380
  )
381
+ if memory_in_gbs and ocpus and infrastructure.shape_name.endswith("Flex"):
382
+ infrastructure.with_shape_config_details(
383
+ ocpus=ocpus,
384
+ memory_in_gbs=memory_in_gbs,
385
+ )
328
386
  # configure model deployment runtime
329
387
  container_runtime = (
330
388
  ModelDeploymentContainerRuntime()
@@ -338,6 +396,7 @@ class AquaDeploymentApp(AquaApp):
338
396
  .with_overwrite_existing_artifact(True)
339
397
  .with_remove_existing_artifact(True)
340
398
  )
399
+
341
400
  # configure model deployment and deploy model on container runtime
342
401
  deployment = (
343
402
  ModelDeployment()
@@ -401,8 +460,8 @@ class AquaDeploymentApp(AquaApp):
401
460
  for model_deployment in model_deployments:
402
461
  oci_aqua = (
403
462
  (
404
- Tags.AQUA_TAG in model_deployment.freeform_tags
405
- or Tags.AQUA_TAG.lower() in model_deployment.freeform_tags
463
+ Tags.AQUA_TAG in model_deployment.freeform_tags
464
+ or Tags.AQUA_TAG.lower() in model_deployment.freeform_tags
406
465
  )
407
466
  if model_deployment.freeform_tags
408
467
  else False
@@ -456,8 +515,8 @@ class AquaDeploymentApp(AquaApp):
456
515
 
457
516
  oci_aqua = (
458
517
  (
459
- Tags.AQUA_TAG in model_deployment.freeform_tags
460
- or Tags.AQUA_TAG.lower() in model_deployment.freeform_tags
518
+ Tags.AQUA_TAG in model_deployment.freeform_tags
519
+ or Tags.AQUA_TAG.lower() in model_deployment.freeform_tags
461
520
  )
462
521
  if model_deployment.freeform_tags
463
522
  else False
@@ -474,8 +533,8 @@ class AquaDeploymentApp(AquaApp):
474
533
  log_group_name = ""
475
534
 
476
535
  logs = (
477
- model_deployment.category_log_details.access
478
- or model_deployment.category_log_details.predict
536
+ model_deployment.category_log_details.access
537
+ or model_deployment.category_log_details.predict
479
538
  )
480
539
  if logs:
481
540
  log_id = logs.log_id
@@ -530,9 +589,9 @@ class AquaDeploymentApp(AquaApp):
530
589
  return config
531
590
 
532
591
  def get_deployment_default_params(
533
- self,
534
- model_id: str,
535
- instance_shape: str,
592
+ self,
593
+ model_id: str,
594
+ instance_shape: str,
536
595
  ) -> List[str]:
537
596
  """Gets the default params set in the deployment configs for the given model and instance shape.
538
597
 
@@ -564,8 +623,8 @@ class AquaDeploymentApp(AquaApp):
564
623
  )
565
624
 
566
625
  if (
567
- container_type_key
568
- and container_type_key in InferenceContainerTypeFamily.values()
626
+ container_type_key
627
+ and container_type_key in InferenceContainerTypeFamily.values()
569
628
  ):
570
629
  deployment_config = self.get_deployment_config(model_id)
571
630
  config_params = (
@@ -588,10 +647,10 @@ class AquaDeploymentApp(AquaApp):
588
647
  return default_params
589
648
 
590
649
  def validate_deployment_params(
591
- self,
592
- model_id: str,
593
- params: List[str] = None,
594
- container_family: str = None,
650
+ self,
651
+ model_id: str,
652
+ params: List[str] = None,
653
+ container_family: str = None,
595
654
  ) -> Dict:
596
655
  """Validate if the deployment parameters passed by the user can be overridden. Parameter values are not
597
656
  validated, only param keys are validated.
@@ -650,9 +709,9 @@ class AquaDeploymentApp(AquaApp):
650
709
 
651
710
  @staticmethod
652
711
  def _find_restricted_params(
653
- default_params: Union[str, List[str]],
654
- user_params: Union[str, List[str]],
655
- container_family: str,
712
+ default_params: Union[str, List[str]],
713
+ user_params: Union[str, List[str]],
714
+ container_family: str,
656
715
  ) -> List[str]:
657
716
  """Returns a list of restricted params that user chooses to override when creating an Aqua deployment.
658
717
  The default parameters coming from the container index json file cannot be overridden.
@@ -1,12 +1,14 @@
1
1
  #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
2
  # Copyright (c) 2024 Oracle and/or its affiliates.
4
3
  # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
5
4
 
6
5
  from dataclasses import dataclass, field
7
6
  from typing import Union
8
7
 
9
- from oci.data_science.models import ModelDeployment, ModelDeploymentSummary
8
+ from oci.data_science.models import (
9
+ ModelDeployment,
10
+ ModelDeploymentSummary,
11
+ )
10
12
 
11
13
  from ads.aqua.common.enums import Tags
12
14
  from ads.aqua.constants import UNKNOWN, UNKNOWN_DICT
@@ -24,18 +26,6 @@ class ModelParams:
24
26
  model: str = None
25
27
 
26
28
 
27
- class ContainerSpec:
28
- """
29
- Class to hold to hold keys within the container spec.
30
- """
31
-
32
- CONTAINER_SPEC = "containerSpec"
33
- CLI_PARM = "cliParam"
34
- SERVER_PORT = "serverPort"
35
- HEALTH_CHECK_PORT = "healthCheckPort"
36
- ENV_VARS = "envVars"
37
-
38
-
39
29
  @dataclass
40
30
  class ShapeInfo:
41
31
  instance_shape: str = None
@@ -61,6 +51,7 @@ class AquaDeployment(DataClassSerializable):
61
51
  lifecycle_details: str = None
62
52
  shape_info: field(default_factory=ShapeInfo) = None
63
53
  tags: dict = None
54
+ environment_variables: dict = None
64
55
 
65
56
  @classmethod
66
57
  def from_oci_model_deployment(
@@ -83,15 +74,12 @@ class AquaDeployment(DataClassSerializable):
83
74
  AquaDeployment:
84
75
  The instance of the Aqua model deployment.
85
76
  """
86
- instance_configuration = (
87
- oci_model_deployment.model_deployment_configuration_details.model_configuration_details.instance_configuration
88
- )
77
+ instance_configuration = oci_model_deployment.model_deployment_configuration_details.model_configuration_details.instance_configuration
89
78
  instance_shape_config_details = (
90
79
  instance_configuration.model_deployment_instance_shape_config_details
91
80
  )
92
- instance_count = (
93
- oci_model_deployment.model_deployment_configuration_details.model_configuration_details.scaling_policy.instance_count
94
- )
81
+ instance_count = oci_model_deployment.model_deployment_configuration_details.model_configuration_details.scaling_policy.instance_count
82
+ environment_variables = oci_model_deployment.model_deployment_configuration_details.environment_configuration_details.environment_variables
95
83
  shape_info = ShapeInfo(
96
84
  instance_shape=instance_configuration.instance_shape_name,
97
85
  instance_count=instance_count,
@@ -131,6 +119,7 @@ class AquaDeployment(DataClassSerializable):
131
119
  region=region,
132
120
  ),
133
121
  tags=freeform_tags,
122
+ environment_variables=environment_variables,
134
123
  )
135
124
 
136
125
 
ads/aqua/ui.py CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
2
  # Copyright (c) 2024 Oracle and/or its affiliates.
4
3
  # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
5
4
  import concurrent.futures
6
- from dataclasses import dataclass, field
5
+ from dataclasses import dataclass, field, fields
7
6
  from datetime import datetime, timedelta
7
+ from enum import Enum
8
8
  from threading import Lock
9
- from typing import Dict, List
9
+ from typing import Dict, List, Optional
10
10
 
11
11
  from cachetools import TTLCache
12
12
  from oci.exceptions import ServiceError
@@ -14,6 +14,7 @@ from oci.identity.models import Compartment
14
14
 
15
15
  from ads.aqua import logger
16
16
  from ads.aqua.app import AquaApp
17
+ from ads.aqua.common.entities import ContainerSpec
17
18
  from ads.aqua.common.enums import Tags
18
19
  from ads.aqua.common.errors import AquaResourceAccessError, AquaValueError
19
20
  from ads.aqua.common.utils import get_container_config, load_config, sanitize_response
@@ -31,14 +32,84 @@ from ads.config import (
31
32
  from ads.telemetry import telemetry
32
33
 
33
34
 
35
+ class ModelFormat(Enum):
36
+ GGUF = "GGUF"
37
+ SAFETENSORS = "SAFETENSORS"
38
+ UNKNOWN = "UNKNOWN"
39
+
40
+ def to_dict(self):
41
+ return self.value
42
+
43
+
44
+ # todo: the container config spec information is shared across ui and deployment modules, move them
45
+ # within ads.aqua.common.entities. In that case, check for circular imports due to usage of get_container_config.
46
+
47
+
48
+ @dataclass(repr=False)
49
+ class AquaContainerEvaluationConfig(DataClassSerializable):
50
+ """
51
+ Represents the evaluation configuration for the container.
52
+ """
53
+
54
+ inference_max_threads: Optional[int] = None
55
+ inference_rps: Optional[int] = None
56
+ inference_timeout: Optional[int] = None
57
+ inference_retries: Optional[int] = None
58
+ inference_backoff_factor: Optional[int] = None
59
+ inference_delay: Optional[int] = None
60
+
61
+ @classmethod
62
+ def from_config(cls, config: dict) -> "AquaContainerEvaluationConfig":
63
+ return cls(
64
+ inference_max_threads=config.get("inference_max_threads"),
65
+ inference_rps=config.get("inference_rps"),
66
+ inference_timeout=config.get("inference_timeout"),
67
+ inference_retries=config.get("inference_retries"),
68
+ inference_backoff_factor=config.get("inference_backoff_factor"),
69
+ inference_delay=config.get("inference_delay"),
70
+ )
71
+
72
+ def to_filtered_dict(self):
73
+ return {
74
+ field.name: getattr(self, field.name)
75
+ for field in fields(self)
76
+ if getattr(self, field.name) is not None
77
+ }
78
+
79
+
80
+ @dataclass(repr=False)
81
+ class AquaContainerConfigSpec(DataClassSerializable):
82
+ cli_param: str = None
83
+ server_port: str = None
84
+ health_check_port: str = None
85
+ env_vars: List[dict] = None
86
+ restricted_params: List[str] = None
87
+ evaluation_configuration: AquaContainerEvaluationConfig = field(
88
+ default_factory=AquaContainerEvaluationConfig
89
+ )
90
+
91
+
34
92
  @dataclass(repr=False)
35
93
  class AquaContainerConfigItem(DataClassSerializable):
36
94
  """Represents an item of the AQUA container configuration."""
37
95
 
96
+ class Platform(Enum):
97
+ ARM_CPU = "ARM_CPU"
98
+ NVIDIA_GPU = "NVIDIA_GPU"
99
+
100
+ def to_dict(self):
101
+ return self.value
102
+
103
+ def __repr__(self):
104
+ return repr(self.value)
105
+
38
106
  name: str = None
39
107
  version: str = None
40
108
  display_name: str = None
41
109
  family: str = None
110
+ platforms: List[Platform] = None
111
+ model_formats: List[ModelFormat] = None
112
+ spec: AquaContainerConfigSpec = field(default_factory=AquaContainerConfigSpec)
42
113
 
43
114
 
44
115
  @dataclass(repr=False)
@@ -47,12 +118,23 @@ class AquaContainerConfig(DataClassSerializable):
47
118
  Represents a configuration with AQUA containers to be returned to the client.
48
119
  """
49
120
 
50
- inference: List[AquaContainerConfigItem] = field(default_factory=list)
51
- finetune: List[AquaContainerConfigItem] = field(default_factory=list)
52
- evaluate: List[AquaContainerConfigItem] = field(default_factory=list)
121
+ inference: Dict[str, AquaContainerConfigItem] = field(default_factory=dict)
122
+ finetune: Dict[str, AquaContainerConfigItem] = field(default_factory=dict)
123
+ evaluate: Dict[str, AquaContainerConfigItem] = field(default_factory=dict)
124
+
125
+ def to_dict(self):
126
+ return {
127
+ "inference": list(self.inference.values()),
128
+ "finetune": list(self.finetune.values()),
129
+ "evaluate": list(self.evaluate.values()),
130
+ }
53
131
 
54
132
  @classmethod
55
- def from_container_index_json(cls, config: Dict) -> "AquaContainerConfig":
133
+ def from_container_index_json(
134
+ cls,
135
+ config: Optional[Dict] = None,
136
+ enable_spec: Optional[bool] = False,
137
+ ) -> "AquaContainerConfig":
56
138
  """
57
139
  Create an AquaContainerConfig instance from a container index JSON.
58
140
 
@@ -60,21 +142,39 @@ class AquaContainerConfig(DataClassSerializable):
60
142
  ----------
61
143
  config : Dict
62
144
  The container index JSON.
145
+ enable_spec: bool
146
+ flag to check if container specification details should be fetched.
63
147
 
64
148
  Returns
65
149
  -------
66
150
  AquaContainerConfig
67
151
  The container configuration instance.
68
152
  """
69
- config = config or {}
70
- inference_items = []
71
- finetune_items = []
72
- evaluate_items = []
153
+ if not config:
154
+ config = get_container_config()
155
+ inference_items = {}
156
+ finetune_items = {}
157
+ evaluate_items = {}
73
158
 
74
159
  # extract inference containers
75
160
  for container_type, containers in config.items():
76
161
  if isinstance(containers, list):
77
162
  for container in containers:
163
+ platforms = [
164
+ AquaContainerConfigItem.Platform[platform]
165
+ for platform in container.get("platforms", [])
166
+ ]
167
+ model_formats = [
168
+ ModelFormat[model_format]
169
+ for model_format in container.get("modelFormats", [])
170
+ ]
171
+ container_spec = (
172
+ config.get(ContainerSpec.CONTAINER_SPEC, {}).get(
173
+ container_type, {}
174
+ )
175
+ if enable_spec
176
+ else None
177
+ )
78
178
  container_item = AquaContainerConfigItem(
79
179
  name=container.get("name", ""),
80
180
  version=container.get("version", ""),
@@ -82,13 +182,35 @@ class AquaContainerConfig(DataClassSerializable):
82
182
  "displayName", container.get("version", "")
83
183
  ),
84
184
  family=container_type,
185
+ platforms=platforms,
186
+ model_formats=model_formats,
187
+ spec=AquaContainerConfigSpec(
188
+ cli_param=container_spec.get(ContainerSpec.CLI_PARM, ""),
189
+ server_port=container_spec.get(
190
+ ContainerSpec.SERVER_PORT, ""
191
+ ),
192
+ health_check_port=container_spec.get(
193
+ ContainerSpec.HEALTH_CHECK_PORT, ""
194
+ ),
195
+ env_vars=container_spec.get(ContainerSpec.ENV_VARS, []),
196
+ restricted_params=container_spec.get(
197
+ ContainerSpec.RESTRICTED_PARAMS, []
198
+ ),
199
+ evaluation_configuration=AquaContainerEvaluationConfig.from_config(
200
+ container_spec.get(
201
+ ContainerSpec.EVALUATION_CONFIGURATION, {}
202
+ )
203
+ ),
204
+ )
205
+ if container_spec
206
+ else None,
85
207
  )
86
208
  if container.get("type") == "inference":
87
- inference_items.append(container_item)
209
+ inference_items[container_type] = container_item
88
210
  elif container_type == "odsc-llm-fine-tuning":
89
- finetune_items.append(container_item)
211
+ finetune_items[container_type] = container_item
90
212
  elif container_type == "odsc-llm-evaluate":
91
- evaluate_items.append(container_item)
213
+ evaluate_items[container_type] = container_item
92
214
 
93
215
  return AquaContainerConfig(
94
216
  inference=inference_items, finetune=finetune_items, evaluate=evaluate_items
@@ -175,11 +297,11 @@ class AquaUIApp(AquaApp):
175
297
  try:
176
298
  if not TENANCY_OCID:
177
299
  raise AquaValueError(
178
- f"TENANCY_OCID must be available in environment"
300
+ "TENANCY_OCID must be available in environment"
179
301
  " variables to list the sub compartments."
180
302
  )
181
303
 
182
- if TENANCY_OCID in self._compartments_cache.keys():
304
+ if TENANCY_OCID in self._compartments_cache:
183
305
  logger.info(
184
306
  f"Returning compartments list in {TENANCY_OCID} from cache."
185
307
  )
@@ -196,7 +318,7 @@ class AquaUIApp(AquaApp):
196
318
  access_level="ANY",
197
319
  )
198
320
  )
199
- except ServiceError as se:
321
+ except ServiceError:
200
322
  logger.error(
201
323
  f"ERROR: Unable to list all sub compartment in tenancy {TENANCY_OCID}."
202
324
  )
@@ -207,7 +329,7 @@ class AquaUIApp(AquaApp):
207
329
  compartment_id=TENANCY_OCID,
208
330
  )
209
331
  )
210
- except ServiceError as se:
332
+ except ServiceError:
211
333
  logger.error(
212
334
  f"ERROR: Unable to list all child compartment in tenancy {TENANCY_OCID}."
213
335
  )
@@ -216,7 +338,7 @@ class AquaUIApp(AquaApp):
216
338
  TENANCY_OCID
217
339
  ).data
218
340
  compartments.insert(0, root_compartment)
219
- except ServiceError as se:
341
+ except ServiceError:
220
342
  logger.error(
221
343
  f"ERROR: Unable to get details of the root compartment {TENANCY_OCID}."
222
344
  )
@@ -248,7 +370,7 @@ class AquaUIApp(AquaApp):
248
370
  """
249
371
  if not COMPARTMENT_OCID:
250
372
  logger.error("No compartment id found from environment variables.")
251
- return dict(compartment_id=COMPARTMENT_OCID)
373
+ return {"compartment_id": COMPARTMENT_OCID}
252
374
 
253
375
  def clear_compartments_list_cache(self) -> dict:
254
376
  """Allows caller to clear compartments list cache
@@ -257,9 +379,9 @@ class AquaUIApp(AquaApp):
257
379
  dict with the key used, and True if cache has the key that needs to be deleted.
258
380
  """
259
381
  res = {}
260
- logger.info(f"Clearing list_compartments cache")
382
+ logger.info("Clearing list_compartments cache")
261
383
  with self._cache_lock:
262
- if TENANCY_OCID in self._compartments_cache.keys():
384
+ if TENANCY_OCID in self._compartments_cache:
263
385
  self._compartments_cache.pop(key=TENANCY_OCID)
264
386
  res = {
265
387
  "key": {
@@ -332,6 +454,7 @@ class AquaUIApp(AquaApp):
332
454
  response = os_client.list_buckets(
333
455
  namespace_name=namespace_name,
334
456
  compartment_id=compartment_id,
457
+ limit=1000,
335
458
  **kwargs,
336
459
  ).data
337
460
 
@@ -474,16 +597,16 @@ class AquaUIApp(AquaApp):
474
597
  raise AquaResourceAccessError(
475
598
  f"Could not check limits availability for the shape {instance_shape}. Make sure you have the necessary policy to check limits availability.",
476
599
  service_payload=se.args[0] if se.args else None,
477
- )
600
+ ) from None
478
601
 
479
602
  available = res.available
480
603
 
481
604
  try:
482
605
  cards = int(instance_shape.split(".")[-1])
483
- except:
606
+ except Exception:
484
607
  cards = 1
485
608
 
486
- response = dict(available_count=available)
609
+ response = {"available_count": available}
487
610
 
488
611
  if available < cards:
489
612
  raise AquaValueError(
@@ -516,7 +639,7 @@ class AquaUIApp(AquaApp):
516
639
  is_versioned = False
517
640
  message = f"Model artifact bucket {bucket_uri} is not versioned. Check if the path exists and enable versioning on the bucket to proceed with model creation."
518
641
 
519
- return dict(is_versioned=is_versioned, message=message)
642
+ return {"is_versioned": is_versioned, "message": message}
520
643
 
521
644
  @telemetry(entry_point="plugin=ui&action=list_containers", name="aqua")
522
645
  def list_containers(self) -> AquaContainerConfig:
@@ -526,8 +649,9 @@ class AquaUIApp(AquaApp):
526
649
  Returns
527
650
  -------
528
651
  AquaContainerConfig
529
- The AQUA containers configuration.
652
+ The AQUA containers configurations.
530
653
  """
531
654
  return AquaContainerConfig.from_container_index_json(
532
- config=get_container_config()
655
+ config=get_container_config(),
656
+ enable_spec=True,
533
657
  )