oracle-ads 2.12.11__py3-none-any.whl → 2.13.1__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 (83) hide show
  1. ads/aqua/__init__.py +7 -1
  2. ads/aqua/app.py +41 -27
  3. ads/aqua/client/client.py +48 -11
  4. ads/aqua/common/entities.py +28 -1
  5. ads/aqua/common/enums.py +32 -21
  6. ads/aqua/common/errors.py +3 -4
  7. ads/aqua/common/utils.py +10 -15
  8. ads/aqua/config/container_config.py +203 -0
  9. ads/aqua/config/evaluation/evaluation_service_config.py +5 -181
  10. ads/aqua/constants.py +1 -1
  11. ads/aqua/evaluation/constants.py +7 -7
  12. ads/aqua/evaluation/errors.py +3 -4
  13. ads/aqua/evaluation/evaluation.py +4 -4
  14. ads/aqua/extension/base_handler.py +4 -0
  15. ads/aqua/extension/model_handler.py +41 -27
  16. ads/aqua/extension/models/ws_models.py +5 -6
  17. ads/aqua/finetuning/constants.py +3 -3
  18. ads/aqua/finetuning/finetuning.py +2 -3
  19. ads/aqua/model/constants.py +7 -7
  20. ads/aqua/model/entities.py +2 -3
  21. ads/aqua/model/enums.py +4 -5
  22. ads/aqua/model/model.py +46 -29
  23. ads/aqua/modeldeployment/deployment.py +6 -14
  24. ads/aqua/modeldeployment/entities.py +5 -3
  25. ads/aqua/server/__init__.py +4 -0
  26. ads/aqua/server/__main__.py +24 -0
  27. ads/aqua/server/app.py +47 -0
  28. ads/aqua/server/aqua_spec.yml +1291 -0
  29. ads/aqua/ui.py +5 -199
  30. ads/common/auth.py +50 -28
  31. ads/common/extended_enum.py +52 -44
  32. ads/common/utils.py +91 -11
  33. ads/config.py +3 -0
  34. ads/llm/__init__.py +12 -8
  35. ads/llm/langchain/plugins/embeddings/__init__.py +4 -0
  36. ads/llm/langchain/plugins/embeddings/oci_data_science_model_deployment_endpoint.py +184 -0
  37. ads/llm/langchain/plugins/llms/oci_data_science_model_deployment_endpoint.py +32 -23
  38. ads/model/artifact_downloader.py +6 -4
  39. ads/model/common/utils.py +15 -3
  40. ads/model/datascience_model.py +422 -71
  41. ads/model/generic_model.py +3 -3
  42. ads/model/model_metadata.py +70 -24
  43. ads/model/model_version_set.py +5 -3
  44. ads/model/service/oci_datascience_model.py +487 -17
  45. ads/opctl/anomaly_detection.py +11 -0
  46. ads/opctl/backend/marketplace/helm_helper.py +13 -14
  47. ads/opctl/cli.py +4 -5
  48. ads/opctl/cmds.py +28 -32
  49. ads/opctl/config/merger.py +8 -11
  50. ads/opctl/config/resolver.py +25 -30
  51. ads/opctl/forecast.py +11 -0
  52. ads/opctl/operator/cli.py +9 -9
  53. ads/opctl/operator/common/backend_factory.py +56 -60
  54. ads/opctl/operator/common/const.py +5 -5
  55. ads/opctl/operator/common/utils.py +16 -0
  56. ads/opctl/operator/lowcode/anomaly/const.py +8 -9
  57. ads/opctl/operator/lowcode/common/data.py +5 -2
  58. ads/opctl/operator/lowcode/common/transformations.py +2 -12
  59. ads/opctl/operator/lowcode/feature_store_marketplace/operator_utils.py +43 -48
  60. ads/opctl/operator/lowcode/forecast/__main__.py +5 -5
  61. ads/opctl/operator/lowcode/forecast/const.py +6 -6
  62. ads/opctl/operator/lowcode/forecast/model/arima.py +6 -3
  63. ads/opctl/operator/lowcode/forecast/model/automlx.py +61 -31
  64. ads/opctl/operator/lowcode/forecast/model/base_model.py +66 -40
  65. ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py +79 -13
  66. ads/opctl/operator/lowcode/forecast/model/neuralprophet.py +5 -2
  67. ads/opctl/operator/lowcode/forecast/model/prophet.py +28 -15
  68. ads/opctl/operator/lowcode/forecast/model_evaluator.py +13 -15
  69. ads/opctl/operator/lowcode/forecast/schema.yaml +1 -1
  70. ads/opctl/operator/lowcode/forecast/whatifserve/deployment_manager.py +7 -0
  71. ads/opctl/operator/lowcode/forecast/whatifserve/score.py +19 -11
  72. ads/opctl/operator/lowcode/pii/constant.py +6 -7
  73. ads/opctl/operator/lowcode/recommender/constant.py +12 -7
  74. ads/opctl/operator/runtime/marketplace_runtime.py +4 -10
  75. ads/opctl/operator/runtime/runtime.py +4 -6
  76. ads/pipeline/ads_pipeline_run.py +13 -25
  77. ads/pipeline/visualizer/graph_renderer.py +3 -4
  78. {oracle_ads-2.12.11.dist-info → oracle_ads-2.13.1.dist-info}/METADATA +18 -15
  79. {oracle_ads-2.12.11.dist-info → oracle_ads-2.13.1.dist-info}/RECORD +82 -74
  80. {oracle_ads-2.12.11.dist-info → oracle_ads-2.13.1.dist-info}/WHEEL +1 -1
  81. ads/aqua/config/evaluation/evaluation_service_model_config.py +0 -8
  82. {oracle_ads-2.12.11.dist-info → oracle_ads-2.13.1.dist-info}/entry_points.txt +0 -0
  83. {oracle_ads-2.12.11.dist-info → oracle_ads-2.13.1.dist-info/licenses}/LICENSE.txt +0 -0
@@ -1,24 +1,15 @@
1
1
  #!/usr/bin/env python
2
- # -*- coding: utf-8; -*-
3
2
 
4
3
  # Copyright (c) 2022, 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
 
7
6
  import logging
8
- import time
7
+ from dataclasses import dataclass
9
8
  from functools import wraps
10
9
  from io import BytesIO
11
- from typing import Callable, Dict, List, Optional
10
+ from typing import Callable, Dict, List, Optional, Union
12
11
 
13
12
  import oci.data_science
14
- from ads.common import utils
15
- from ads.common.object_storage_details import ObjectStorageDetails
16
- from ads.common.oci_datascience import OCIDataScienceMixin
17
- from ads.common.oci_mixin import OCIWorkRequestMixin
18
- from ads.common.oci_resource import SEARCH_TYPE, OCIResource
19
- from ads.common.utils import extract_region
20
- from ads.common.work_request import DataScienceWorkRequest
21
- from ads.model.deployment import ModelDeployment
22
13
  from oci.data_science.models import (
23
14
  ArtifactExportDetailsObjectStorage,
24
15
  ArtifactImportDetailsObjectStorage,
@@ -26,9 +17,21 @@ from oci.data_science.models import (
26
17
  ExportModelArtifactDetails,
27
18
  ImportModelArtifactDetails,
28
19
  UpdateModelDetails,
29
- WorkRequest,
30
20
  )
31
21
  from oci.exceptions import ServiceError
22
+ from requests.structures import CaseInsensitiveDict
23
+
24
+ from ads.common import utils
25
+ from ads.common.auth import default_signer
26
+ from ads.common.object_storage_details import ObjectStorageDetails
27
+ from ads.common.oci_datascience import OCIDataScienceMixin
28
+ from ads.common.oci_mixin import OCIWorkRequestMixin
29
+ from ads.common.oci_resource import SEARCH_TYPE, OCIResource
30
+ from ads.common.serializer import DataClassSerializable
31
+ from ads.common.utils import extract_region, read_file, text_sanitizer
32
+ from ads.common.work_request import DataScienceWorkRequest
33
+ from ads.model.common.utils import MetadataArtifactPathType
34
+ from ads.model.deployment import ModelDeployment
32
35
 
33
36
  logger = logging.getLogger(__name__)
34
37
 
@@ -57,6 +60,21 @@ class ModelWithActiveDeploymentError(Exception): # pragma: no cover
57
60
  pass
58
61
 
59
62
 
63
+ class ModelMetadataArtifactNotFoundError(Exception): # pragma: no cover
64
+ def __init__(self, model_ocid, metadata_key: str):
65
+ super().__init__(
66
+ f"The model {model_ocid} does not contain the metadata with key {metadata_key}."
67
+ )
68
+
69
+
70
+ @dataclass(repr=False)
71
+ class ModelMetadataArtifactDetails(DataClassSerializable):
72
+ """Represents a details of Model Metadata ."""
73
+
74
+ headers: Union[Dict, CaseInsensitiveDict]
75
+ status: str
76
+
77
+
60
78
  def check_for_model_id(msg: str = MODEL_NEEDS_TO_BE_SAVED):
61
79
  """The decorator helping to check if the ID attribute sepcified for a datascience model.
62
80
 
@@ -89,6 +107,12 @@ def check_for_model_id(msg: str = MODEL_NEEDS_TO_BE_SAVED):
89
107
  return decorator
90
108
 
91
109
 
110
+ def convert_model_metadata_response(
111
+ headers: Union[Dict, CaseInsensitiveDict], status: int
112
+ ) -> ModelMetadataArtifactDetails:
113
+ return ModelMetadataArtifactDetails(headers=headers, status=str(status))
114
+
115
+
92
116
  class OCIDataScienceModel(
93
117
  OCIDataScienceMixin,
94
118
  OCIWorkRequestMixin,
@@ -282,7 +306,7 @@ class OCIDataScienceModel(
282
306
  msg="Model needs to be restored before the archived artifact content can be accessed."
283
307
  )
284
308
  def restore_archived_model_artifact(
285
- self, restore_model_for_hours_specified: Optional[int] = None
309
+ self, restore_model_for_hours_specified: Optional[int] = None
286
310
  ) -> None:
287
311
  """Restores the archived model artifact.
288
312
 
@@ -304,7 +328,8 @@ class OCIDataScienceModel(
304
328
  """
305
329
  return self.client.restore_archived_model_artifact(
306
330
  model_id=self.id,
307
- restore_model_for_hours_specified=restore_model_for_hours_specified).headers["opc-work-request-id"]
331
+ restore_model_for_hours_specified=restore_model_for_hours_specified,
332
+ ).headers["opc-work-request-id"]
308
333
 
309
334
  @check_for_model_id(
310
335
  msg="Model needs to be saved to the Model Catalog before the artifact content can be read."
@@ -531,8 +556,6 @@ class OCIDataScienceModel(
531
556
 
532
557
  Parameters
533
558
  ----------
534
- model_id: str
535
- The model ID.
536
559
  config: (Dict, optional). Defaults to `None`.
537
560
  Configuration keys and values as per SDK and Tool Configuration.
538
561
  The from_file() method can be used to load configuration from a file.
@@ -581,7 +604,7 @@ class OCIDataScienceModel(
581
604
  raise ValueError("Model OCID not provided.")
582
605
  return super().from_ocid(ocid)
583
606
 
584
- def is_model_by_reference(self):
607
+ def is_model_created_by_reference(self):
585
608
  """Checks if model is created by reference
586
609
  Returns
587
610
  -------
@@ -596,3 +619,450 @@ class OCIDataScienceModel(
596
619
  ):
597
620
  return True
598
621
  return False
622
+
623
+ def get_metadata_content(
624
+ self, artifact_path_or_content: str, path_type: MetadataArtifactPathType
625
+ ):
626
+ """
627
+ returns the content of the metadata artifact
628
+
629
+ Parameters
630
+ ----------
631
+ artifact_path_or_content: str
632
+ The path of the file (local or oss) containing metadata artifact or content.
633
+ path_type: str
634
+ can be one of local , oss or actual content itself
635
+
636
+ Returns
637
+ -------
638
+ metadata artifact content
639
+ """
640
+
641
+ if path_type == MetadataArtifactPathType.CONTENT:
642
+ return artifact_path_or_content
643
+
644
+ elif path_type == MetadataArtifactPathType.LOCAL:
645
+ if not utils.is_path_exists(artifact_path_or_content):
646
+ raise FileNotFoundError(
647
+ f"File not found: {artifact_path_or_content} . "
648
+ )
649
+
650
+ with open(artifact_path_or_content, "rb") as f:
651
+ contents = f.read()
652
+ logger.info(f"The metadata artifact content - {contents}")
653
+
654
+ return contents
655
+
656
+ elif path_type == MetadataArtifactPathType.OSS:
657
+ if not utils.is_path_exists(artifact_path_or_content):
658
+ raise FileNotFoundError(f"File not found: {artifact_path_or_content}")
659
+
660
+ contents = str(
661
+ read_file(file_path=artifact_path_or_content, auth=default_signer())
662
+ )
663
+ logger.debug(f"The metadata artifact content - {contents}")
664
+
665
+ return contents
666
+
667
+ @check_for_model_id(
668
+ msg="Model needs to be saved to the Model Catalog before the creating custom metadata artifact corresponding to that model"
669
+ )
670
+ def create_custom_metadata_artifact(
671
+ self,
672
+ metadata_key_name: str,
673
+ artifact_path: str,
674
+ path_type: MetadataArtifactPathType,
675
+ ) -> ModelMetadataArtifactDetails:
676
+ """Creates model custom metadata artifact for specified model.
677
+
678
+ Parameters
679
+ ----------
680
+ metadata_key_name: str
681
+ The name of the model metadatum in the metadata.
682
+
683
+ artifact_path: str
684
+ The model custom metadata artifact path to be upload.
685
+
686
+ path_type: MetadataArtifactPathType
687
+ can be one of local , oss or actual content itself
688
+
689
+ Returns
690
+ -------
691
+ ModelMetadataArtifactDetails
692
+ The model custom metadata artifact creation info.
693
+ Example:
694
+ {
695
+ 'Date': 'Mon, 02 Dec 2024 06:38:24 GMT',
696
+ 'opc-request-id': 'E4F7',
697
+ 'ETag': '77156317-8bb9-4c4a-882b-0d85f8140d93',
698
+ 'X-Content-Type-Options': 'nosniff',
699
+ 'Content-Length': '4029958',
700
+ 'Vary': 'Origin',
701
+ 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
702
+ 'status': 204
703
+ }
704
+
705
+ """
706
+ contents = self.get_metadata_content(
707
+ artifact_path_or_content=artifact_path, path_type=path_type
708
+ )
709
+ response = self.client.create_model_custom_metadatum_artifact(
710
+ self.id,
711
+ metadata_key_name,
712
+ text_sanitizer(contents),
713
+ content_disposition="form" '-data; name="file"; filename="readme.*"',
714
+ )
715
+ response_data = convert_model_metadata_response(
716
+ response.headers, response.status
717
+ )
718
+ return response_data
719
+
720
+ @check_for_model_id(
721
+ msg="Model needs to be saved to the Model Catalog before creating defined metadata artifact corresponding to that model"
722
+ )
723
+ def create_defined_metadata_artifact(
724
+ self,
725
+ metadata_key_name: str,
726
+ artifact_path: str,
727
+ path_type: MetadataArtifactPathType,
728
+ ) -> ModelMetadataArtifactDetails:
729
+ """Creates model defined metadata artifact for specified model.
730
+
731
+ Parameters
732
+ ----------
733
+ metadata_key_name: str
734
+ The name of the model metadatum in the metadata.
735
+
736
+ artifact_path: str
737
+ The model custom metadata artifact path to be upload.
738
+
739
+ path_type: MetadataArtifactPathType
740
+ can be one of local , oss or actual content itself.
741
+
742
+ Returns
743
+ -------
744
+ ModelMetadataArtifactDetails
745
+ The model defined metadata artifact creation info.
746
+ Example:
747
+ {
748
+ 'Date': 'Mon, 02 Dec 2024 06:38:24 GMT',
749
+ 'opc-request-id': 'E4F7',
750
+ 'ETag': '77156317-8bb9-4c4a-882b-0d85f8140d93',
751
+ 'X-Content-Type-Options': 'nosniff',
752
+ 'Content-Length': '4029958',
753
+ 'Vary': 'Origin',
754
+ 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
755
+ 'status': 204
756
+ }
757
+
758
+ """
759
+ contents = self.get_metadata_content(
760
+ artifact_path_or_content=artifact_path, path_type=path_type
761
+ )
762
+ response = self.client.create_model_defined_metadatum_artifact(
763
+ self.id,
764
+ metadata_key_name,
765
+ text_sanitizer(contents),
766
+ content_disposition='form-data; name="file"; filename="readme.*"',
767
+ )
768
+ response_data = convert_model_metadata_response(
769
+ response.headers, response.status
770
+ )
771
+ return response_data
772
+
773
+ @check_for_model_id(
774
+ msg="Model needs to be saved to the Model Catalog before updating defined metadata artifact corresponding to that model"
775
+ )
776
+ def update_defined_metadata_artifact(
777
+ self,
778
+ metadata_key_name: str,
779
+ artifact_path: str,
780
+ path_type: MetadataArtifactPathType,
781
+ ) -> ModelMetadataArtifactDetails:
782
+ """Update model defined metadata artifact for specified model.
783
+
784
+ Parameters
785
+ ----------
786
+ metadata_key_name: str
787
+ The name of the model metadatum in the metadata.
788
+
789
+ artifact_path: str
790
+ The model defined metadata artifact path to be upload.
791
+
792
+ path_type:MetadataArtifactPathType
793
+ can be one of local , oss or actual content itself.
794
+ Returns
795
+ -------
796
+ ModelMetadataArtifactDetails
797
+ The model defined metadata artifact update info.
798
+ Example:
799
+ {
800
+ 'Date': 'Mon, 02 Dec 2024 06:38:24 GMT',
801
+ 'opc-request-id': 'E4F7',
802
+ 'ETag': '77156317-8bb9-4c4a-882b-0d85f8140d93',
803
+ 'X-Content-Type-Options': 'nosniff',
804
+ 'Content-Length': '4029958',
805
+ 'Vary': 'Origin',
806
+ 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
807
+ 'status': 204
808
+ }
809
+
810
+ """
811
+ contents = self.get_metadata_content(
812
+ artifact_path_or_content=artifact_path, path_type=path_type
813
+ )
814
+ response = self.client.update_model_defined_metadatum_artifact(
815
+ self.id,
816
+ metadata_key_name,
817
+ text_sanitizer(contents),
818
+ content_disposition='form-data; name="file"; filename="readme.*"',
819
+ )
820
+ response_data = convert_model_metadata_response(
821
+ response.headers, response.status
822
+ )
823
+ return response_data
824
+
825
+ @check_for_model_id(
826
+ msg="Model needs to be saved to the Model Catalog before updating custom metadata artifact corresponding to that model"
827
+ )
828
+ def update_custom_metadata_artifact(
829
+ self,
830
+ metadata_key_name: str,
831
+ artifact_path: str,
832
+ path_type: MetadataArtifactPathType,
833
+ ) -> ModelMetadataArtifactDetails:
834
+ """Update model custom metadata artifact for specified model.
835
+
836
+ Parameters
837
+ ----------
838
+ metadata_key_name: str
839
+ The name of the model metadatum in the metadata.
840
+
841
+ artifact_path: str
842
+ The model custom metadata artifact path to be upload.
843
+
844
+ path_type: MetadataArtifactPathType
845
+ can be one of local , oss or actual content itself.
846
+
847
+ Returns
848
+ -------
849
+ ModelMetadataArtifactDetails
850
+ The model custom metadata artifact update info.
851
+ Example:
852
+ {
853
+ 'Date': 'Mon, 02 Dec 2024 06:38:24 GMT',
854
+ 'opc-request-id': 'E4F7',
855
+ 'ETag': '77156317-8bb9-4c4a-882b-0d85f8140d93',
856
+ 'X-Content-Type-Options': 'nosniff',
857
+ 'Content-Length': '4029958',
858
+ 'Vary': 'Origin',
859
+ 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
860
+ 'status': 204
861
+ }
862
+
863
+ """
864
+ contents = self.get_metadata_content(
865
+ artifact_path_or_content=artifact_path, path_type=path_type
866
+ )
867
+ response = self.client.update_model_custom_metadatum_artifact(
868
+ self.id,
869
+ metadata_key_name,
870
+ text_sanitizer(contents),
871
+ content_disposition="form" '-data; name="file"; filename="readme.*"',
872
+ )
873
+ response_data = convert_model_metadata_response(
874
+ response.headers, response.status
875
+ )
876
+ return response_data
877
+
878
+ @check_for_model_id(
879
+ msg="Model needs to be saved to the Model Catalog before fetching custom metadata artifact corresponding to that model"
880
+ )
881
+ def get_custom_metadata_artifact(self, metadata_key_name: str) -> bytes:
882
+ """Downloads model custom metadata artifact content for specified model metadata key.
883
+
884
+ Parameters
885
+ ----------
886
+ metadata_key_name: str
887
+ The name of the model metadatum in the metadata.
888
+ Returns
889
+ -------
890
+ bytes
891
+ custom metadata artifact content
892
+
893
+ """
894
+ try:
895
+ return self.client.get_model_custom_metadatum_artifact_content(
896
+ self.id, metadata_key_name
897
+ ).data.content
898
+ except ServiceError as ex:
899
+ if ex.status == 404:
900
+ raise ModelMetadataArtifactNotFoundError(self.id, metadata_key_name)
901
+
902
+ @check_for_model_id(
903
+ msg="Model needs to be saved to the Model Catalog before fetching defined metadata artifact corresponding to that model"
904
+ )
905
+ def get_defined_metadata_artifact(self, metadata_key_name: str) -> bytes:
906
+ """Downloads model defined metadata artifact content for specified model metadata key.
907
+
908
+ Parameters
909
+ ----------
910
+ metadata_key_name: str
911
+ The name of the model metadatum in the metadata.
912
+ Returns
913
+ -------
914
+ bytes
915
+ Defined metadata artifact content
916
+
917
+ """
918
+ try:
919
+ return self.client.get_model_defined_metadatum_artifact_content(
920
+ self.id, metadata_key_name
921
+ ).data.content
922
+ except ServiceError as ex:
923
+ if ex.status == 404 or ex.status == 400:
924
+ raise ModelMetadataArtifactNotFoundError(self.id, metadata_key_name)
925
+
926
+ @check_for_model_id(
927
+ msg="Model needs to be saved to the Model Catalog before fetching custom metadata artifact corresponding to that model"
928
+ )
929
+ def head_custom_metadata_artifact(
930
+ self, metadata_key_name: str
931
+ ) -> ModelMetadataArtifactDetails:
932
+ """Gets custom metadata artifact metadata for specified model metadata key.
933
+
934
+ Parameters
935
+ ----------
936
+ metadata_key_name: str
937
+ The name of the model metadatum in the metadata.
938
+ Returns
939
+ -------
940
+ ModelMetadataArtifactDetails
941
+ The model custom metadata artifact head call info.
942
+ Example:
943
+ {
944
+ 'Date': 'Mon, 02 Dec 2024 06:38:24 GMT',
945
+ 'opc-request-id': 'E4F7',
946
+ 'ETag': '77156317-8bb9-4c4a-882b-0d85f8140d93',
947
+ 'X-Content-Type-Options': 'nosniff',
948
+ 'Content-Length': '4029958',
949
+ 'Vary': 'Origin',
950
+ 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
951
+ 'status': 204
952
+ }
953
+
954
+ """
955
+ response = self.client.head_model_custom_metadatum_artifact(
956
+ self.id, metadata_key_name
957
+ )
958
+ response_data = convert_model_metadata_response(
959
+ response.headers, response.status
960
+ )
961
+ return response_data
962
+
963
+ @check_for_model_id(
964
+ msg="Model needs to be saved to the Model Catalog before fetching defined metadata artifact corresponding to that model"
965
+ )
966
+ def head_defined_metadata_artifact(
967
+ self, metadata_key_name: str
968
+ ) -> ModelMetadataArtifactDetails:
969
+ """Gets defined metadata artifact metadata for specified model metadata key.
970
+
971
+ Parameters
972
+ ----------
973
+ metadata_key_name: str
974
+ The name of the model metadatum in the metadata.
975
+ Returns
976
+ -------
977
+ ModelMetadataArtifactDetails
978
+ The model defined metadata artifact head call info.
979
+ Example:
980
+ {
981
+ 'Date': 'Mon, 02 Dec 2024 06:38:24 GMT',
982
+ 'opc-request-id': 'E4F7',
983
+ 'ETag': '77156317-8bb9-4c4a-882b-0d85f8140d93',
984
+ 'X-Content-Type-Options': 'nosniff',
985
+ 'Content-Length': '4029958',
986
+ 'Vary': 'Origin',
987
+ 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
988
+ 'status': 204
989
+ }
990
+
991
+ """
992
+ response = self.client.head_model_defined_metadatum_artifact(
993
+ self.id, metadata_key_name
994
+ )
995
+ response_data = convert_model_metadata_response(
996
+ response.headers, response.status
997
+ )
998
+ return response_data
999
+
1000
+ @check_for_model_id(
1001
+ msg="Model needs to be saved to the Model Catalog before the deleting custom metadata artifact corresponding to that model"
1002
+ )
1003
+ def delete_custom_metadata_artifact(
1004
+ self, metadata_key_name: str
1005
+ ) -> ModelMetadataArtifactDetails:
1006
+ """Deletes model custom metadata artifact for specified model metadata key.
1007
+
1008
+ Parameters
1009
+ ----------
1010
+ metadata_key_name: str
1011
+ The name of the model metadatum in the metadata.
1012
+ Returns
1013
+ -------
1014
+ ModelMetadataArtifactDetails
1015
+ The model custom metadata artifact delete call info.
1016
+ Example:
1017
+ {
1018
+ 'Date': 'Mon, 02 Dec 2024 06:38:24 GMT',
1019
+ 'opc-request-id': 'E4F7',
1020
+ 'X-Content-Type-Options': 'nosniff',
1021
+ 'Vary': 'Origin',
1022
+ 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
1023
+ 'status': 204
1024
+ }
1025
+
1026
+ """
1027
+ response = self.client.delete_model_custom_metadatum_artifact(
1028
+ self.id, metadata_key_name
1029
+ )
1030
+ response_data = convert_model_metadata_response(
1031
+ response.headers, response.status
1032
+ )
1033
+ return response_data
1034
+
1035
+ @check_for_model_id(
1036
+ msg="Model needs to be saved to the Model Catalog before the deleting defined metadata artifact corresponding to that model"
1037
+ )
1038
+ def delete_defined_metadata_artifact(
1039
+ self, metadata_key_name: str
1040
+ ) -> ModelMetadataArtifactDetails:
1041
+ """Deletes model defined metadata artifact for specified model metadata key.
1042
+
1043
+ Parameters
1044
+ ----------
1045
+ metadata_key_name: str
1046
+ The name of the model metadatum in the metadata.
1047
+ Returns
1048
+ -------
1049
+ ModelMetadataArtifactDetails
1050
+ The model defined metadata artifact delete call info.
1051
+ Example:
1052
+ {
1053
+ 'Date': 'Mon, 02 Dec 2024 06:38:24 GMT',
1054
+ 'opc-request-id': 'E4F7',
1055
+ 'X-Content-Type-Options': 'nosniff',
1056
+ 'Vary': 'Origin',
1057
+ 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
1058
+ 'status': 204
1059
+ }
1060
+
1061
+ """
1062
+ response = self.client.delete_model_defined_metadatum_artifact(
1063
+ self.id, metadata_key_name
1064
+ )
1065
+ response_data = convert_model_metadata_response(
1066
+ response.headers, response.status
1067
+ )
1068
+ return response_data
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env python
2
+
3
+ # Copyright (c) 2025 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
+ from ads.opctl.operator.lowcode.anomaly.__main__ import operate
7
+ from ads.opctl.operator.lowcode.anomaly.operator_config import AnomalyOperatorConfig
8
+
9
+ if __name__ == "__main__":
10
+ config = AnomalyOperatorConfig()
11
+ operate(config)
@@ -1,31 +1,30 @@
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
 
6
+ import io
7
7
  import subprocess
8
8
  from enum import Enum
9
9
  from typing import List
10
- import io
11
10
 
12
11
  import click
13
12
  import pandas as pd
14
- from ads.opctl.backend.marketplace.models.marketplace_type import (
15
- HelmMarketplaceListingDetails,
16
- )
17
13
 
18
- from ads.common.extended_enum import ExtendedEnumMeta
14
+ from ads.common.extended_enum import ExtendedEnum
19
15
  from ads.opctl import logger
20
16
  from ads.opctl.backend.marketplace.marketplace_utils import (
21
- StatusIcons,
22
- get_docker_bearer_token,
23
17
  WARNING,
24
18
  Color,
19
+ StatusIcons,
20
+ get_docker_bearer_token,
21
+ )
22
+ from ads.opctl.backend.marketplace.models.marketplace_type import (
23
+ HelmMarketplaceListingDetails,
25
24
  )
26
25
 
27
26
 
28
- class HelmCommand(str, metaclass=ExtendedEnumMeta):
27
+ class HelmCommand(ExtendedEnum):
29
28
  """Supported Helm commands."""
30
29
 
31
30
  Install = "install"
@@ -63,7 +62,7 @@ def run_helm_install(
63
62
  "-i",
64
63
  ]
65
64
  print(f"\n{Color.BLUE}{' '.join(helm_cmd)}{Color.END}")
66
- return subprocess.run(helm_cmd)
65
+ return subprocess.run(helm_cmd, check=False)
67
66
 
68
67
 
69
68
  def _get_as_flags_(**kwargs) -> List[str]:
@@ -125,7 +124,7 @@ def check_helm_pull(helm_chart_url: str, version: str) -> HelmPullStatus:
125
124
  *_get_as_flags_(version=f"{version}"),
126
125
  ]
127
126
  logger.debug(" ".join(helm_cmd))
128
- result = subprocess.run(helm_cmd, capture_output=True)
127
+ result = subprocess.run(helm_cmd, capture_output=True, check=False)
129
128
  stderr = result.stderr.decode("utf-8")
130
129
  if result.returncode == 0:
131
130
  return HelmPullStatus.SUCCESS
@@ -146,7 +145,7 @@ def run_helm_login(ocir_repo: str, token: str):
146
145
  *_get_as_flags_(username="BEARER_TOKEN", password=token),
147
146
  ]
148
147
  logger.debug(" ".join(helm_cmd[:-1]))
149
- result = subprocess.run(helm_cmd, capture_output=True)
148
+ result = subprocess.run(helm_cmd, capture_output=True, check=False)
150
149
  if result.returncode == 0:
151
150
  pass
152
151
  else:
@@ -162,7 +161,7 @@ def run_helm_list(namespace: str, **kwargs) -> pd.DataFrame:
162
161
  *_get_as_flags_(namespace=namespace, **kwargs),
163
162
  ]
164
163
  logger.debug(" ".join(helm_cmd))
165
- result = subprocess.run(helm_cmd, capture_output=True)
164
+ result = subprocess.run(helm_cmd, capture_output=True, check=False)
166
165
  if result.returncode == 0:
167
166
  return pd.read_csv(
168
167
  io.BytesIO(result.stdout), delimiter=r"\s*\t\s*", engine="python"
ads/opctl/cli.py CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env python
2
- # -*- coding: utf-8; -*-
3
2
 
4
- # Copyright (c) 2022, 2023 Oracle and/or its affiliates.
3
+ # Copyright (c) 2022, 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 os
@@ -173,7 +172,7 @@ _options = [
173
172
  click.option(
174
173
  "--backend",
175
174
  "-b",
176
- type=click.Choice([backend.value for backend in BACKEND_NAME]),
175
+ type=click.Choice([backend for backend in BACKEND_NAME]),
177
176
  help="backend to run the operator",
178
177
  required=False,
179
178
  default=None,
@@ -405,7 +404,7 @@ def check(file, **kwargs):
405
404
  debug = kwargs["debug"]
406
405
  if file:
407
406
  if os.path.exists(file):
408
- with open(file, "r") as f:
407
+ with open(file) as f:
409
408
  config = suppress_traceback(debug)(yaml.safe_load)(f.read())
410
409
  else:
411
410
  raise FileNotFoundError(f"{file} is not found")
@@ -586,7 +585,7 @@ def deactivate(**kwargs):
586
585
  )
587
586
  @click.option(
588
587
  "--output",
589
- help=f"The filename to save the resulting specification template YAML",
588
+ help="The filename to save the resulting specification template YAML",
590
589
  required=False,
591
590
  default=None,
592
591
  )