oracle-ads 2.11.14__py3-none-any.whl → 2.11.16__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 (70) hide show
  1. ads/aqua/common/entities.py +17 -0
  2. ads/aqua/common/enums.py +5 -1
  3. ads/aqua/common/utils.py +109 -22
  4. ads/aqua/config/config.py +1 -1
  5. ads/aqua/config/deployment_config_defaults.json +29 -1
  6. ads/aqua/config/resource_limit_names.json +1 -0
  7. ads/aqua/constants.py +35 -18
  8. ads/aqua/evaluation/entities.py +0 -1
  9. ads/aqua/evaluation/evaluation.py +165 -121
  10. ads/aqua/extension/common_ws_msg_handler.py +57 -0
  11. ads/aqua/extension/deployment_handler.py +14 -13
  12. ads/aqua/extension/deployment_ws_msg_handler.py +54 -0
  13. ads/aqua/extension/errors.py +1 -1
  14. ads/aqua/extension/evaluation_handler.py +4 -7
  15. ads/aqua/extension/evaluation_ws_msg_handler.py +28 -10
  16. ads/aqua/extension/model_handler.py +31 -6
  17. ads/aqua/extension/models/ws_models.py +78 -3
  18. ads/aqua/extension/models_ws_msg_handler.py +49 -0
  19. ads/aqua/extension/ui_websocket_handler.py +7 -1
  20. ads/aqua/model/entities.py +17 -9
  21. ads/aqua/model/model.py +260 -90
  22. ads/aqua/modeldeployment/constants.py +0 -16
  23. ads/aqua/modeldeployment/deployment.py +97 -74
  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 +29 -3
  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/common/operator_config.py +1 -0
  32. ads/opctl/operator/lowcode/anomaly/README.md +3 -3
  33. ads/opctl/operator/lowcode/anomaly/__main__.py +5 -6
  34. ads/opctl/operator/lowcode/anomaly/const.py +9 -0
  35. ads/opctl/operator/lowcode/anomaly/model/anomaly_dataset.py +6 -2
  36. ads/opctl/operator/lowcode/anomaly/model/base_model.py +51 -26
  37. ads/opctl/operator/lowcode/anomaly/model/factory.py +41 -13
  38. ads/opctl/operator/lowcode/anomaly/model/isolationforest.py +79 -0
  39. ads/opctl/operator/lowcode/anomaly/model/oneclasssvm.py +79 -0
  40. ads/opctl/operator/lowcode/anomaly/operator_config.py +1 -0
  41. ads/opctl/operator/lowcode/anomaly/schema.yaml +16 -2
  42. ads/opctl/operator/lowcode/anomaly/utils.py +16 -13
  43. ads/opctl/operator/lowcode/common/data.py +2 -1
  44. ads/opctl/operator/lowcode/common/errors.py +6 -0
  45. ads/opctl/operator/lowcode/common/transformations.py +37 -9
  46. ads/opctl/operator/lowcode/common/utils.py +32 -10
  47. ads/opctl/operator/lowcode/forecast/model/base_model.py +21 -13
  48. ads/opctl/operator/lowcode/forecast/model/ml_forecast.py +14 -18
  49. ads/opctl/operator/lowcode/forecast/model_evaluator.py +15 -4
  50. ads/opctl/operator/lowcode/forecast/schema.yaml +9 -0
  51. ads/opctl/operator/lowcode/recommender/MLoperator +16 -0
  52. ads/opctl/operator/lowcode/recommender/README.md +206 -0
  53. ads/opctl/operator/lowcode/recommender/__init__.py +5 -0
  54. ads/opctl/operator/lowcode/recommender/__main__.py +82 -0
  55. ads/opctl/operator/lowcode/recommender/cmd.py +33 -0
  56. ads/opctl/operator/lowcode/recommender/constant.py +25 -0
  57. ads/opctl/operator/lowcode/recommender/environment.yaml +11 -0
  58. ads/opctl/operator/lowcode/recommender/model/base_model.py +198 -0
  59. ads/opctl/operator/lowcode/recommender/model/factory.py +58 -0
  60. ads/opctl/operator/lowcode/recommender/model/recommender_dataset.py +25 -0
  61. ads/opctl/operator/lowcode/recommender/model/svd.py +88 -0
  62. ads/opctl/operator/lowcode/recommender/operator_config.py +81 -0
  63. ads/opctl/operator/lowcode/recommender/schema.yaml +265 -0
  64. ads/opctl/operator/lowcode/recommender/utils.py +13 -0
  65. ads/pipeline/ads_pipeline_run.py +13 -2
  66. {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/METADATA +6 -1
  67. {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/RECORD +70 -50
  68. {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/LICENSE.txt +0 -0
  69. {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/WHEEL +0 -0
  70. {oracle_ads-2.11.14.dist-info → oracle_ads-2.11.16.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,4 @@
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
 
@@ -8,8 +7,8 @@ from urllib.parse import urlparse
8
7
  from tornado.web import HTTPError
9
8
 
10
9
  from ads.aqua.common.decorator import handle_exceptions
11
- from ads.aqua.extension.errors import Errors
12
10
  from ads.aqua.extension.base_handler import AquaAPIhandler
11
+ from ads.aqua.extension.errors import Errors
13
12
  from ads.aqua.modeldeployment import AquaDeploymentApp, MDInferenceResponse
14
13
  from ads.aqua.modeldeployment.entities import ModelParams
15
14
  from ads.config import COMPARTMENT_OCID, PROJECT_OCID
@@ -66,8 +65,8 @@ class AquaDeploymentHandler(AquaAPIhandler):
66
65
  """
67
66
  try:
68
67
  input_data = self.get_json_body()
69
- except Exception:
70
- raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT)
68
+ except Exception as ex:
69
+ raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT) from ex
71
70
 
72
71
  if not input_data:
73
72
  raise HTTPError(400, Errors.NO_INPUT_DATA)
@@ -100,6 +99,8 @@ class AquaDeploymentHandler(AquaAPIhandler):
100
99
  health_check_port = input_data.get("health_check_port")
101
100
  env_var = input_data.get("env_var")
102
101
  container_family = input_data.get("container_family")
102
+ ocpus = input_data.get("ocpus")
103
+ memory_in_gbs = input_data.get("memory_in_gbs")
103
104
 
104
105
  self.finish(
105
106
  AquaDeploymentApp().create(
@@ -119,6 +120,8 @@ class AquaDeploymentHandler(AquaAPIhandler):
119
120
  health_check_port=health_check_port,
120
121
  env_var=env_var,
121
122
  container_family=container_family,
123
+ ocpus=ocpus,
124
+ memory_in_gbs=memory_in_gbs,
122
125
  )
123
126
  )
124
127
 
@@ -153,9 +156,7 @@ class AquaDeploymentInferenceHandler(AquaAPIhandler):
153
156
  return False
154
157
  if not url.netloc:
155
158
  return False
156
- if not url.path.endswith("/predict"):
157
- return False
158
- return True
159
+ return url.path.endswith("/predict")
159
160
  except Exception:
160
161
  return False
161
162
 
@@ -170,8 +171,8 @@ class AquaDeploymentInferenceHandler(AquaAPIhandler):
170
171
  """
171
172
  try:
172
173
  input_data = self.get_json_body()
173
- except Exception:
174
- raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT)
174
+ except Exception as ex:
175
+ raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT) from ex
175
176
 
176
177
  if not input_data:
177
178
  raise HTTPError(400, Errors.NO_INPUT_DATA)
@@ -192,10 +193,10 @@ class AquaDeploymentInferenceHandler(AquaAPIhandler):
192
193
  )
193
194
  try:
194
195
  model_params_obj = ModelParams(**model_params)
195
- except:
196
+ except Exception as ex:
196
197
  raise HTTPError(
197
198
  400, Errors.INVALID_INPUT_DATA_FORMAT.format("model_params")
198
- )
199
+ ) from ex
199
200
 
200
201
  return self.finish(
201
202
  MDInferenceResponse(prompt, model_params_obj).get_model_deployment_response(
@@ -236,8 +237,8 @@ class AquaDeploymentParamsHandler(AquaAPIhandler):
236
237
  """
237
238
  try:
238
239
  input_data = self.get_json_body()
239
- except Exception:
240
- raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT)
240
+ except Exception as ex:
241
+ raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT) from ex
241
242
 
242
243
  if not input_data:
243
244
  raise HTTPError(400, Errors.NO_INPUT_DATA)
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env python
2
+
3
+ # Copyright (c) 2024 Oracle and/or its affiliates.
4
+ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
5
+
6
+ import json
7
+ from typing import List, Union
8
+
9
+ from ads.aqua.common.decorator import handle_exceptions
10
+ from ads.aqua.extension.aqua_ws_msg_handler import AquaWSMsgHandler
11
+ from ads.aqua.extension.models.ws_models import (
12
+ ListDeploymentResponse,
13
+ ModelDeploymentDetailsResponse,
14
+ RequestResponseType,
15
+ )
16
+ from ads.aqua.modeldeployment import AquaDeploymentApp
17
+ from ads.config import COMPARTMENT_OCID
18
+
19
+
20
+ class AquaDeploymentWSMsgHandler(AquaWSMsgHandler):
21
+ def __init__(self, message: Union[str, bytes]):
22
+ super().__init__(message)
23
+
24
+ @staticmethod
25
+ def get_message_types() -> List[RequestResponseType]:
26
+ return [
27
+ RequestResponseType.ListDeployments,
28
+ RequestResponseType.DeploymentDetails,
29
+ ]
30
+
31
+ @handle_exceptions
32
+ def process(self) -> Union[ListDeploymentResponse, ModelDeploymentDetailsResponse]:
33
+ request = json.loads(self.message)
34
+ if request.get("kind") == "ListDeployments":
35
+ deployment_list = AquaDeploymentApp().list(
36
+ compartment_id=request.get("compartment_id") or COMPARTMENT_OCID,
37
+ project_id=request.get("project_id"),
38
+ )
39
+ response = ListDeploymentResponse(
40
+ message_id=request.get("message_id"),
41
+ kind=RequestResponseType.ListDeployments,
42
+ data=deployment_list,
43
+ )
44
+ return response
45
+ elif request.get("kind") == "DeploymentDetails":
46
+ deployment_details = AquaDeploymentApp().get(
47
+ request.get("model_deployment_id")
48
+ )
49
+ response = ModelDeploymentDetailsResponse(
50
+ message_id=request.get("message_id"),
51
+ kind=RequestResponseType.DeploymentDetails,
52
+ data=deployment_details,
53
+ )
54
+ return response
@@ -1,5 +1,4 @@
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
 
@@ -8,3 +7,4 @@ class Errors(str):
8
7
  INVALID_INPUT_DATA_FORMAT = "Invalid format of input data."
9
8
  NO_INPUT_DATA = "No input data provided."
10
9
  MISSING_REQUIRED_PARAMETER = "Missing required parameter: '{}'"
10
+ MISSING_ONEOF_REQUIRED_PARAMETER = "Either '{}' or '{}' is required."
@@ -1,5 +1,4 @@
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
 
@@ -10,8 +9,8 @@ from tornado.web import HTTPError
10
9
  from ads.aqua.common.decorator import handle_exceptions
11
10
  from ads.aqua.evaluation import AquaEvaluationApp
12
11
  from ads.aqua.evaluation.entities import CreateAquaEvaluationDetails
13
- from ads.aqua.extension.errors import Errors
14
12
  from ads.aqua.extension.base_handler import AquaAPIhandler
13
+ from ads.aqua.extension.errors import Errors
15
14
  from ads.aqua.extension.utils import validate_function_parameters
16
15
  from ads.config import COMPARTMENT_OCID
17
16
 
@@ -41,8 +40,8 @@ class AquaEvaluationHandler(AquaAPIhandler):
41
40
  """
42
41
  try:
43
42
  input_data = self.get_json_body()
44
- except Exception:
45
- raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT)
43
+ except Exception as ex:
44
+ raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT) from ex
46
45
 
47
46
  if not input_data:
48
47
  raise HTTPError(400, Errors.NO_INPUT_DATA)
@@ -77,9 +76,7 @@ class AquaEvaluationHandler(AquaAPIhandler):
77
76
  def list(self):
78
77
  """List Aqua models."""
79
78
  compartment_id = self.get_argument("compartment_id", default=COMPARTMENT_OCID)
80
- # project_id is no needed.
81
- project_id = self.get_argument("project_id", default=None)
82
- return self.finish(AquaEvaluationApp().list(compartment_id, project_id))
79
+ return self.finish(AquaEvaluationApp().list(compartment_id))
83
80
 
84
81
  def get_default_metrics(self):
85
82
  """Lists supported metrics for evaluation."""
@@ -1,18 +1,16 @@
1
1
  #!/usr/bin/env python
2
- # -*- coding: utf-8 -*--
3
2
 
4
3
  # Copyright (c) 2024 Oracle and/or its affiliates.
5
4
  # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
6
5
 
6
+ import json
7
7
  from typing import List, Union
8
8
 
9
- from tornado.web import HTTPError
10
-
11
9
  from ads.aqua.common.decorator import handle_exceptions
12
10
  from ads.aqua.evaluation import AquaEvaluationApp
13
11
  from ads.aqua.extension.aqua_ws_msg_handler import AquaWSMsgHandler
14
12
  from ads.aqua.extension.models.ws_models import (
15
- ListEvaluationsRequest,
13
+ EvaluationDetailsResponse,
16
14
  ListEvaluationsResponse,
17
15
  RequestResponseType,
18
16
  )
@@ -22,22 +20,42 @@ from ads.config import COMPARTMENT_OCID
22
20
  class AquaEvaluationWSMsgHandler(AquaWSMsgHandler):
23
21
  @staticmethod
24
22
  def get_message_types() -> List[RequestResponseType]:
25
- return [RequestResponseType.ListEvaluations]
23
+ return [
24
+ RequestResponseType.ListEvaluations,
25
+ RequestResponseType.EvaluationDetails,
26
+ ]
26
27
 
27
28
  def __init__(self, message: Union[str, bytes]):
28
29
  super().__init__(message)
29
30
 
30
31
  @handle_exceptions
31
- def process(self) -> ListEvaluationsResponse:
32
- list_eval_request = ListEvaluationsRequest.from_json(self.message)
32
+ def process(self) -> Union[ListEvaluationsResponse, EvaluationDetailsResponse]:
33
+ request = json.loads(self.message)
34
+ if request["kind"] == "ListEvaluations":
35
+ return self.list_evaluations(request)
36
+ if request["kind"] == "EvaluationDetails":
37
+ return self.evaluation_details(request)
33
38
 
39
+ @staticmethod
40
+ def list_evaluations(request) -> ListEvaluationsResponse:
34
41
  eval_list = AquaEvaluationApp().list(
35
- list_eval_request.compartment_id or COMPARTMENT_OCID,
36
- list_eval_request.project_id,
42
+ request.get("compartment_id") or COMPARTMENT_OCID
37
43
  )
38
44
  response = ListEvaluationsResponse(
39
- message_id=list_eval_request.message_id,
45
+ message_id=request["message_id"],
40
46
  kind=RequestResponseType.ListEvaluations,
41
47
  data=eval_list,
42
48
  )
43
49
  return response
50
+
51
+ @staticmethod
52
+ def evaluation_details(request) -> EvaluationDetailsResponse:
53
+ evaluation_details = AquaEvaluationApp().get(
54
+ eval_id=request.get("evaluation_id")
55
+ )
56
+ response = EvaluationDetailsResponse(
57
+ message_id=request.get("message_id"),
58
+ kind=RequestResponseType.EvaluationDetails,
59
+ data=evaluation_details,
60
+ )
61
+ return response
@@ -1,27 +1,50 @@
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
- import re
7
- from typing import Optional
8
5
  from urllib.parse import urlparse
9
6
 
10
7
  from tornado.web import HTTPError
11
- from ads.aqua.extension.errors import Errors
8
+
12
9
  from ads.aqua.common.decorator import handle_exceptions
10
+ from ads.aqua.common.errors import AquaValueError
13
11
  from ads.aqua.extension.base_handler import AquaAPIhandler
12
+ from ads.aqua.extension.errors import Errors
14
13
  from ads.aqua.model import AquaModelApp
14
+ from ads.aqua.ui import ModelFormat
15
15
 
16
16
 
17
17
  class AquaModelHandler(AquaAPIhandler):
18
18
  """Handler for Aqua Model REST APIs."""
19
19
 
20
20
  @handle_exceptions
21
- def get(self, model_id=""):
21
+ def get(
22
+ self,
23
+ model_id="",
24
+ ):
22
25
  """Handle GET request."""
23
- if not model_id:
26
+ url_parse = urlparse(self.request.path)
27
+ paths = url_parse.path.strip("/")
28
+ if paths.startswith("aqua/model/files"):
29
+ os_path = self.get_argument("os_path")
30
+ if not os_path:
31
+ raise HTTPError(
32
+ 400, Errors.MISSING_REQUIRED_PARAMETER.format("os_path")
33
+ )
34
+ model_format = self.get_argument("model_format")
35
+ if not model_format:
36
+ raise HTTPError(
37
+ 400, Errors.MISSING_REQUIRED_PARAMETER.format("model_format")
38
+ )
39
+ try:
40
+ model_format = ModelFormat(model_format.upper())
41
+ except ValueError:
42
+ raise AquaValueError(f"Invalid model format: {model_format}")
43
+ else:
44
+ return self.finish(AquaModelApp.get_model_files(os_path, model_format))
45
+ elif not model_id:
24
46
  return self.list()
47
+
25
48
  return self.read(model_id)
26
49
 
27
50
  def read(self, model_id):
@@ -81,6 +104,7 @@ class AquaModelHandler(AquaAPIhandler):
81
104
  finetuning_container = input_data.get("finetuning_container")
82
105
  compartment_id = input_data.get("compartment_id")
83
106
  project_id = input_data.get("project_id")
107
+ model_file = input_data.get("model_file")
84
108
 
85
109
  return self.finish(
86
110
  AquaModelApp().register(
@@ -90,6 +114,7 @@ class AquaModelHandler(AquaAPIhandler):
90
114
  finetuning_container=finetuning_container,
91
115
  compartment_id=compartment_id,
92
116
  project_id=project_id,
117
+ model_file=model_file,
93
118
  )
94
119
  )
95
120
 
@@ -7,15 +7,22 @@
7
7
  from dataclasses import dataclass
8
8
  from typing import List, Optional
9
9
 
10
- from ads.aqua.evaluation.entities import AquaEvaluationSummary
11
- from ads.aqua.model.entities import AquaModelSummary
10
+ from ads.aqua.evaluation.entities import AquaEvaluationSummary, AquaEvaluationDetail
11
+ from ads.aqua.model.entities import AquaModelSummary, AquaModel
12
+ from ads.aqua.modeldeployment.entities import AquaDeployment, AquaDeploymentDetail
12
13
  from ads.common.extended_enum import ExtendedEnumMeta
13
14
  from ads.common.serializer import DataClassSerializable
14
15
 
15
16
 
16
17
  class RequestResponseType(str, metaclass=ExtendedEnumMeta):
17
18
  ListEvaluations = "ListEvaluations"
19
+ EvaluationDetails = "EvaluationDetails"
20
+ ListDeployments = "ListDeployments"
21
+ DeploymentDetails = "DeploymentDetails"
18
22
  ListModels = "ListModels"
23
+ ModelDetails = "ModelDetails"
24
+ AdsVersion = "AdsVersion"
25
+ CompatibilityCheck = "CompatibilityCheck"
19
26
  Error = "Error"
20
27
 
21
28
 
@@ -23,7 +30,7 @@ class RequestResponseType(str, metaclass=ExtendedEnumMeta):
23
30
  class BaseResponse(DataClassSerializable):
24
31
  message_id: str
25
32
  kind: RequestResponseType
26
- data: object
33
+ data: Optional[object]
27
34
 
28
35
 
29
36
  @dataclass
@@ -40,9 +47,37 @@ class ListEvaluationsRequest(BaseRequest):
40
47
  kind = RequestResponseType.ListEvaluations
41
48
 
42
49
 
50
+ @dataclass
51
+ class EvaluationDetailsRequest(BaseRequest):
52
+ kind = RequestResponseType.EvaluationDetails
53
+ evaluation_id: str
54
+
55
+
43
56
  @dataclass
44
57
  class ListModelsRequest(BaseRequest):
45
58
  compartment_id: Optional[str] = None
59
+ project_id: Optional[str] = None
60
+ model_type: Optional[str] = None
61
+ kind = RequestResponseType.ListDeployments
62
+
63
+
64
+ @dataclass
65
+ class ModelDetailsRequest(BaseRequest):
66
+ kind = RequestResponseType.ModelDetails
67
+ model_id: str
68
+
69
+
70
+ @dataclass
71
+ class ListDeploymentRequest(BaseRequest):
72
+ compartment_id: str
73
+ project_id: Optional[str] = None
74
+ kind = RequestResponseType.ListDeployments
75
+
76
+
77
+ @dataclass
78
+ class DeploymentDetailsRequest(BaseRequest):
79
+ model_deployment_id: str
80
+ kind = RequestResponseType.DeploymentDetails
46
81
 
47
82
 
48
83
  @dataclass
@@ -50,11 +85,51 @@ class ListEvaluationsResponse(BaseResponse):
50
85
  data: List[AquaEvaluationSummary]
51
86
 
52
87
 
88
+ @dataclass
89
+ class EvaluationDetailsResponse(BaseResponse):
90
+ data: AquaEvaluationDetail
91
+
92
+
93
+ @dataclass
94
+ class ListDeploymentResponse(BaseResponse):
95
+ data: List[AquaDeployment]
96
+
97
+
98
+ @dataclass
99
+ class ModelDeploymentDetailsResponse(BaseResponse):
100
+ data: AquaDeploymentDetail
101
+
102
+
53
103
  @dataclass
54
104
  class ListModelsResponse(BaseResponse):
55
105
  data: List[AquaModelSummary]
56
106
 
57
107
 
108
+ @dataclass
109
+ class ModelDetailsResponse(BaseResponse):
110
+ data: AquaModel
111
+
112
+
113
+ @dataclass
114
+ class AdsVersionRequest(BaseRequest):
115
+ kind: RequestResponseType.AdsVersion
116
+
117
+
118
+ @dataclass
119
+ class AdsVersionResponse(BaseResponse):
120
+ data: str
121
+
122
+
123
+ @dataclass
124
+ class CompatibilityCheckRequest(BaseRequest):
125
+ kind: RequestResponseType.CompatibilityCheck
126
+
127
+
128
+ @dataclass
129
+ class CompatibilityCheckResponse(BaseResponse):
130
+ data: object
131
+
132
+
58
133
  @dataclass
59
134
  class AquaWsError(DataClassSerializable):
60
135
  status: str
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env python
2
+
3
+ # Copyright (c) 2024 Oracle and/or its affiliates.
4
+ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
5
+
6
+ import json
7
+ from typing import List, Union
8
+
9
+ from ads.aqua.common.decorator import handle_exceptions
10
+ from ads.aqua.extension.aqua_ws_msg_handler import AquaWSMsgHandler
11
+ from ads.aqua.extension.models.ws_models import (
12
+ ListModelsResponse,
13
+ ModelDetailsResponse,
14
+ RequestResponseType,
15
+ )
16
+ from ads.aqua.model import AquaModelApp
17
+
18
+
19
+ class AquaModelWSMsgHandler(AquaWSMsgHandler):
20
+ def __init__(self, message: Union[str, bytes]):
21
+ super().__init__(message)
22
+
23
+ @staticmethod
24
+ def get_message_types() -> List[RequestResponseType]:
25
+ return [RequestResponseType.ListModels, RequestResponseType.ModelDetails]
26
+
27
+ @handle_exceptions
28
+ def process(self) -> Union[ListModelsResponse, ModelDetailsResponse]:
29
+ request = json.loads(self.message)
30
+ if request.get("kind") == "ListModels":
31
+ models_list = AquaModelApp().list(
32
+ compartment_id=request.get("compartment_id"),
33
+ project_id=request.get("project_id"),
34
+ model_type=request.get("model_type"),
35
+ )
36
+ response = ListModelsResponse(
37
+ message_id=request.get("message_id"),
38
+ kind=RequestResponseType.ListModels,
39
+ data=models_list,
40
+ )
41
+ return response
42
+ elif request.get("kind") == "ModelDetails":
43
+ model_id = request.get("model_id")
44
+ response = AquaModelApp().get(model_id)
45
+ return ModelDetailsResponse(
46
+ message_id=request.get("message_id"),
47
+ kind=RequestResponseType.ModelDetails,
48
+ data=response,
49
+ )
@@ -14,6 +14,8 @@ from tornado.websocket import WebSocketHandler
14
14
 
15
15
  from ads.aqua import logger
16
16
  from ads.aqua.extension.aqua_ws_msg_handler import AquaWSMsgHandler
17
+ from ads.aqua.extension.common_ws_msg_handler import AquaCommonWsMsgHandler
18
+ from ads.aqua.extension.deployment_ws_msg_handler import AquaDeploymentWSMsgHandler
17
19
  from ads.aqua.extension.evaluation_ws_msg_handler import AquaEvaluationWSMsgHandler
18
20
  from ads.aqua.extension.models.ws_models import (
19
21
  AquaWsError,
@@ -22,6 +24,7 @@ from ads.aqua.extension.models.ws_models import (
22
24
  ErrorResponse,
23
25
  RequestResponseType,
24
26
  )
27
+ from ads.aqua.extension.models_ws_msg_handler import AquaModelWSMsgHandler
25
28
 
26
29
  MAX_WORKERS = 20
27
30
 
@@ -43,7 +46,10 @@ def get_aqua_internal_error_response(message_id: str) -> ErrorResponse:
43
46
  class AquaUIWebSocketHandler(WebSocketHandler):
44
47
  """Handler for Aqua Websocket."""
45
48
 
46
- _handlers_: List[Type[AquaWSMsgHandler]] = [AquaEvaluationWSMsgHandler]
49
+ _handlers_: List[Type[AquaWSMsgHandler]] = [AquaEvaluationWSMsgHandler,
50
+ AquaDeploymentWSMsgHandler,
51
+ AquaModelWSMsgHandler,
52
+ AquaCommonWsMsgHandler]
47
53
 
48
54
  thread_pool: ThreadPoolExecutor
49
55
 
@@ -1,5 +1,4 @@
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
 
@@ -9,19 +8,20 @@ aqua.model.entities
9
8
 
10
9
  This module contains dataclasses for Aqua Model.
11
10
  """
11
+
12
12
  import re
13
13
  from dataclasses import InitVar, dataclass, field
14
14
  from typing import List, Optional
15
15
 
16
16
  import oci
17
-
18
17
  from ads.aqua import logger
19
18
  from ads.aqua.app import CLIBuilderMixin
20
19
  from ads.aqua.common import utils
21
- from ads.aqua.constants import UNKNOWN_VALUE
20
+ from ads.aqua.constants import LIFECYCLE_DETAILS_MISSING_JOBRUN, UNKNOWN_VALUE
22
21
  from ads.aqua.data import AquaResourceIdentifier
23
22
  from ads.aqua.model.enums import FineTuningDefinedMetadata
24
23
  from ads.aqua.training.exceptions import exit_code_dict
24
+ from ads.aqua.ui import ModelFormat
25
25
  from ads.common.serializer import DataClassSerializable
26
26
  from ads.common.utils import get_log_links
27
27
  from ads.model.datascience_model import DataScienceModel
@@ -41,6 +41,12 @@ class AquaFineTuneValidation(DataClassSerializable):
41
41
  value: str = ""
42
42
 
43
43
 
44
+ class ModelValidationResult:
45
+ model_file: Optional[str] = None
46
+ model_format: ModelFormat = None
47
+ telemetry_model_name: str = None
48
+
49
+
44
50
  @dataclass(repr=False)
45
51
  class AquaFineTuningMetric(DataClassSerializable):
46
52
  name: str = field(default_factory=str)
@@ -76,6 +82,9 @@ class AquaModelSummary(DataClassSerializable):
76
82
  ready_to_deploy: bool = True
77
83
  ready_to_finetune: bool = False
78
84
  ready_to_import: bool = False
85
+ nvidia_gpu_supported: bool = False
86
+ arm_cpu_supported: bool = False
87
+ model_format: ModelFormat = ModelFormat.UNKNOWN
79
88
 
80
89
 
81
90
  @dataclass(repr=False)
@@ -147,14 +156,14 @@ class AquaEvalFTCommon(DataClassSerializable):
147
156
  try:
148
157
  log = utils.query_resource(log_id, return_all=False)
149
158
  log_name = log.display_name if log else ""
150
- except:
159
+ except Exception:
151
160
  pass
152
161
 
153
162
  if loggroup_id:
154
163
  try:
155
164
  loggroup = utils.query_resource(loggroup_id, return_all=False)
156
165
  loggroup_name = loggroup.display_name if loggroup else ""
157
- except:
166
+ except Exception:
158
167
  pass
159
168
 
160
169
  experiment_id, experiment_name = utils._get_experiment_info(model)
@@ -168,9 +177,7 @@ class AquaEvalFTCommon(DataClassSerializable):
168
177
  )
169
178
  self.job = utils._build_job_identifier(job_run_details=jobrun, region=region)
170
179
  self.lifecycle_details = (
171
- utils.LIFECYCLE_DETAILS_MISSING_JOBRUN
172
- if not jobrun
173
- else jobrun.lifecycle_details
180
+ LIFECYCLE_DETAILS_MISSING_JOBRUN if not jobrun else jobrun.lifecycle_details
174
181
  )
175
182
 
176
183
 
@@ -247,7 +254,7 @@ class AquaFineTuneModel(AquaModel, AquaEvalFTCommon, DataClassSerializable):
247
254
  lifecycle_details,
248
255
  )
249
256
  message = f"{exception.reason} (exit code {exit_code})"
250
- except:
257
+ except Exception:
251
258
  pass
252
259
 
253
260
  return message
@@ -261,6 +268,7 @@ class ImportModelDetails(CLIBuilderMixin):
261
268
  finetuning_container: Optional[str] = None
262
269
  compartment_id: Optional[str] = None
263
270
  project_id: Optional[str] = None
271
+ model_file: Optional[str] = None
264
272
 
265
273
  def __post_init__(self):
266
274
  self._command = "model register"