Skip to content

Commit 3226228

Browse files
authored
Merge pull request #14 from oracle/2.6.x
Release version 2.6.6
2 parents e123f56 + 2f117bb commit 3226228

File tree

236 files changed

+16927
-2305
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

236 files changed

+16927
-2305
lines changed

ads/__init__.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,26 @@
88
import os
99
import logging
1010
import sys
11+
import json
1112

13+
__version__ = ""
14+
with open(
15+
os.path.join(os.path.dirname(os.path.abspath(__file__)), "ads_version.json")
16+
) as version_file:
17+
__version__ = json.load(version_file)["version"]
1218
import oci
1319

1420
import matplotlib.font_manager # causes matplotlib to regenerate its fonts
15-
import json
1621

1722
import ocifs
1823
from ads.common.decorator.deprecate import deprecated
1924
from ads.common.ipython import configure_plotting, _log_traceback
2025
from ads.feature_engineering.accessor.series_accessor import ADSSeriesAccessor
2126
from ads.feature_engineering.accessor.dataframe_accessor import ADSDataFrameAccessor
22-
27+
from ads.common import auth
2328

2429
os.environ["GIT_PYTHON_REFRESH"] = "quiet"
2530

26-
__version__ = ""
27-
with open(
28-
os.path.join(os.path.dirname(os.path.abspath(__file__)), "ads_version.json")
29-
) as version_file:
30-
__version__ = json.load(version_file)["version"]
3131

3232
debug_mode = os.environ.get("DEBUG_MODE", False)
3333
documentation_mode = os.environ.get("DOCUMENTATION_MODE", "False") == "True"
@@ -64,7 +64,7 @@ def set_auth(
6464
oci_config_path = oci_config_location
6565
else:
6666
logging.warning(
67-
f"{oci_config_location} file not exists, default value oci.config.DEFAULT_LOCATION used instead"
67+
f"{oci_config_location} file does not exist, default value oci.config.DEFAULT_LOCATION used instead"
6868
)
6969
oci_config_path = oci.config.DEFAULT_LOCATION
7070
elif auth == "resource_principal":

ads/ads_version.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"version": "2.6.5"
2+
"version": "2.6.6"
33
}

ads/cli.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@
33

44
# Copyright (c) 2021, 2022 Oracle and/or its affiliates.
55
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
6-
7-
import click
8-
import ads.opctl.cli
9-
import ads.jobs.cli
10-
import os
11-
import json
12-
6+
try:
7+
import click
8+
import ads.opctl.cli
9+
import ads.jobs.cli
10+
import os
11+
import json
12+
except:
13+
print(
14+
"Please run `pip install oracle-ads[opctl]` to install the required dependencies for ADS CLI"
15+
)
16+
exit()
1317
with open(
1418
os.path.join(os.path.dirname(os.path.abspath(__file__)), "ads_version.json")
1519
) as version_file:

ads/common/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77
import logging
88

99
logger = logging.getLogger(__name__)
10+
11+
from ads.common import auth

ads/common/auth.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import oci
88
import os
99
from ads.common import utils
10+
import ads.telemetry
1011

1112

1213
def api_keys(
@@ -42,7 +43,9 @@ def api_keys(
4243
>>> auth = authutil.api_keys(oci_config="/home/datascience/.oci/config", profile="TEST", client_kwargs={"timeout": 6000})
4344
>>> oc.OCIClientFactory(**auth).object_storage # Creates Object storage client with timeout set to 6000 using API Key authentication
4445
"""
45-
configuration = oci.config.from_file(oci_config, profile)
46+
configuration = ads.telemetry.update_oci_client_config(
47+
oci.config.from_file(oci_config, profile)
48+
)
4649
return {
4750
"config": configuration,
4851
"signer": oci.signer.Signer(
@@ -82,8 +85,10 @@ def resource_principal(client_kwargs=None):
8285
>>> oc.OCIClientFactory(**auth).object_storage # Creates Object Storage client with timeout set to 6000 seconds using resource principal authentication
8386
"""
8487

88+
configuration = ads.telemetry.update_oci_client_config()
89+
8590
return {
86-
"config": {},
91+
"config": configuration,
8792
"signer": oci.auth.signers.get_resource_principals_signer(),
8893
"client_kwargs": client_kwargs,
8994
}

ads/common/base_properties.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import dataclasses
88
import json
99
import os
10-
from typing import Any, Dict, Optional
10+
from typing import Any, Dict, Optional, Union
1111

1212
from ads.common.config import Config, ConfigSection
1313
from ads.common.serializer import Serializable
@@ -42,11 +42,21 @@ def __setattr__(self, name: str, value: Any):
4242
if value is None:
4343
self.__dict__[name] = value
4444
elif name in self.__annotations__:
45-
if self.__annotations__[name] != type(value):
45+
if hasattr(self.__annotations__[name], "__origin__"):
46+
if self.__annotations__[name].__origin__ is Union and not isinstance(
47+
value, self.__annotations__[name].__args__
48+
):
49+
raise TypeError(
50+
f"Field `{name}` was expected to be of type `{self.__annotations__[name].__args__}` "
51+
f"but type `{type(value)}` was provided."
52+
)
53+
54+
elif self.__annotations__[name] != type(value):
4655
raise TypeError(
47-
f"Field `{name}` was expected to be of type `{self.__annotations__[name].__name__}` "
48-
f"but type `{type(value).__name__}` was provided."
56+
f"Field `{name}` was expected to be of type `{self.__annotations__[name]}` "
57+
f"but type `{type(value)}` was provided."
4958
)
59+
5060
self.__dict__[name] = value
5161

5262
def with_prop(self, name: str, value: Any) -> "BaseProperties":

ads/common/data_serializer.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8; -*-
3+
4+
# Copyright (c) 2022 Oracle and/or its affiliates.
5+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
6+
7+
from __future__ import absolute_import, print_function
8+
9+
import base64
10+
from io import BytesIO
11+
from typing import Dict, List, Union
12+
import requests
13+
import json
14+
import numpy as np
15+
import pandas as pd
16+
17+
DEFAULT_CONTENT_TYPE_JSON = "application/json"
18+
DEFAULT_CONTENT_TYPE_BYTES = "application/octet-stream"
19+
20+
21+
class InputDataSerializer:
22+
"""[An internal class]
23+
Defines the contract for input data
24+
25+
"""
26+
27+
def __init__(
28+
self,
29+
data: Union[
30+
Dict,
31+
str,
32+
List,
33+
np.ndarray,
34+
pd.core.series.Series,
35+
pd.core.frame.DataFrame,
36+
],
37+
data_type=None,
38+
):
39+
"""
40+
Parameters
41+
----------
42+
data: Union[Dict, str, list, numpy.ndarray, pd.core.series.Series,
43+
pd.core.frame.DataFrame]
44+
Data expected by the model deployment predict API.
45+
data_type: Any, defaults to None.
46+
Type of the data. If not provided, it will be checked against data.
47+
48+
"""
49+
if not data_type:
50+
data_type = type(data)
51+
if isinstance(data, np.ndarray):
52+
np_bytes = BytesIO()
53+
np.save(np_bytes, data, allow_pickle=True)
54+
data = base64.b64encode(np_bytes.getvalue()).decode("utf-8")
55+
elif isinstance(data, pd.core.series.Series):
56+
data = data.tolist()
57+
elif isinstance(data, pd.core.frame.DataFrame):
58+
data = data.to_json()
59+
elif (
60+
isinstance(data, dict)
61+
or isinstance(data, str)
62+
or isinstance(data, list)
63+
or isinstance(data, tuple)
64+
or isinstance(data, bytes)
65+
):
66+
pass
67+
else:
68+
raise TypeError(
69+
"The provided data type is not json serializable. "
70+
"The supported data types are Dict, str, list, "
71+
"numpy.ndarray, pd.core.series.Series, "
72+
"pd.core.frame.DataFrame. Please "
73+
"convert to the supported data types first. "
74+
)
75+
76+
self._data = data
77+
self._data_type = str(data_type)
78+
79+
@property
80+
def data(self):
81+
return self._data
82+
83+
@property
84+
def data_type(self):
85+
return self._data_type
86+
87+
def to_dict(self):
88+
return {
89+
"data": self._data,
90+
"data_type": self._data_type,
91+
}
92+
93+
def is_bytes(self):
94+
return "bytes" in self.data_type
95+
96+
def send(self, endpoint: str, dry_run: bool = False, **kwargs):
97+
headers = dict()
98+
if self.is_bytes():
99+
headers["Content-Type"] = (
100+
kwargs.get("content_type") or DEFAULT_CONTENT_TYPE_BYTES
101+
)
102+
request_kwargs = {"data": self.data} # should pass bytes when using data
103+
else:
104+
headers["Content-Type"] = (
105+
kwargs.get("content_type") or DEFAULT_CONTENT_TYPE_JSON
106+
)
107+
request_kwargs = {"json": self.to_dict()}
108+
request_kwargs["headers"] = headers
109+
if dry_run:
110+
request_kwargs["headers"]["Accept"] = "*/*"
111+
req = requests.Request("POST", endpoint, **request_kwargs).prepare()
112+
if self.is_bytes():
113+
return req.body
114+
return json.loads(req.body)
115+
else:
116+
request_kwargs["auth"] = kwargs.get("signer")
117+
return requests.post(endpoint, **request_kwargs).json()

ads/common/decorator/runtime_dependency.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class OptionalDependency:
6262
GEO = "oracle-ads[geo]"
6363
ONNX = "oracle-ads[onnx]"
6464
OPTUNA = "oracle-ads[optuna]"
65+
SPARK = "oracle-ads[spark]"
6566

6667

6768
def runtime_dependency(

ads/common/model.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
runtime_dependency,
2424
OptionalDependency,
2525
)
26+
from ads.common.decorator.deprecate import deprecated
2627
from ads.common.utils import is_notebook
2728
from ads.dataset.pipeline import TransformerPipeline
28-
from distutils import dir_util
2929
from sklearn.pipeline import Pipeline
3030

3131

@@ -171,14 +171,18 @@ def rename(self, name):
171171
"""
172172
self.name = name
173173

174+
@deprecated(
175+
"2.6.6",
176+
details="Use framework specific Model utility class for saving and deploying model saving and deploying. Check https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html",
177+
)
174178
def predict(self, X):
175179
"""
176180
Runs the models predict function on some data
177181
178182
Parameters
179183
----------
180-
X: MLData
181-
A MLData object which holds the examples to be predicted on.
184+
X: ADSData
185+
A ADSData object which holds the examples to be predicted on.
182186
183187
Returns
184188
-------
@@ -202,8 +206,8 @@ def predict_proba(self, X):
202206
203207
Parameters
204208
----------
205-
X: MLData
206-
A MLData object which holds the examples to be predicted on.
209+
X: ADSData
210+
A ADSData object which holds the examples to be predicted on.
207211
208212
Returns
209213
-------
@@ -218,16 +222,20 @@ def predict_proba(self, X):
218222
else:
219223
return self.est.predict_proba(X)
220224

225+
@deprecated(
226+
"2.6.6",
227+
details="Use framework specific Model utility class for saving and deploying model saving and deploying. Check https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html",
228+
)
221229
def score(self, X, y_true, score_fn=None):
222230
"""
223231
Scores a model according to a custom score function
224232
225233
Parameters
226234
----------
227-
X: MLData
228-
A MLData object which holds the examples to be predicted on.
229-
y_true: MLData
230-
A MLData object which holds ground truth labels for the examples which are being predicted on.
235+
X: ADSData
236+
A ADSData object which holds the examples to be predicted on.
237+
y_true: ADSData
238+
A ADSData object which holds ground truth labels for the examples which are being predicted on.
231239
score_fn: Scorer (callable)
232240
A callable object that returns a score, usually created with sklearn.metrics.make_scorer().
233241
@@ -250,6 +258,10 @@ def score(self, X, y_true, score_fn=None):
250258
else:
251259
return self.est.score(X, y_true)
252260

261+
@deprecated(
262+
"2.6.6",
263+
details="Use framework specific Model utility class for saving and deploying model saving and deploying. Check https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html",
264+
)
253265
def summary(self):
254266
"""
255267
A summary of the ADSModel
@@ -274,14 +286,18 @@ def __repr__(self):
274286
def __getattr__(self, item):
275287
return getattr(self.est, item)
276288

289+
@deprecated(
290+
"2.6.6",
291+
details="Use framework specific Model utility class for saving and deploying model saving and deploying. Check https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html",
292+
)
277293
def transform(self, X):
278294
"""
279-
Process some MLData through the selected ADSModel transformers
295+
Process some ADSData through the selected ADSModel transformers
280296
281297
Parameters
282298
----------
283-
X: MLData
284-
A MLData object which holds the examples to be transformed.
299+
X: ADSData
300+
A ADSData object which holds the examples to be transformed.
285301
"""
286302

287303
if hasattr(X, "copy"):
@@ -310,6 +326,10 @@ def is_classifier(self):
310326
"""
311327
return hasattr(self, "classes_") and self.classes_ is not None
312328

329+
@deprecated(
330+
"2.6.6",
331+
details="Use framework specific Model utility class for saving and deploying model saving and deploying. Check https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html",
332+
)
313333
def feature_names(self, X=None):
314334
model_type = self._underlying_model
315335
if model_type == "sklearn":
@@ -367,6 +387,10 @@ def __getstate__(self):
367387
def __setstate__(self, state):
368388
self.__dict__ = state
369389

390+
@deprecated(
391+
"2.6.6",
392+
details="Use framework specific Model utility class for saving and deploying model saving and deploying. Check https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html",
393+
)
370394
def prepare(
371395
self,
372396
target_dir=None,

0 commit comments

Comments
 (0)