oracle-ads 2.12.8__py3-none-any.whl → 2.12.10__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 (82) hide show
  1. ads/aqua/__init__.py +4 -3
  2. ads/aqua/app.py +40 -18
  3. ads/aqua/client/__init__.py +3 -0
  4. ads/aqua/client/client.py +799 -0
  5. ads/aqua/common/enums.py +3 -0
  6. ads/aqua/common/utils.py +62 -2
  7. ads/aqua/data.py +2 -19
  8. ads/aqua/evaluation/entities.py +6 -0
  9. ads/aqua/evaluation/evaluation.py +45 -15
  10. ads/aqua/extension/aqua_ws_msg_handler.py +14 -7
  11. ads/aqua/extension/base_handler.py +12 -9
  12. ads/aqua/extension/deployment_handler.py +8 -4
  13. ads/aqua/extension/finetune_handler.py +8 -14
  14. ads/aqua/extension/model_handler.py +30 -6
  15. ads/aqua/extension/ui_handler.py +13 -1
  16. ads/aqua/finetuning/constants.py +5 -2
  17. ads/aqua/finetuning/entities.py +73 -17
  18. ads/aqua/finetuning/finetuning.py +110 -82
  19. ads/aqua/model/entities.py +5 -1
  20. ads/aqua/model/model.py +230 -104
  21. ads/aqua/modeldeployment/deployment.py +35 -11
  22. ads/aqua/modeldeployment/entities.py +7 -4
  23. ads/aqua/ui.py +24 -2
  24. ads/cli.py +16 -8
  25. ads/common/auth.py +9 -9
  26. ads/llm/autogen/__init__.py +2 -0
  27. ads/llm/autogen/constants.py +15 -0
  28. ads/llm/autogen/reports/__init__.py +2 -0
  29. ads/llm/autogen/reports/base.py +67 -0
  30. ads/llm/autogen/reports/data.py +103 -0
  31. ads/llm/autogen/reports/session.py +526 -0
  32. ads/llm/autogen/reports/templates/chat_box.html +13 -0
  33. ads/llm/autogen/reports/templates/chat_box_lt.html +5 -0
  34. ads/llm/autogen/reports/templates/chat_box_rt.html +6 -0
  35. ads/llm/autogen/reports/utils.py +56 -0
  36. ads/llm/autogen/v02/__init__.py +4 -0
  37. ads/llm/autogen/{client_v02.py → v02/client.py} +23 -10
  38. ads/llm/autogen/v02/log_handlers/__init__.py +2 -0
  39. ads/llm/autogen/v02/log_handlers/oci_file_handler.py +83 -0
  40. ads/llm/autogen/v02/loggers/__init__.py +6 -0
  41. ads/llm/autogen/v02/loggers/metric_logger.py +320 -0
  42. ads/llm/autogen/v02/loggers/session_logger.py +580 -0
  43. ads/llm/autogen/v02/loggers/utils.py +86 -0
  44. ads/llm/autogen/v02/runtime_logging.py +163 -0
  45. ads/llm/guardrails/base.py +6 -5
  46. ads/llm/langchain/plugins/chat_models/oci_data_science.py +46 -20
  47. ads/llm/langchain/plugins/llms/oci_data_science_model_deployment_endpoint.py +38 -11
  48. ads/model/__init__.py +11 -13
  49. ads/model/artifact.py +47 -8
  50. ads/model/extractor/embedding_onnx_extractor.py +80 -0
  51. ads/model/framework/embedding_onnx_model.py +438 -0
  52. ads/model/generic_model.py +26 -24
  53. ads/model/model_metadata.py +8 -7
  54. ads/opctl/config/merger.py +13 -14
  55. ads/opctl/operator/common/operator_config.py +4 -4
  56. ads/opctl/operator/lowcode/common/transformations.py +50 -8
  57. ads/opctl/operator/lowcode/common/utils.py +22 -6
  58. ads/opctl/operator/lowcode/forecast/__main__.py +10 -0
  59. ads/opctl/operator/lowcode/forecast/const.py +3 -0
  60. ads/opctl/operator/lowcode/forecast/model/arima.py +19 -13
  61. ads/opctl/operator/lowcode/forecast/model/automlx.py +129 -36
  62. ads/opctl/operator/lowcode/forecast/model/autots.py +1 -0
  63. ads/opctl/operator/lowcode/forecast/model/base_model.py +58 -17
  64. ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py +1 -1
  65. ads/opctl/operator/lowcode/forecast/model/neuralprophet.py +10 -3
  66. ads/opctl/operator/lowcode/forecast/model/prophet.py +25 -18
  67. ads/opctl/operator/lowcode/forecast/model_evaluator.py +3 -2
  68. ads/opctl/operator/lowcode/forecast/operator_config.py +31 -0
  69. ads/opctl/operator/lowcode/forecast/schema.yaml +76 -0
  70. ads/opctl/operator/lowcode/forecast/utils.py +8 -6
  71. ads/opctl/operator/lowcode/forecast/whatifserve/__init__.py +7 -0
  72. ads/opctl/operator/lowcode/forecast/whatifserve/deployment_manager.py +233 -0
  73. ads/opctl/operator/lowcode/forecast/whatifserve/score.py +238 -0
  74. ads/telemetry/base.py +18 -11
  75. ads/telemetry/client.py +33 -13
  76. ads/templates/schemas/openapi.json +1740 -0
  77. ads/templates/score_embedding_onnx.jinja2 +202 -0
  78. {oracle_ads-2.12.8.dist-info → oracle_ads-2.12.10.dist-info}/METADATA +11 -10
  79. {oracle_ads-2.12.8.dist-info → oracle_ads-2.12.10.dist-info}/RECORD +82 -56
  80. {oracle_ads-2.12.8.dist-info → oracle_ads-2.12.10.dist-info}/LICENSE.txt +0 -0
  81. {oracle_ads-2.12.8.dist-info → oracle_ads-2.12.10.dist-info}/WHEEL +0 -0
  82. {oracle_ads-2.12.8.dist-info → oracle_ads-2.12.10.dist-info}/entry_points.txt +0 -0
ads/aqua/common/enums.py CHANGED
@@ -52,6 +52,9 @@ class InferenceContainerTypeFamily(str, metaclass=ExtendedEnumMeta):
52
52
  AQUA_VLLM_CONTAINER_FAMILY = "odsc-vllm-serving"
53
53
  AQUA_TGI_CONTAINER_FAMILY = "odsc-tgi-serving"
54
54
  AQUA_LLAMA_CPP_CONTAINER_FAMILY = "odsc-llama-cpp-serving"
55
+
56
+
57
+ class CustomInferenceContainerTypeFamily(str, metaclass=ExtendedEnumMeta):
55
58
  AQUA_TEI_CONTAINER_FAMILY = "odsc-tei-serving"
56
59
 
57
60
 
ads/aqua/common/utils.py CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python
2
- # Copyright (c) 2024 Oracle and/or its affiliates.
2
+ # Copyright (c) 2024, 2025 Oracle and/or its affiliates.
3
3
  # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
4
4
  """AQUA utils and constants."""
5
5
 
@@ -11,6 +11,7 @@ import os
11
11
  import random
12
12
  import re
13
13
  import shlex
14
+ import shutil
14
15
  import subprocess
15
16
  from datetime import datetime, timedelta
16
17
  from functools import wraps
@@ -21,6 +22,8 @@ from typing import List, Union
21
22
  import fsspec
22
23
  import oci
23
24
  from cachetools import TTLCache, cached
25
+ from huggingface_hub.constants import HF_HUB_CACHE
26
+ from huggingface_hub.file_download import repo_folder_name
24
27
  from huggingface_hub.hf_api import HfApi, ModelInfo
25
28
  from huggingface_hub.utils import (
26
29
  GatedRepoError,
@@ -30,6 +33,7 @@ from huggingface_hub.utils import (
30
33
  )
31
34
  from oci.data_science.models import JobRun, Model
32
35
  from oci.object_storage.models import ObjectSummary
36
+ from pydantic import ValidationError
33
37
 
34
38
  from ads.aqua.common.enums import (
35
39
  InferenceContainerParamType,
@@ -788,7 +792,9 @@ def get_ocid_substring(ocid: str, key_len: int) -> str:
788
792
  return ocid[-key_len:] if ocid and len(ocid) > key_len else ""
789
793
 
790
794
 
791
- def upload_folder(os_path: str, local_dir: str, model_name: str, exclude_pattern: str = None) -> str:
795
+ def upload_folder(
796
+ os_path: str, local_dir: str, model_name: str, exclude_pattern: str = None
797
+ ) -> str:
792
798
  """Upload the local folder to the object storage
793
799
 
794
800
  Args:
@@ -818,6 +824,48 @@ def upload_folder(os_path: str, local_dir: str, model_name: str, exclude_pattern
818
824
  return f"oci://{os_details.bucket}@{os_details.namespace}" + "/" + object_path
819
825
 
820
826
 
827
+ def cleanup_local_hf_model_artifact(
828
+ model_name: str,
829
+ local_dir: str = None,
830
+ ):
831
+ """
832
+ Helper function that deletes local artifacts downloaded from Hugging Face to free up disk space.
833
+ Parameters
834
+ ----------
835
+ model_name (str): Name of the huggingface model
836
+ local_dir (str): Local directory where the object is downloaded
837
+
838
+ """
839
+ if local_dir and os.path.exists(local_dir):
840
+ model_dir = os.path.join(local_dir, model_name)
841
+ model_dir = (
842
+ os.path.dirname(model_dir)
843
+ if "/" in model_name or os.sep in model_name
844
+ else model_dir
845
+ )
846
+ shutil.rmtree(model_dir, ignore_errors=True)
847
+ if os.path.exists(model_dir):
848
+ logger.debug(
849
+ f"Could not delete local model artifact directory: {model_dir}"
850
+ )
851
+ else:
852
+ logger.debug(f"Deleted local model artifact directory: {model_dir}.")
853
+
854
+ hf_local_path = os.path.join(
855
+ HF_HUB_CACHE, repo_folder_name(repo_id=model_name, repo_type="model")
856
+ )
857
+ shutil.rmtree(hf_local_path, ignore_errors=True)
858
+
859
+ if os.path.exists(hf_local_path):
860
+ logger.debug(
861
+ f"Could not clear the local Hugging Face cache directory {hf_local_path} for the model {model_name}."
862
+ )
863
+ else:
864
+ logger.debug(
865
+ f"Cleared contents of local Hugging Face cache directory {hf_local_path} for the model {model_name}."
866
+ )
867
+
868
+
821
869
  def is_service_managed_container(container):
822
870
  return container and container.startswith(SERVICE_MANAGED_CONTAINER_URI_SCHEME)
823
871
 
@@ -1159,3 +1207,15 @@ def validate_cmd_var(cmd_var: List[str], overrides: List[str]) -> List[str]:
1159
1207
 
1160
1208
  combined_cmd_var = cmd_var + overrides
1161
1209
  return combined_cmd_var
1210
+
1211
+
1212
+ def build_pydantic_error_message(ex: ValidationError):
1213
+ """Added to handle error messages from pydantic model validator.
1214
+ Combine both loc and msg for errors where loc (field) is present in error details, else only build error
1215
+ message using msg field."""
1216
+
1217
+ return {
1218
+ ".".join(map(str, e["loc"])): e["msg"]
1219
+ for e in ex.errors()
1220
+ if "loc" in e and e["loc"]
1221
+ } or "; ".join(e["msg"] for e in ex.errors())
ads/aqua/data.py CHANGED
@@ -1,9 +1,8 @@
1
1
  #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
- # Copyright (c) 2024 Oracle and/or its affiliates.
2
+ # Copyright (c) 2024, 2025 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
- from dataclasses import dataclass, field
5
+ from dataclasses import dataclass
7
6
 
8
7
  from ads.common.serializer import DataClassSerializable
9
8
 
@@ -13,19 +12,3 @@ class AquaResourceIdentifier(DataClassSerializable):
13
12
  id: str = ""
14
13
  name: str = ""
15
14
  url: str = ""
16
-
17
-
18
- @dataclass(repr=False)
19
- class AquaJobSummary(DataClassSerializable):
20
- """Represents an Aqua job summary."""
21
-
22
- id: str
23
- name: str
24
- console_url: str
25
- lifecycle_state: str
26
- lifecycle_details: str
27
- time_created: str
28
- tags: dict
29
- experiment: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
30
- source: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
31
- job: AquaResourceIdentifier = field(default_factory=AquaResourceIdentifier)
@@ -64,6 +64,10 @@ class CreateAquaEvaluationDetails(Serializable):
64
64
  The metrics for the evaluation.
65
65
  force_overwrite: (bool, optional). Defaults to `False`.
66
66
  Whether to force overwrite the existing file in object storage.
67
+ freeform_tags: (dict, optional)
68
+ Freeform tags for the evaluation model
69
+ defined_tags: (dict, optional)
70
+ Defined tags for the evaluation model
67
71
  """
68
72
 
69
73
  evaluation_source_id: str
@@ -85,6 +89,8 @@ class CreateAquaEvaluationDetails(Serializable):
85
89
  log_id: Optional[str] = None
86
90
  metrics: Optional[List[Dict[str, Any]]] = None
87
91
  force_overwrite: Optional[bool] = False
92
+ freeform_tags: Optional[dict] = None
93
+ defined_tags: Optional[dict] = None
88
94
 
89
95
  class Config:
90
96
  extra = "ignore"
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python
2
- # Copyright (c) 2024 Oracle and/or its affiliates.
2
+ # Copyright (c) 2024, 2025 Oracle and/or its affiliates.
3
3
  # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
4
4
  import base64
5
5
  import json
@@ -199,11 +199,11 @@ class AquaEvaluationApp(AquaApp):
199
199
  eval_inference_configuration = (
200
200
  container.spec.evaluation_configuration
201
201
  )
202
- except Exception:
202
+ except Exception as ex:
203
203
  logger.debug(
204
204
  f"Could not load inference config details for the evaluation source id: "
205
205
  f"{create_aqua_evaluation_details.evaluation_source_id}. Please check if the container"
206
- f" runtime has the correct SMC image information."
206
+ f" runtime has the correct SMC image information.\nError: {str(ex)}"
207
207
  )
208
208
  elif (
209
209
  DataScienceResource.MODEL
@@ -289,7 +289,7 @@ class AquaEvaluationApp(AquaApp):
289
289
  f"Invalid experiment name. Please provide an experiment with `{Tags.AQUA_EVALUATION}` in tags."
290
290
  )
291
291
  except Exception:
292
- logger.debug(
292
+ logger.info(
293
293
  f"Model version set {experiment_model_version_set_name} doesn't exist. "
294
294
  "Creating new model version set."
295
295
  )
@@ -297,6 +297,10 @@ class AquaEvaluationApp(AquaApp):
297
297
  evaluation_mvs_freeform_tags = {
298
298
  Tags.AQUA_EVALUATION: Tags.AQUA_EVALUATION,
299
299
  }
300
+ evaluation_mvs_freeform_tags = {
301
+ **evaluation_mvs_freeform_tags,
302
+ **(create_aqua_evaluation_details.freeform_tags or {}),
303
+ }
300
304
 
301
305
  model_version_set = (
302
306
  ModelVersionSet()
@@ -307,6 +311,9 @@ class AquaEvaluationApp(AquaApp):
307
311
  create_aqua_evaluation_details.experiment_description
308
312
  )
309
313
  .with_freeform_tags(**evaluation_mvs_freeform_tags)
314
+ .with_defined_tags(
315
+ **(create_aqua_evaluation_details.defined_tags or {})
316
+ )
310
317
  # TODO: decide what parameters will be needed
311
318
  .create(**kwargs)
312
319
  )
@@ -369,6 +376,10 @@ class AquaEvaluationApp(AquaApp):
369
376
  Tags.AQUA_EVALUATION: Tags.AQUA_EVALUATION,
370
377
  Tags.AQUA_EVALUATION_MODEL_ID: evaluation_model.id,
371
378
  }
379
+ evaluation_job_freeform_tags = {
380
+ **evaluation_job_freeform_tags,
381
+ **(create_aqua_evaluation_details.freeform_tags or {}),
382
+ }
372
383
 
373
384
  evaluation_job = Job(name=evaluation_model.display_name).with_infrastructure(
374
385
  DataScienceJob()
@@ -379,6 +390,7 @@ class AquaEvaluationApp(AquaApp):
379
390
  .with_shape_name(create_aqua_evaluation_details.shape_name)
380
391
  .with_block_storage_size(create_aqua_evaluation_details.block_storage_size)
381
392
  .with_freeform_tag(**evaluation_job_freeform_tags)
393
+ .with_defined_tag(**(create_aqua_evaluation_details.defined_tags or {}))
382
394
  )
383
395
  if (
384
396
  create_aqua_evaluation_details.memory_in_gbs
@@ -425,6 +437,7 @@ class AquaEvaluationApp(AquaApp):
425
437
  evaluation_job_run = evaluation_job.run(
426
438
  name=evaluation_model.display_name,
427
439
  freeform_tags=evaluation_job_freeform_tags,
440
+ defined_tags=(create_aqua_evaluation_details.defined_tags or {}),
428
441
  wait=False,
429
442
  )
430
443
  logger.debug(
@@ -444,13 +457,20 @@ class AquaEvaluationApp(AquaApp):
444
457
  for metadata in evaluation_model_custom_metadata.to_dict()["data"]
445
458
  ]
446
459
 
460
+ evaluation_model_freeform_tags = {
461
+ Tags.AQUA_EVALUATION: Tags.AQUA_EVALUATION,
462
+ **(create_aqua_evaluation_details.freeform_tags or {}),
463
+ }
464
+ evaluation_model_defined_tags = (
465
+ create_aqua_evaluation_details.defined_tags or {}
466
+ )
467
+
447
468
  self.ds_client.update_model(
448
469
  model_id=evaluation_model.id,
449
470
  update_model_details=UpdateModelDetails(
450
471
  custom_metadata_list=updated_custom_metadata_list,
451
- freeform_tags={
452
- Tags.AQUA_EVALUATION: Tags.AQUA_EVALUATION,
453
- },
472
+ freeform_tags=evaluation_model_freeform_tags,
473
+ defined_tags=evaluation_model_defined_tags,
454
474
  ),
455
475
  )
456
476
 
@@ -524,6 +544,8 @@ class AquaEvaluationApp(AquaApp):
524
544
  "evaluation_job_id": evaluation_job.id,
525
545
  "evaluation_source": create_aqua_evaluation_details.evaluation_source_id,
526
546
  "evaluation_experiment_id": experiment_model_version_set_id,
547
+ **evaluation_model_freeform_tags,
548
+ **evaluation_model_defined_tags,
527
549
  },
528
550
  parameters=AquaEvalParams(),
529
551
  )
@@ -689,21 +711,27 @@ class AquaEvaluationApp(AquaApp):
689
711
  try:
690
712
  log = utils.query_resource(log_id, return_all=False)
691
713
  log_name = log.display_name if log else ""
692
- except Exception:
714
+ except Exception as ex:
715
+ logger.debug(f"Failed to get associated log name. Error: {ex}")
693
716
  pass
694
717
 
695
718
  if loggroup_id:
696
719
  try:
697
720
  loggroup = utils.query_resource(loggroup_id, return_all=False)
698
721
  loggroup_name = loggroup.display_name if loggroup else ""
699
- except Exception:
722
+ except Exception as ex:
723
+ logger.debug(f"Failed to get associated loggroup name. Error: {ex}")
700
724
  pass
701
725
 
702
726
  try:
703
727
  introspection = json.loads(
704
728
  self._get_attribute_from_model_metadata(resource, "ArtifactTestResults")
705
729
  )
706
- except Exception:
730
+ except Exception as ex:
731
+ logger.debug(
732
+ f"There was an issue loading the model attribute as json object for evaluation {eval_id}. "
733
+ f"Setting introspection to empty.\n Error:{ex}"
734
+ )
707
735
  introspection = {}
708
736
 
709
737
  summary = AquaEvaluationDetail(
@@ -856,13 +884,13 @@ class AquaEvaluationApp(AquaApp):
856
884
  try:
857
885
  log_id = job_run_details.log_details.log_id
858
886
  except Exception as e:
859
- logger.debug(f"Failed to get associated log. {str(e)}")
887
+ logger.debug(f"Failed to get associated log.\nError: {str(e)}")
860
888
  log_id = ""
861
889
 
862
890
  try:
863
891
  loggroup_id = job_run_details.log_details.log_group_id
864
892
  except Exception as e:
865
- logger.debug(f"Failed to get associated log. {str(e)}")
893
+ logger.debug(f"Failed to get associated log.\nError: {str(e)}")
866
894
  loggroup_id = ""
867
895
 
868
896
  loggroup_url = get_log_links(region=self.region, log_group_id=loggroup_id)
@@ -936,7 +964,7 @@ class AquaEvaluationApp(AquaApp):
936
964
  )
937
965
  except Exception as e:
938
966
  logger.debug(
939
- "Failed to load `report.json` from evaluation artifact" f"{str(e)}"
967
+ f"Failed to load `report.json` from evaluation artifact.\nError: {str(e)}"
940
968
  )
941
969
  json_report = {}
942
970
 
@@ -1025,6 +1053,7 @@ class AquaEvaluationApp(AquaApp):
1025
1053
  return report
1026
1054
 
1027
1055
  with tempfile.TemporaryDirectory() as temp_dir:
1056
+ logger.info(f"Downloading evaluation artifact for {eval_id}.")
1028
1057
  DataScienceModel.from_id(eval_id).download_artifact(
1029
1058
  temp_dir,
1030
1059
  auth=self._auth,
@@ -1178,6 +1207,7 @@ class AquaEvaluationApp(AquaApp):
1178
1207
  def load_evaluation_config(self, container: Optional[str] = None) -> Dict:
1179
1208
  """Loads evaluation config."""
1180
1209
 
1210
+ logger.info("Loading evaluation container config.")
1181
1211
  # retrieve the evaluation config by container family name
1182
1212
  evaluation_config = get_evaluation_service_config(container)
1183
1213
 
@@ -1257,9 +1287,9 @@ class AquaEvaluationApp(AquaApp):
1257
1287
  raise AquaRuntimeError(
1258
1288
  f"Not supported source type: {resource_type}"
1259
1289
  )
1260
- except Exception:
1290
+ except Exception as ex:
1261
1291
  logger.debug(
1262
- f"Failed to retrieve source information for evaluation {evaluation.identifier}."
1292
+ f"Failed to retrieve source information for evaluation {evaluation.identifier}.\nError: {str(ex)}"
1263
1293
  )
1264
1294
  source_name = ""
1265
1295
 
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env python
2
- # -*- coding: utf-8 -*--
3
2
 
4
- # Copyright (c) 2024 Oracle and/or its affiliates.
3
+ # Copyright (c) 2024, 2025 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
 
7
6
  import traceback
7
+ import uuid
8
8
  from abc import abstractmethod
9
9
  from http.client import responses
10
10
  from typing import List
@@ -34,7 +34,7 @@ class AquaWSMsgHandler:
34
34
  self.telemetry = TelemetryClient(
35
35
  bucket=AQUA_TELEMETRY_BUCKET, namespace=AQUA_TELEMETRY_BUCKET_NS
36
36
  )
37
- except:
37
+ except Exception:
38
38
  pass
39
39
 
40
40
  @staticmethod
@@ -66,16 +66,23 @@ class AquaWSMsgHandler:
66
66
  "message": message,
67
67
  "service_payload": service_payload,
68
68
  "reason": reason,
69
+ "request_id": str(uuid.uuid4()),
69
70
  }
70
71
  exc_info = kwargs.get("exc_info")
71
72
  if exc_info:
72
- logger.error("".join(traceback.format_exception(*exc_info)))
73
+ logger.error(
74
+ f"Error Request ID: {reply['request_id']}\n"
75
+ f"Error: {''.join(traceback.format_exception(*exc_info))}"
76
+ )
73
77
  e = exc_info[1]
74
78
  if isinstance(e, HTTPError):
75
79
  reply["message"] = e.log_message or message
76
80
  reply["reason"] = e.reason
77
- else:
78
- logger.warning(reply["message"])
81
+
82
+ logger.error(
83
+ f"Error Request ID: {reply['request_id']}\n"
84
+ f"Error: {reply['message']} {reply['reason']}"
85
+ )
79
86
  # telemetry may not be present if there is an error while initializing
80
87
  if hasattr(self, "telemetry"):
81
88
  aqua_api_details = kwargs.get("aqua_api_details", {})
@@ -83,7 +90,7 @@ class AquaWSMsgHandler:
83
90
  category="aqua/error",
84
91
  action=str(status_code),
85
92
  value=reason,
86
- **aqua_api_details
93
+ **aqua_api_details,
87
94
  )
88
95
  response = AquaWsError(
89
96
  status=status_code,
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
- # Copyright (c) 2024 Oracle and/or its affiliates.
2
+ # Copyright (c) 2024, 2025 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
 
@@ -35,7 +34,7 @@ class AquaAPIhandler(APIHandler):
35
34
  self.telemetry = TelemetryClient(
36
35
  bucket=AQUA_TELEMETRY_BUCKET, namespace=AQUA_TELEMETRY_BUCKET_NS
37
36
  )
38
- except:
37
+ except Exception:
39
38
  pass
40
39
 
41
40
  @staticmethod
@@ -82,19 +81,23 @@ class AquaAPIhandler(APIHandler):
82
81
  "message": message,
83
82
  "service_payload": service_payload,
84
83
  "reason": reason,
84
+ "request_id": str(uuid.uuid4()),
85
85
  }
86
86
  exc_info = kwargs.get("exc_info")
87
87
  if exc_info:
88
- logger.error("".join(traceback.format_exception(*exc_info)))
88
+ logger.error(
89
+ f"Error Request ID: {reply['request_id']}\n"
90
+ f"Error: {''.join(traceback.format_exception(*exc_info))}"
91
+ )
89
92
  e = exc_info[1]
90
93
  if isinstance(e, HTTPError):
91
94
  reply["message"] = e.log_message or message
92
95
  reply["reason"] = e.reason if e.reason else reply["reason"]
93
- reply["request_id"] = str(uuid.uuid4())
94
- else:
95
- reply["request_id"] = str(uuid.uuid4())
96
96
 
97
- logger.warning(reply["message"])
97
+ logger.error(
98
+ f"Error Request ID: {reply['request_id']}\n"
99
+ f"Error: {reply['message']} {reply['reason']}"
100
+ )
98
101
 
99
102
  # telemetry may not be present if there is an error while initializing
100
103
  if hasattr(self, "telemetry"):
@@ -103,7 +106,7 @@ class AquaAPIhandler(APIHandler):
103
106
  category="aqua/error",
104
107
  action=str(status_code),
105
108
  value=reason,
106
- **aqua_api_details
109
+ **aqua_api_details,
107
110
  )
108
111
 
109
112
  self.finish(json.dumps(reply))
@@ -59,7 +59,7 @@ class AquaDeploymentHandler(AquaAPIhandler):
59
59
  return self.finish(AquaDeploymentApp().delete(model_deployment_id))
60
60
 
61
61
  @handle_exceptions
62
- def put(self, *args, **kwargs):
62
+ def put(self, *args, **kwargs): # noqa: ARG002
63
63
  """
64
64
  Handles put request for the activating and deactivating OCI datascience model deployments
65
65
  Raises
@@ -82,7 +82,7 @@ class AquaDeploymentHandler(AquaAPIhandler):
82
82
  raise HTTPError(400, f"The request {self.request.path} is invalid.")
83
83
 
84
84
  @handle_exceptions
85
- def post(self, *args, **kwargs):
85
+ def post(self, *args, **kwargs): # noqa: ARG002
86
86
  """
87
87
  Handles post request for the deployment APIs
88
88
  Raises
@@ -132,6 +132,8 @@ class AquaDeploymentHandler(AquaAPIhandler):
132
132
  private_endpoint_id = input_data.get("private_endpoint_id")
133
133
  container_image_uri = input_data.get("container_image_uri")
134
134
  cmd_var = input_data.get("cmd_var")
135
+ freeform_tags = input_data.get("freeform_tags")
136
+ defined_tags = input_data.get("defined_tags")
135
137
 
136
138
  self.finish(
137
139
  AquaDeploymentApp().create(
@@ -157,6 +159,8 @@ class AquaDeploymentHandler(AquaAPIhandler):
157
159
  private_endpoint_id=private_endpoint_id,
158
160
  container_image_uri=container_image_uri,
159
161
  cmd_var=cmd_var,
162
+ freeform_tags=freeform_tags,
163
+ defined_tags=defined_tags,
160
164
  )
161
165
  )
162
166
 
@@ -196,7 +200,7 @@ class AquaDeploymentInferenceHandler(AquaAPIhandler):
196
200
  return False
197
201
 
198
202
  @handle_exceptions
199
- def post(self, *args, **kwargs):
203
+ def post(self, *args, **kwargs): # noqa: ARG002
200
204
  """
201
205
  Handles inference request for the Active Model Deployments
202
206
  Raises
@@ -262,7 +266,7 @@ class AquaDeploymentParamsHandler(AquaAPIhandler):
262
266
  )
263
267
 
264
268
  @handle_exceptions
265
- def post(self, *args, **kwargs):
269
+ def post(self, *args, **kwargs): # noqa: ARG002
266
270
  """Handles post request for the deployment param handler API.
267
271
 
268
272
  Raises
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python
2
- # Copyright (c) 2024 Oracle and/or its affiliates.
2
+ # Copyright (c) 2024, 2025 Oracle and/or its affiliates.
3
3
  # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
4
4
 
5
5
 
@@ -10,9 +10,7 @@ from tornado.web import HTTPError
10
10
  from ads.aqua.common.decorator import handle_exceptions
11
11
  from ads.aqua.extension.base_handler import AquaAPIhandler
12
12
  from ads.aqua.extension.errors import Errors
13
- from ads.aqua.extension.utils import validate_function_parameters
14
13
  from ads.aqua.finetuning import AquaFineTuningApp
15
- from ads.aqua.finetuning.entities import CreateFineTuningDetails
16
14
 
17
15
 
18
16
  class AquaFineTuneHandler(AquaAPIhandler):
@@ -33,7 +31,7 @@ class AquaFineTuneHandler(AquaAPIhandler):
33
31
  raise HTTPError(400, f"The request {self.request.path} is invalid.")
34
32
 
35
33
  @handle_exceptions
36
- def post(self, *args, **kwargs):
34
+ def post(self, *args, **kwargs): # noqa: ARG002
37
35
  """Handles post request for the fine-tuning API
38
36
 
39
37
  Raises
@@ -43,17 +41,13 @@ class AquaFineTuneHandler(AquaAPIhandler):
43
41
  """
44
42
  try:
45
43
  input_data = self.get_json_body()
46
- except Exception:
47
- raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT)
44
+ except Exception as ex:
45
+ raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT) from ex
48
46
 
49
47
  if not input_data:
50
48
  raise HTTPError(400, Errors.NO_INPUT_DATA)
51
49
 
52
- validate_function_parameters(
53
- data_class=CreateFineTuningDetails, input_data=input_data
54
- )
55
-
56
- self.finish(AquaFineTuningApp().create(CreateFineTuningDetails(**input_data)))
50
+ self.finish(AquaFineTuningApp().create(**input_data))
57
51
 
58
52
  def get_finetuning_config(self, model_id):
59
53
  """Gets the finetuning config for Aqua model."""
@@ -71,7 +65,7 @@ class AquaFineTuneParamsHandler(AquaAPIhandler):
71
65
  )
72
66
 
73
67
  @handle_exceptions
74
- def post(self, *args, **kwargs):
68
+ def post(self, *args, **kwargs): # noqa: ARG002
75
69
  """Handles post request for the finetuning param handler API.
76
70
 
77
71
  Raises
@@ -81,8 +75,8 @@ class AquaFineTuneParamsHandler(AquaAPIhandler):
81
75
  """
82
76
  try:
83
77
  input_data = self.get_json_body()
84
- except Exception:
85
- raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT)
78
+ except Exception as ex:
79
+ raise HTTPError(400, Errors.INVALID_INPUT_DATA_FORMAT) from ex
86
80
 
87
81
  if not input_data:
88
82
  raise HTTPError(400, Errors.NO_INPUT_DATA)