oracle-ads 2.13.0__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.
- ads/aqua/__init__.py +7 -1
- ads/aqua/app.py +24 -23
- ads/aqua/client/client.py +48 -11
- ads/aqua/common/entities.py +28 -1
- ads/aqua/common/enums.py +13 -7
- ads/aqua/common/utils.py +8 -13
- ads/aqua/config/container_config.py +203 -0
- ads/aqua/config/evaluation/evaluation_service_config.py +5 -181
- ads/aqua/constants.py +0 -1
- ads/aqua/evaluation/evaluation.py +4 -4
- ads/aqua/extension/base_handler.py +4 -0
- ads/aqua/extension/model_handler.py +19 -28
- ads/aqua/finetuning/finetuning.py +2 -3
- ads/aqua/model/entities.py +2 -3
- ads/aqua/model/model.py +25 -30
- ads/aqua/modeldeployment/deployment.py +6 -14
- ads/aqua/modeldeployment/entities.py +2 -2
- ads/aqua/server/__init__.py +4 -0
- ads/aqua/server/__main__.py +24 -0
- ads/aqua/server/app.py +47 -0
- ads/aqua/server/aqua_spec.yml +1291 -0
- ads/aqua/ui.py +5 -199
- ads/common/auth.py +20 -11
- ads/common/utils.py +91 -11
- ads/config.py +3 -0
- ads/llm/__init__.py +1 -0
- ads/llm/langchain/plugins/llms/oci_data_science_model_deployment_endpoint.py +32 -23
- ads/model/artifact_downloader.py +4 -1
- ads/model/common/utils.py +15 -3
- ads/model/datascience_model.py +339 -8
- ads/model/model_metadata.py +54 -14
- ads/model/model_version_set.py +5 -3
- ads/model/service/oci_datascience_model.py +477 -5
- ads/opctl/anomaly_detection.py +11 -0
- ads/opctl/forecast.py +11 -0
- ads/opctl/operator/common/utils.py +16 -0
- ads/opctl/operator/lowcode/common/data.py +5 -2
- ads/opctl/operator/lowcode/common/transformations.py +2 -12
- ads/opctl/operator/lowcode/forecast/__main__.py +5 -5
- ads/opctl/operator/lowcode/forecast/model/arima.py +6 -3
- ads/opctl/operator/lowcode/forecast/model/automlx.py +61 -31
- ads/opctl/operator/lowcode/forecast/model/base_model.py +66 -40
- ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py +79 -13
- ads/opctl/operator/lowcode/forecast/model/neuralprophet.py +5 -2
- ads/opctl/operator/lowcode/forecast/model/prophet.py +28 -15
- ads/opctl/operator/lowcode/forecast/model_evaluator.py +13 -15
- ads/opctl/operator/lowcode/forecast/schema.yaml +1 -1
- ads/opctl/operator/lowcode/forecast/whatifserve/deployment_manager.py +7 -0
- ads/opctl/operator/lowcode/forecast/whatifserve/score.py +19 -11
- {oracle_ads-2.13.0.dist-info → oracle_ads-2.13.1.dist-info}/METADATA +18 -15
- {oracle_ads-2.13.0.dist-info → oracle_ads-2.13.1.dist-info}/RECORD +54 -48
- {oracle_ads-2.13.0.dist-info → oracle_ads-2.13.1.dist-info}/WHEEL +1 -1
- ads/aqua/config/evaluation/evaluation_service_model_config.py +0 -8
- {oracle_ads-2.13.0.dist-info → oracle_ads-2.13.1.dist-info}/entry_points.txt +0 -0
- {oracle_ads-2.13.0.dist-info → oracle_ads-2.13.1.dist-info/licenses}/LICENSE.txt +0 -0
@@ -4,9 +4,10 @@
|
|
4
4
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
5
5
|
|
6
6
|
import logging
|
7
|
+
from dataclasses import dataclass
|
7
8
|
from functools import wraps
|
8
9
|
from io import BytesIO
|
9
|
-
from typing import Callable, Dict, List, Optional
|
10
|
+
from typing import Callable, Dict, List, Optional, Union
|
10
11
|
|
11
12
|
import oci.data_science
|
12
13
|
from oci.data_science.models import (
|
@@ -18,13 +19,18 @@ from oci.data_science.models import (
|
|
18
19
|
UpdateModelDetails,
|
19
20
|
)
|
20
21
|
from oci.exceptions import ServiceError
|
22
|
+
from requests.structures import CaseInsensitiveDict
|
21
23
|
|
24
|
+
from ads.common import utils
|
25
|
+
from ads.common.auth import default_signer
|
22
26
|
from ads.common.object_storage_details import ObjectStorageDetails
|
23
27
|
from ads.common.oci_datascience import OCIDataScienceMixin
|
24
28
|
from ads.common.oci_mixin import OCIWorkRequestMixin
|
25
29
|
from ads.common.oci_resource import SEARCH_TYPE, OCIResource
|
26
|
-
from ads.common.
|
30
|
+
from ads.common.serializer import DataClassSerializable
|
31
|
+
from ads.common.utils import extract_region, read_file, text_sanitizer
|
27
32
|
from ads.common.work_request import DataScienceWorkRequest
|
33
|
+
from ads.model.common.utils import MetadataArtifactPathType
|
28
34
|
from ads.model.deployment import ModelDeployment
|
29
35
|
|
30
36
|
logger = logging.getLogger(__name__)
|
@@ -54,6 +60,21 @@ class ModelWithActiveDeploymentError(Exception): # pragma: no cover
|
|
54
60
|
pass
|
55
61
|
|
56
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
|
+
|
57
78
|
def check_for_model_id(msg: str = MODEL_NEEDS_TO_BE_SAVED):
|
58
79
|
"""The decorator helping to check if the ID attribute sepcified for a datascience model.
|
59
80
|
|
@@ -86,6 +107,12 @@ def check_for_model_id(msg: str = MODEL_NEEDS_TO_BE_SAVED):
|
|
86
107
|
return decorator
|
87
108
|
|
88
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
|
+
|
89
116
|
class OCIDataScienceModel(
|
90
117
|
OCIDataScienceMixin,
|
91
118
|
OCIWorkRequestMixin,
|
@@ -529,8 +556,6 @@ class OCIDataScienceModel(
|
|
529
556
|
|
530
557
|
Parameters
|
531
558
|
----------
|
532
|
-
model_id: str
|
533
|
-
The model ID.
|
534
559
|
config: (Dict, optional). Defaults to `None`.
|
535
560
|
Configuration keys and values as per SDK and Tool Configuration.
|
536
561
|
The from_file() method can be used to load configuration from a file.
|
@@ -579,7 +604,7 @@ class OCIDataScienceModel(
|
|
579
604
|
raise ValueError("Model OCID not provided.")
|
580
605
|
return super().from_ocid(ocid)
|
581
606
|
|
582
|
-
def
|
607
|
+
def is_model_created_by_reference(self):
|
583
608
|
"""Checks if model is created by reference
|
584
609
|
Returns
|
585
610
|
-------
|
@@ -594,3 +619,450 @@ class OCIDataScienceModel(
|
|
594
619
|
):
|
595
620
|
return True
|
596
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)
|
ads/opctl/forecast.py
ADDED
@@ -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.forecast.__main__ import operate
|
7
|
+
from ads.opctl.operator.lowcode.forecast.operator_config import ForecastOperatorConfig
|
8
|
+
|
9
|
+
if __name__ == "__main__":
|
10
|
+
config = ForecastOperatorConfig()
|
11
|
+
operate(config)
|
@@ -9,6 +9,7 @@ import os
|
|
9
9
|
import sys
|
10
10
|
import time
|
11
11
|
import traceback
|
12
|
+
import uuid
|
12
13
|
from string import Template
|
13
14
|
from typing import Any, Dict, List, Tuple
|
14
15
|
|
@@ -17,6 +18,7 @@ import yaml
|
|
17
18
|
from cerberus import Validator
|
18
19
|
|
19
20
|
from ads.opctl import logger, utils
|
21
|
+
from ads.common.oci_logging import OCILog
|
20
22
|
|
21
23
|
CONTAINER_NETWORK = "CONTAINER_NETWORK"
|
22
24
|
|
@@ -190,3 +192,17 @@ def print_traceback():
|
|
190
192
|
if logger.level == logging.DEBUG:
|
191
193
|
ex_type, ex, tb = sys.exc_info()
|
192
194
|
traceback.print_tb(tb)
|
195
|
+
|
196
|
+
|
197
|
+
def create_log_in_log_group(compartment_id, log_group_id, auth, log_name=None):
|
198
|
+
"""
|
199
|
+
Creates a log within a given log group
|
200
|
+
"""
|
201
|
+
if not log_name:
|
202
|
+
log_name = f"log-{int(time.time())}-{uuid.uuid4()}"
|
203
|
+
log = OCILog(display_name=log_name,
|
204
|
+
log_group_id=log_group_id,
|
205
|
+
compartment_id=compartment_id,
|
206
|
+
**auth).create()
|
207
|
+
logger.info(f"Created log with log OCID {log.id}")
|
208
|
+
return log.id
|
@@ -19,13 +19,16 @@ from .transformations import Transformations
|
|
19
19
|
|
20
20
|
|
21
21
|
class AbstractData(ABC):
|
22
|
-
def __init__(self, spec
|
22
|
+
def __init__(self, spec, name="input_data", data=None):
|
23
23
|
self.Transformations = Transformations
|
24
24
|
self.data = None
|
25
25
|
self._data_dict = dict()
|
26
26
|
self.name = name
|
27
27
|
self.spec = spec
|
28
|
-
|
28
|
+
if data is not None:
|
29
|
+
self.data = data
|
30
|
+
else:
|
31
|
+
self.load_transform_ingest_data(spec)
|
29
32
|
|
30
33
|
def get_raw_data_by_cat(self, category):
|
31
34
|
mapping = self._data_transformer.get_target_category_columns_map()
|
@@ -31,7 +31,6 @@ class Transformations(ABC):
|
|
31
31
|
dataset_info : ForecastOperatorConfig
|
32
32
|
"""
|
33
33
|
self.name = name
|
34
|
-
self.has_artificial_series = False
|
35
34
|
self.dataset_info = dataset_info
|
36
35
|
self.target_category_columns = dataset_info.target_category_columns
|
37
36
|
self.target_column_name = dataset_info.target_column
|
@@ -136,7 +135,6 @@ class Transformations(ABC):
|
|
136
135
|
self._target_category_columns_map = {}
|
137
136
|
if not self.target_category_columns:
|
138
137
|
df[DataColumns.Series] = "Series 1"
|
139
|
-
self.has_artificial_series = True
|
140
138
|
else:
|
141
139
|
df[DataColumns.Series] = merge_category_columns(
|
142
140
|
df, self.target_category_columns
|
@@ -209,7 +207,7 @@ class Transformations(ABC):
|
|
209
207
|
|
210
208
|
def _missing_value_imputation_add(self, df):
|
211
209
|
"""
|
212
|
-
Function fills missing values
|
210
|
+
Function fills missing values with zero
|
213
211
|
|
214
212
|
Parameters
|
215
213
|
----------
|
@@ -219,15 +217,7 @@ class Transformations(ABC):
|
|
219
217
|
-------
|
220
218
|
A new Pandas DataFrame without missing values.
|
221
219
|
"""
|
222
|
-
|
223
|
-
for col in df.columns:
|
224
|
-
# find next int not in list
|
225
|
-
i = 0
|
226
|
-
vals = df[col].unique()
|
227
|
-
while i in vals:
|
228
|
-
i = i + 1
|
229
|
-
df[col] = df[col].fillna(0)
|
230
|
-
return df
|
220
|
+
return df.fillna(0)
|
231
221
|
|
232
222
|
def _outlier_treatment(self, df):
|
233
223
|
"""
|
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8 -*--
|
3
2
|
|
4
|
-
# Copyright (c) 2023,
|
3
|
+
# Copyright (c) 2023, 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 json
|
@@ -15,17 +14,17 @@ from ads.opctl import logger
|
|
15
14
|
from ads.opctl.operator.common.const import ENV_OPERATOR_ARGS
|
16
15
|
from ads.opctl.operator.common.utils import _parse_input_args
|
17
16
|
|
17
|
+
from .model.forecast_datasets import ForecastDatasets, ForecastResults
|
18
18
|
from .operator_config import ForecastOperatorConfig
|
19
|
-
from .model.forecast_datasets import ForecastDatasets
|
20
19
|
from .whatifserve import ModelDeploymentManager
|
21
20
|
|
22
21
|
|
23
|
-
def operate(operator_config: ForecastOperatorConfig) ->
|
22
|
+
def operate(operator_config: ForecastOperatorConfig) -> ForecastResults:
|
24
23
|
"""Runs the forecasting operator."""
|
25
24
|
from .model.factory import ForecastOperatorModelFactory
|
26
25
|
|
27
26
|
datasets = ForecastDatasets(operator_config)
|
28
|
-
ForecastOperatorModelFactory.get_model(
|
27
|
+
results = ForecastOperatorModelFactory.get_model(
|
29
28
|
operator_config, datasets
|
30
29
|
).generate_report()
|
31
30
|
# saving to model catalog
|
@@ -36,6 +35,7 @@ def operate(operator_config: ForecastOperatorConfig) -> None:
|
|
36
35
|
if spec.what_if_analysis.model_deployment:
|
37
36
|
mdm.create_deployment()
|
38
37
|
mdm.save_deployment_info()
|
38
|
+
return results
|
39
39
|
|
40
40
|
|
41
41
|
def verify(spec: Dict, **kwargs: Dict) -> bool:
|