snowflake-ml-python 1.18.0__py3-none-any.whl → 1.19.0__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.
- snowflake/ml/experiment/_client/experiment_tracking_sql_client.py +1 -7
- snowflake/ml/experiment/experiment_tracking.py +31 -63
- snowflake/ml/feature_store/feature_store.py +85 -30
- snowflake/ml/feature_store/feature_view.py +12 -6
- snowflake/ml/fileset/stage_fs.py +12 -1
- snowflake/ml/jobs/job.py +3 -3
- snowflake/ml/jobs/manager.py +6 -6
- snowflake/ml/model/_client/ops/model_ops.py +11 -4
- snowflake/ml/model/_packager/model_runtime/_snowml_inference_alternative_requirements.py +1 -1
- snowflake/ml/monitoring/explain_visualize.py +3 -1
- snowflake/ml/version.py +1 -1
- {snowflake_ml_python-1.18.0.dist-info → snowflake_ml_python-1.19.0.dist-info}/METADATA +26 -4
- {snowflake_ml_python-1.18.0.dist-info → snowflake_ml_python-1.19.0.dist-info}/RECORD +16 -16
- {snowflake_ml_python-1.18.0.dist-info → snowflake_ml_python-1.19.0.dist-info}/WHEEL +0 -0
- {snowflake_ml_python-1.18.0.dist-info → snowflake_ml_python-1.19.0.dist-info}/licenses/LICENSE.txt +0 -0
- {snowflake_ml_python-1.18.0.dist-info → snowflake_ml_python-1.19.0.dist-info}/top_level.txt +0 -0
|
@@ -128,13 +128,7 @@ class ExperimentTrackingSQLClient(_base._BaseSQLClient):
|
|
|
128
128
|
run_name: sql_identifier.SqlIdentifier,
|
|
129
129
|
artifact_path: str,
|
|
130
130
|
) -> list[artifact.ArtifactInfo]:
|
|
131
|
-
results = (
|
|
132
|
-
query_result_checker.SqlResultValidator(
|
|
133
|
-
self._session, f"LIST {self._build_snow_uri(experiment_name, run_name, artifact_path)}"
|
|
134
|
-
)
|
|
135
|
-
.has_dimensions(expected_cols=4)
|
|
136
|
-
.validate()
|
|
137
|
-
)
|
|
131
|
+
results = self._session.sql(f"LIST {self._build_snow_uri(experiment_name, run_name, artifact_path)}").collect()
|
|
138
132
|
return [
|
|
139
133
|
artifact.ArtifactInfo(
|
|
140
134
|
name=str(result.name).removeprefix(f"/versions/{run_name}/"),
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import json
|
|
3
3
|
import sys
|
|
4
|
-
from typing import Any,
|
|
4
|
+
from typing import Any, Optional, Union
|
|
5
5
|
from urllib.parse import quote
|
|
6
6
|
|
|
7
7
|
from snowflake import snowpark
|
|
8
8
|
from snowflake.ml import model as ml_model, registry
|
|
9
9
|
from snowflake.ml._internal.human_readable_id import hrid_generator
|
|
10
|
-
from snowflake.ml._internal.utils import
|
|
10
|
+
from snowflake.ml._internal.utils import connection_params, sql_identifier
|
|
11
11
|
from snowflake.ml.experiment import (
|
|
12
12
|
_entities as entities,
|
|
13
13
|
_experiment_info as experiment_info,
|
|
@@ -21,34 +21,12 @@ from snowflake.ml.utils import sql_client as sql_client_utils
|
|
|
21
21
|
|
|
22
22
|
DEFAULT_EXPERIMENT_NAME = sql_identifier.SqlIdentifier("DEFAULT")
|
|
23
23
|
|
|
24
|
-
P = ParamSpec("P")
|
|
25
|
-
T = TypeVar("T")
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
def _restore_session(
|
|
29
|
-
func: Callable[Concatenate["ExperimentTracking", P], T],
|
|
30
|
-
) -> Callable[Concatenate["ExperimentTracking", P], T]:
|
|
31
|
-
@functools.wraps(func)
|
|
32
|
-
def wrapper(self: "ExperimentTracking", /, *args: P.args, **kwargs: P.kwargs) -> T:
|
|
33
|
-
if self._session is None:
|
|
34
|
-
if self._session_state is None:
|
|
35
|
-
raise RuntimeError(
|
|
36
|
-
f"Session is not set before calling {func.__name__}, and there is no session state to restore from"
|
|
37
|
-
)
|
|
38
|
-
self._set_session(self._session_state)
|
|
39
|
-
if self._session is None:
|
|
40
|
-
raise RuntimeError(f"Failed to restore session before calling {func.__name__}")
|
|
41
|
-
return func(self, *args, **kwargs)
|
|
42
|
-
|
|
43
|
-
return wrapper
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
25
|
+
class ExperimentTracking:
|
|
47
26
|
"""
|
|
48
27
|
Class to manage experiments in Snowflake.
|
|
49
28
|
"""
|
|
50
29
|
|
|
51
|
-
@snowpark._internal.utils.private_preview(version="1.9.1")
|
|
52
30
|
def __init__(
|
|
53
31
|
self,
|
|
54
32
|
session: snowpark.Session,
|
|
@@ -93,10 +71,7 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
93
71
|
database_name=self._database_name,
|
|
94
72
|
schema_name=self._schema_name,
|
|
95
73
|
)
|
|
96
|
-
self._session
|
|
97
|
-
# Used to store information about the session if the session could not be restored during unpickling
|
|
98
|
-
# _session_state is None if and only if _session is not None
|
|
99
|
-
self._session_state: Optional[mixins._SessionState] = None
|
|
74
|
+
self._session = session
|
|
100
75
|
|
|
101
76
|
# The experiment in context
|
|
102
77
|
self._experiment: Optional[entities.Experiment] = None
|
|
@@ -104,35 +79,40 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
104
79
|
self._run: Optional[entities.Run] = None
|
|
105
80
|
|
|
106
81
|
def __getstate__(self) -> dict[str, Any]:
|
|
107
|
-
|
|
82
|
+
parent_state = (
|
|
83
|
+
super().__getstate__() # type: ignore[misc] # object.__getstate__ appears in 3.11
|
|
84
|
+
if hasattr(super(), "__getstate__")
|
|
85
|
+
else self.__dict__
|
|
86
|
+
)
|
|
87
|
+
state = dict(parent_state) # Create a copy so we can safely modify the state
|
|
88
|
+
|
|
108
89
|
# Remove unpicklable attributes
|
|
90
|
+
state["_session"] = None
|
|
109
91
|
state["_sql_client"] = None
|
|
110
92
|
state["_registry"] = None
|
|
111
93
|
return state
|
|
112
94
|
|
|
113
|
-
def
|
|
114
|
-
|
|
115
|
-
super().
|
|
116
|
-
assert self._session is not None
|
|
117
|
-
except (snowpark.exceptions.SnowparkSessionException, AssertionError):
|
|
118
|
-
# If session was not set, store the session state
|
|
119
|
-
self._session = None
|
|
120
|
-
self._session_state = session_state
|
|
95
|
+
def __setstate__(self, state: dict[str, Any]) -> None:
|
|
96
|
+
if hasattr(super(), "__setstate__"):
|
|
97
|
+
super().__setstate__(state) # type: ignore[misc]
|
|
121
98
|
else:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
self.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
99
|
+
self.__dict__.update(state)
|
|
100
|
+
|
|
101
|
+
# Restore unpicklable attributes
|
|
102
|
+
options: dict[str, Any] = connection_params.SnowflakeLoginOptions()
|
|
103
|
+
options["client_session_keep_alive"] = True # Needed for long-running training jobs
|
|
104
|
+
self._session = snowpark.Session.builder.configs(options).getOrCreate()
|
|
105
|
+
self._sql_client = sql_client.ExperimentTrackingSQLClient(
|
|
106
|
+
session=self._session,
|
|
107
|
+
database_name=self._database_name,
|
|
108
|
+
schema_name=self._schema_name,
|
|
109
|
+
)
|
|
110
|
+
self._registry = registry.Registry(
|
|
111
|
+
session=self._session,
|
|
112
|
+
database_name=self._database_name,
|
|
113
|
+
schema_name=self._schema_name,
|
|
114
|
+
)
|
|
134
115
|
|
|
135
|
-
@_restore_session
|
|
136
116
|
def set_experiment(
|
|
137
117
|
self,
|
|
138
118
|
experiment_name: str,
|
|
@@ -157,7 +137,6 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
157
137
|
self._run = None
|
|
158
138
|
return self._experiment
|
|
159
139
|
|
|
160
|
-
@_restore_session
|
|
161
140
|
def delete_experiment(
|
|
162
141
|
self,
|
|
163
142
|
experiment_name: str,
|
|
@@ -174,10 +153,8 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
174
153
|
self._run = None
|
|
175
154
|
|
|
176
155
|
@functools.wraps(registry.Registry.log_model)
|
|
177
|
-
@_restore_session
|
|
178
156
|
def log_model(
|
|
179
157
|
self,
|
|
180
|
-
/, # self needs to be a positional argument to stop mypy from complaining
|
|
181
158
|
model: Union[type_hints.SupportedModelType, ml_model.ModelVersion],
|
|
182
159
|
*,
|
|
183
160
|
model_name: str,
|
|
@@ -187,7 +164,6 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
187
164
|
with experiment_info.ExperimentInfoPatcher(experiment_info=run._get_experiment_info()):
|
|
188
165
|
return self._registry.log_model(model, model_name=model_name, **kwargs)
|
|
189
166
|
|
|
190
|
-
@_restore_session
|
|
191
167
|
def start_run(
|
|
192
168
|
self,
|
|
193
169
|
run_name: Optional[str] = None,
|
|
@@ -229,7 +205,6 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
229
205
|
self._run = entities.Run(experiment_tracking=self, experiment_name=experiment.name, run_name=run_name)
|
|
230
206
|
return self._run
|
|
231
207
|
|
|
232
|
-
@_restore_session
|
|
233
208
|
def end_run(self, run_name: Optional[str] = None) -> None:
|
|
234
209
|
"""
|
|
235
210
|
End the current run if no run name is provided. Otherwise, the specified run is ended.
|
|
@@ -259,7 +234,6 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
259
234
|
self._run = None
|
|
260
235
|
self._print_urls(experiment_name=experiment_name, run_name=run_name)
|
|
261
236
|
|
|
262
|
-
@_restore_session
|
|
263
237
|
def delete_run(
|
|
264
238
|
self,
|
|
265
239
|
run_name: str,
|
|
@@ -298,7 +272,6 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
298
272
|
"""
|
|
299
273
|
self.log_metrics(metrics={key: value}, step=step)
|
|
300
274
|
|
|
301
|
-
@_restore_session
|
|
302
275
|
def log_metrics(
|
|
303
276
|
self,
|
|
304
277
|
metrics: dict[str, float],
|
|
@@ -335,7 +308,6 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
335
308
|
"""
|
|
336
309
|
self.log_params({key: value})
|
|
337
310
|
|
|
338
|
-
@_restore_session
|
|
339
311
|
def log_params(
|
|
340
312
|
self,
|
|
341
313
|
params: dict[str, Any],
|
|
@@ -357,7 +329,6 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
357
329
|
params=json.dumps([param.to_dict() for param in params_list]),
|
|
358
330
|
)
|
|
359
331
|
|
|
360
|
-
@_restore_session
|
|
361
332
|
def log_artifact(
|
|
362
333
|
self,
|
|
363
334
|
local_path: str,
|
|
@@ -381,7 +352,6 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
381
352
|
file_path=file_path,
|
|
382
353
|
)
|
|
383
354
|
|
|
384
|
-
@_restore_session
|
|
385
355
|
def list_artifacts(
|
|
386
356
|
self,
|
|
387
357
|
run_name: str,
|
|
@@ -410,7 +380,6 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
410
380
|
artifact_path=artifact_path or "",
|
|
411
381
|
)
|
|
412
382
|
|
|
413
|
-
@_restore_session
|
|
414
383
|
def download_artifacts(
|
|
415
384
|
self,
|
|
416
385
|
run_name: str,
|
|
@@ -452,7 +421,6 @@ class ExperimentTracking(mixins.SerializableSessionMixin):
|
|
|
452
421
|
return self._run
|
|
453
422
|
return self.start_run()
|
|
454
423
|
|
|
455
|
-
@_restore_session
|
|
456
424
|
def _generate_run_name(self, experiment: entities.Experiment) -> sql_identifier.SqlIdentifier:
|
|
457
425
|
generator = hrid_generator.HRID16()
|
|
458
426
|
existing_runs = self._sql_client.show_runs_in_experiment(experiment_name=experiment.name)
|
|
@@ -474,8 +474,8 @@ class FeatureStore:
|
|
|
474
474
|
feature_view: FeatureView instance to materialize.
|
|
475
475
|
version: version of the registered FeatureView.
|
|
476
476
|
NOTE: Version only accepts letters, numbers and underscore. Also version will be capitalized.
|
|
477
|
-
block:
|
|
478
|
-
|
|
477
|
+
block: Deprecated. To make the initial refresh asynchronous, set the `initialize`
|
|
478
|
+
argument on the `FeatureView` to `"ON_SCHEDULE"`. Default is true.
|
|
479
479
|
overwrite: Overwrite the existing FeatureView with same version. This is the same as dropping the
|
|
480
480
|
FeatureView first then recreate. NOTE: there will be backfill cost associated if the FeatureView is
|
|
481
481
|
being continuously maintained.
|
|
@@ -521,6 +521,15 @@ class FeatureStore:
|
|
|
521
521
|
"""
|
|
522
522
|
version = FeatureViewVersion(version)
|
|
523
523
|
|
|
524
|
+
if block is False:
|
|
525
|
+
raise snowml_exceptions.SnowflakeMLException(
|
|
526
|
+
error_code=error_codes.INVALID_ARGUMENT,
|
|
527
|
+
original_exception=ValueError(
|
|
528
|
+
'block=False is deprecated. Use FeatureView(..., initialize="ON_SCHEDULE") '
|
|
529
|
+
"for async initial refresh."
|
|
530
|
+
),
|
|
531
|
+
)
|
|
532
|
+
|
|
524
533
|
if feature_view.status != FeatureViewStatus.DRAFT:
|
|
525
534
|
try:
|
|
526
535
|
return self._get_feature_view_if_exists(feature_view.name, str(version))
|
|
@@ -2094,26 +2103,48 @@ class FeatureStore:
|
|
|
2094
2103
|
def _plan_online_update(
|
|
2095
2104
|
self, feature_view: FeatureView, online_config: Optional[fv_mod.OnlineConfig]
|
|
2096
2105
|
) -> _OnlineUpdateStrategy:
|
|
2097
|
-
"""Plan online update operations based on current state and target config.
|
|
2106
|
+
"""Plan online update operations based on current state and target config.
|
|
2107
|
+
|
|
2108
|
+
Handles three cases:
|
|
2109
|
+
- enable is None: Preserve current online state, only update if currently online
|
|
2110
|
+
- enable is True: Enable online storage (create if needed, update if exists)
|
|
2111
|
+
- enable is False: Disable online storage (drop if exists)
|
|
2112
|
+
|
|
2113
|
+
Args:
|
|
2114
|
+
feature_view: The FeatureView object to check current online state.
|
|
2115
|
+
online_config: The OnlineConfig with target enable and lag settings.
|
|
2116
|
+
|
|
2117
|
+
Returns:
|
|
2118
|
+
_OnlineUpdateStrategy containing operations and their rollbacks.
|
|
2119
|
+
"""
|
|
2098
2120
|
if online_config is None:
|
|
2099
2121
|
return self._OnlineUpdateStrategy([], [], None)
|
|
2100
2122
|
|
|
2101
2123
|
current_online = feature_view.online
|
|
2102
2124
|
target_online = online_config.enable
|
|
2103
2125
|
|
|
2104
|
-
#
|
|
2126
|
+
# Case 1: enable is None - preserve current online state, only update if currently online
|
|
2127
|
+
if target_online is None:
|
|
2128
|
+
if current_online and (online_config.target_lag is not None):
|
|
2129
|
+
# Online is currently enabled and user wants to update lag
|
|
2130
|
+
return self._plan_online_update_existing(feature_view, online_config)
|
|
2131
|
+
else:
|
|
2132
|
+
# No online changes needed (either not online, or lag not specified)
|
|
2133
|
+
return self._OnlineUpdateStrategy([], [], None)
|
|
2134
|
+
|
|
2135
|
+
# Case 2: Enable online (create table)
|
|
2105
2136
|
if target_online and not current_online:
|
|
2106
2137
|
return self._plan_online_enable(feature_view, online_config)
|
|
2107
2138
|
|
|
2108
|
-
# Disable online (drop table)
|
|
2139
|
+
# Case 3: Disable online (drop table)
|
|
2109
2140
|
elif not target_online and current_online:
|
|
2110
2141
|
return self._plan_online_disable(feature_view)
|
|
2111
2142
|
|
|
2112
|
-
# Update existing online table
|
|
2143
|
+
# Case 4: Update existing online table
|
|
2113
2144
|
elif target_online and current_online:
|
|
2114
2145
|
return self._plan_online_update_existing(feature_view, online_config)
|
|
2115
2146
|
|
|
2116
|
-
# No change needed
|
|
2147
|
+
# Case 5: No change needed
|
|
2117
2148
|
else:
|
|
2118
2149
|
return self._OnlineUpdateStrategy([], [], online_config)
|
|
2119
2150
|
|
|
@@ -2621,9 +2652,10 @@ class FeatureStore:
|
|
|
2621
2652
|
|
|
2622
2653
|
This method supports feature views with different join keys by:
|
|
2623
2654
|
1. Creating a spine CTE that includes all possible join keys
|
|
2624
|
-
2.
|
|
2625
|
-
3. Performing
|
|
2626
|
-
4.
|
|
2655
|
+
2. For each feature view, creating a deduplicated spine subquery with only that FV's join keys
|
|
2656
|
+
3. Performing ASOF JOINs on the deduplicated spine when timestamp columns exist
|
|
2657
|
+
4. Performing LEFT JOINs on the deduplicated spine when timestamp columns are missing
|
|
2658
|
+
5. Combining results by LEFT JOINing each FV CTE back to the original SPINE
|
|
2627
2659
|
|
|
2628
2660
|
Args:
|
|
2629
2661
|
feature_views: A list of feature views to join.
|
|
@@ -2633,9 +2665,6 @@ class FeatureStore:
|
|
|
2633
2665
|
include_feature_view_timestamp_col: Whether to include the timestamp column of
|
|
2634
2666
|
the feature view in the result. Default to false.
|
|
2635
2667
|
|
|
2636
|
-
Note: This method does NOT work when there are duplicate combinations of join keys and timestamp columns
|
|
2637
|
-
in spine.
|
|
2638
|
-
|
|
2639
2668
|
Returns:
|
|
2640
2669
|
A SQL query string with CTE structure for joining feature views.
|
|
2641
2670
|
"""
|
|
@@ -2659,11 +2688,17 @@ class FeatureStore:
|
|
|
2659
2688
|
fv_join_keys = list({k for e in feature_view.entities for k in e.join_keys})
|
|
2660
2689
|
join_keys_str = ", ".join(fv_join_keys)
|
|
2661
2690
|
|
|
2662
|
-
# Build the JOIN condition using only this feature view's join keys
|
|
2663
|
-
join_conditions = [f'SPINE."{col}" = FEATURE."{col}"' for col in fv_join_keys]
|
|
2664
|
-
|
|
2665
2691
|
# Use ASOF JOIN if both spine and feature view have timestamp columns, otherwise use LEFT JOIN
|
|
2666
2692
|
if spine_timestamp_col is not None and feature_timestamp_col is not None:
|
|
2693
|
+
# Build the deduplicated spine columns set (join keys + timestamp)
|
|
2694
|
+
spine_dedup_cols_set = set(fv_join_keys)
|
|
2695
|
+
if spine_timestamp_col not in spine_dedup_cols_set:
|
|
2696
|
+
spine_dedup_cols_set.add(spine_timestamp_col)
|
|
2697
|
+
spine_dedup_cols_str = ", ".join(f'"{col}"' for col in spine_dedup_cols_set)
|
|
2698
|
+
|
|
2699
|
+
# Build the JOIN condition using only this feature view's join keys
|
|
2700
|
+
join_conditions_dedup = [f'SPINE_DEDUP."{col}" = FEATURE."{col}"' for col in fv_join_keys]
|
|
2701
|
+
|
|
2667
2702
|
if include_feature_view_timestamp_col:
|
|
2668
2703
|
f_ts_col_alias = identifier.concat_names(
|
|
2669
2704
|
[feature_view.name, "_", str(feature_view.version), "_", feature_timestamp_col]
|
|
@@ -2674,36 +2709,46 @@ class FeatureStore:
|
|
|
2674
2709
|
ctes.append(
|
|
2675
2710
|
f"""{cte_name} AS (
|
|
2676
2711
|
SELECT
|
|
2677
|
-
|
|
2712
|
+
SPINE_DEDUP.*,
|
|
2678
2713
|
{f_ts_col_str}
|
|
2679
2714
|
FEATURE.* EXCLUDE ({join_keys_str}, {feature_timestamp_col})
|
|
2680
|
-
FROM
|
|
2681
|
-
|
|
2715
|
+
FROM (
|
|
2716
|
+
SELECT DISTINCT {spine_dedup_cols_str}
|
|
2717
|
+
FROM SPINE
|
|
2718
|
+
) SPINE_DEDUP
|
|
2682
2719
|
ASOF JOIN (
|
|
2683
2720
|
SELECT {join_keys_str}, {feature_timestamp_col}, {feature_columns[i]}
|
|
2684
2721
|
FROM {feature_view.fully_qualified_name()}
|
|
2685
2722
|
) FEATURE
|
|
2686
|
-
MATCH_CONDITION (
|
|
2687
|
-
ON {" AND ".join(
|
|
2723
|
+
MATCH_CONDITION (SPINE_DEDUP."{spine_timestamp_col}" >= FEATURE."{feature_timestamp_col}")
|
|
2724
|
+
ON {" AND ".join(join_conditions_dedup)}
|
|
2688
2725
|
)"""
|
|
2689
2726
|
)
|
|
2690
2727
|
else:
|
|
2728
|
+
# Build the deduplicated spine columns list (just join keys, no timestamp)
|
|
2729
|
+
spine_dedup_cols_str = ", ".join(f'"{col}"' for col in fv_join_keys)
|
|
2730
|
+
|
|
2731
|
+
# Build the JOIN condition using only this feature view's join keys
|
|
2732
|
+
join_conditions_dedup = [f'SPINE_DEDUP."{col}" = FEATURE."{col}"' for col in fv_join_keys]
|
|
2733
|
+
|
|
2691
2734
|
ctes.append(
|
|
2692
2735
|
f"""{cte_name} AS (
|
|
2693
2736
|
SELECT
|
|
2694
|
-
|
|
2737
|
+
SPINE_DEDUP.*,
|
|
2695
2738
|
FEATURE.* EXCLUDE ({join_keys_str})
|
|
2696
|
-
FROM
|
|
2697
|
-
|
|
2739
|
+
FROM (
|
|
2740
|
+
SELECT DISTINCT {spine_dedup_cols_str}
|
|
2741
|
+
FROM SPINE
|
|
2742
|
+
) SPINE_DEDUP
|
|
2698
2743
|
LEFT JOIN (
|
|
2699
2744
|
SELECT {join_keys_str}, {feature_columns[i]}
|
|
2700
2745
|
FROM {feature_view.fully_qualified_name()}
|
|
2701
2746
|
) FEATURE
|
|
2702
|
-
ON {" AND ".join(
|
|
2747
|
+
ON {" AND ".join(join_conditions_dedup)}
|
|
2703
2748
|
)"""
|
|
2704
2749
|
)
|
|
2705
2750
|
|
|
2706
|
-
# Build final SELECT with
|
|
2751
|
+
# Build final SELECT with LEFT joins to each FV CTE
|
|
2707
2752
|
select_columns = []
|
|
2708
2753
|
join_clauses = []
|
|
2709
2754
|
|
|
@@ -2711,19 +2756,29 @@ class FeatureStore:
|
|
|
2711
2756
|
feature_view = feature_views[i]
|
|
2712
2757
|
fv_join_keys = list({k for e in feature_view.entities for k in e.join_keys})
|
|
2713
2758
|
join_conditions = [f'SPINE."{col}" = {cte_name}."{col}"' for col in fv_join_keys]
|
|
2714
|
-
if
|
|
2759
|
+
# Only include spine timestamp in join condition if both spine and FV have timestamps
|
|
2760
|
+
if spine_timestamp_col is not None and feature_view.timestamp_col is not None:
|
|
2715
2761
|
join_conditions.append(f'SPINE."{spine_timestamp_col}" = {cte_name}."{spine_timestamp_col}"')
|
|
2762
|
+
|
|
2716
2763
|
if include_feature_view_timestamp_col and feature_view.timestamp_col is not None:
|
|
2717
2764
|
f_ts_col_alias = identifier.concat_names(
|
|
2718
2765
|
[feature_view.name, "_", str(feature_view.version), "_", feature_view.timestamp_col]
|
|
2719
2766
|
)
|
|
2720
2767
|
f_ts_col_str = f"{cte_name}.{f_ts_col_alias} AS {f_ts_col_alias}"
|
|
2721
2768
|
select_columns.append(f_ts_col_str)
|
|
2722
|
-
|
|
2769
|
+
|
|
2770
|
+
# Select features from the CTE
|
|
2771
|
+
# feature_columns[i] is already a comma-separated string of column names
|
|
2772
|
+
feature_cols_from_cte = []
|
|
2773
|
+
for col in feature_columns[i].split(", "):
|
|
2774
|
+
col_clean = col.strip()
|
|
2775
|
+
feature_cols_from_cte.append(f"{cte_name}.{col_clean}")
|
|
2776
|
+
select_columns.extend(feature_cols_from_cte)
|
|
2777
|
+
|
|
2723
2778
|
# Create join condition using only this feature view's join keys
|
|
2724
2779
|
join_clauses.append(
|
|
2725
2780
|
f"""
|
|
2726
|
-
|
|
2781
|
+
LEFT JOIN {cte_name}
|
|
2727
2782
|
ON {" AND ".join(join_conditions)}"""
|
|
2728
2783
|
)
|
|
2729
2784
|
|
|
@@ -3388,7 +3443,7 @@ FROM SPINE{' '.join(join_clauses)}
|
|
|
3388
3443
|
online_table_name = FeatureView._get_online_table_name(feature_view_name)
|
|
3389
3444
|
|
|
3390
3445
|
fully_qualified_online_name = self._get_fully_qualified_name(online_table_name)
|
|
3391
|
-
source_table_name = feature_view_name
|
|
3446
|
+
source_table_name = self._get_fully_qualified_name(feature_view_name)
|
|
3392
3447
|
|
|
3393
3448
|
# Extract join keys for PRIMARY KEY (preserve order and ensure unique)
|
|
3394
3449
|
ordered_join_keys: list[str] = []
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
"""Feature view module for Snowflake ML Feature Store."""
|
|
1
2
|
from __future__ import annotations
|
|
2
3
|
|
|
3
4
|
import json
|
|
4
|
-
import logging
|
|
5
5
|
import re
|
|
6
6
|
import warnings
|
|
7
7
|
from collections import OrderedDict
|
|
@@ -52,7 +52,7 @@ _RESULT_SCAN_QUERY_PATTERN = re.compile(
|
|
|
52
52
|
class OnlineConfig:
|
|
53
53
|
"""Configuration for online feature storage."""
|
|
54
54
|
|
|
55
|
-
enable: bool =
|
|
55
|
+
enable: Optional[bool] = None
|
|
56
56
|
target_lag: Optional[str] = None
|
|
57
57
|
|
|
58
58
|
def __post_init__(self) -> None:
|
|
@@ -248,6 +248,7 @@ class FeatureView(lineage_node.LineageNode):
|
|
|
248
248
|
- If `timestamp_col` is provided, it is added to the default clustering keys.
|
|
249
249
|
online_config: Optional configuration for online storage. If provided with enable=True,
|
|
250
250
|
online storage will be enabled. Defaults to None (no online storage).
|
|
251
|
+
NOTE: this feature is currently in Public Preview.
|
|
251
252
|
_kwargs: reserved kwargs for system generated args. NOTE: DO NOT USE.
|
|
252
253
|
|
|
253
254
|
Example::
|
|
@@ -289,8 +290,6 @@ class FeatureView(lineage_node.LineageNode):
|
|
|
289
290
|
|
|
290
291
|
# noqa: DAR401
|
|
291
292
|
"""
|
|
292
|
-
if online_config is not None:
|
|
293
|
-
logging.warning("'online_config' is in private preview since 1.12.0. Do not use it in production.")
|
|
294
293
|
|
|
295
294
|
self._name: SqlIdentifier = SqlIdentifier(name)
|
|
296
295
|
self._entities: list[Entity] = entities
|
|
@@ -533,8 +532,15 @@ class FeatureView(lineage_node.LineageNode):
|
|
|
533
532
|
return self._feature_desc
|
|
534
533
|
|
|
535
534
|
@property
|
|
536
|
-
def online(self) -> bool:
|
|
537
|
-
|
|
535
|
+
def online(self) -> bool: # noqa: DAR101
|
|
536
|
+
"""Check if online storage is enabled for this feature view.
|
|
537
|
+
|
|
538
|
+
Returns:
|
|
539
|
+
True if online storage is enabled, False otherwise.
|
|
540
|
+
"""
|
|
541
|
+
if self._online_config and self._online_config.enable is True:
|
|
542
|
+
return True
|
|
543
|
+
return False
|
|
538
544
|
|
|
539
545
|
@property
|
|
540
546
|
def online_config(self) -> Optional[OnlineConfig]:
|
snowflake/ml/fileset/stage_fs.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
import logging
|
|
3
|
+
import re
|
|
3
4
|
import time
|
|
4
5
|
from dataclasses import dataclass
|
|
5
6
|
from typing import Any, Optional, Union, cast
|
|
@@ -27,6 +28,8 @@ _PRESIGNED_URL_LIFETIME_SEC = 14400
|
|
|
27
28
|
# The threshold of when the presigned url should get refreshed before its expiration.
|
|
28
29
|
_PRESIGNED_URL_HEADROOM_SEC = 3600
|
|
29
30
|
|
|
31
|
+
# Regex pattern to match cloud storage prefixes (s3://, gcs://, azure://) and bucket/container name at start of string
|
|
32
|
+
_CLOUD_PATH_PREFIX_PATTERN = re.compile(r"^(s3|gcs|azure)://[^/]+/", re.IGNORECASE)
|
|
30
33
|
|
|
31
34
|
_PROJECT = "FileSet"
|
|
32
35
|
|
|
@@ -355,8 +358,16 @@ class SFStageFileSystem(fsspec.AbstractFileSystem):
|
|
|
355
358
|
|
|
356
359
|
Returns:
|
|
357
360
|
A string of the relative stage path.
|
|
361
|
+
|
|
362
|
+
Raises:
|
|
363
|
+
ValueError: If the stage path format is invalid.
|
|
358
364
|
"""
|
|
359
|
-
|
|
365
|
+
if stage_path.lower().startswith(self._stage.lower()):
|
|
366
|
+
return stage_path[len(self._stage) + 1 :]
|
|
367
|
+
elif match := _CLOUD_PATH_PREFIX_PATTERN.match(stage_path):
|
|
368
|
+
return stage_path[match.end() :]
|
|
369
|
+
|
|
370
|
+
raise ValueError(f"Invalid stage path: {stage_path}")
|
|
360
371
|
|
|
361
372
|
def _add_file_info_helper(
|
|
362
373
|
self,
|
snowflake/ml/jobs/job.py
CHANGED
|
@@ -109,11 +109,11 @@ class MLJob(Generic[T], SerializableSessionMixin):
|
|
|
109
109
|
return cast(dict[str, Any], container_spec)
|
|
110
110
|
|
|
111
111
|
@property
|
|
112
|
-
def _stage_path(self) -> str:
|
|
112
|
+
def _stage_path(self) -> Optional[str]:
|
|
113
113
|
"""Get the job's artifact storage stage location."""
|
|
114
114
|
volumes = self._service_spec["spec"]["volumes"]
|
|
115
|
-
|
|
116
|
-
return cast(str,
|
|
115
|
+
stage_volume = next((v for v in volumes if v["name"] == constants.STAGE_VOLUME_NAME), None)
|
|
116
|
+
return cast(str, stage_volume["source"]) if stage_volume else None
|
|
117
117
|
|
|
118
118
|
@property
|
|
119
119
|
def _result_path(self) -> str:
|
snowflake/ml/jobs/manager.py
CHANGED
|
@@ -192,12 +192,12 @@ def delete_job(job: Union[str, jb.MLJob[Any]], session: Optional[snowpark.Sessio
|
|
|
192
192
|
"""Delete a job service from the backend. Status and logs will be lost."""
|
|
193
193
|
job = job if isinstance(job, jb.MLJob) else get_job(job, session=session)
|
|
194
194
|
session = job._session
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
195
|
+
if job._stage_path:
|
|
196
|
+
try:
|
|
197
|
+
session.sql(f"REMOVE {job._stage_path}/").collect()
|
|
198
|
+
logger.debug(f"Successfully cleaned up stage files for job {job.id} at {job._stage_path}")
|
|
199
|
+
except Exception as e:
|
|
200
|
+
logger.warning(f"Failed to clean up stage files for job {job.id}: {e}")
|
|
201
201
|
query_helper.run_query(session, "DROP SERVICE IDENTIFIER(?)", params=(job.id,))
|
|
202
202
|
|
|
203
203
|
|
|
@@ -515,10 +515,17 @@ class ModelOperator:
|
|
|
515
515
|
statement_params=statement_params,
|
|
516
516
|
)
|
|
517
517
|
for r in res:
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
518
|
+
aliases_data = r[self._model_client.MODEL_VERSION_ALIASES_COL_NAME]
|
|
519
|
+
if aliases_data:
|
|
520
|
+
aliases_list = json.loads(aliases_data)
|
|
521
|
+
|
|
522
|
+
# Compare using Snowflake identifier semantics for exact match
|
|
523
|
+
for alias in aliases_list:
|
|
524
|
+
if sql_identifier.SqlIdentifier(alias) == alias_name:
|
|
525
|
+
return sql_identifier.SqlIdentifier(
|
|
526
|
+
r[self._model_client.MODEL_VERSION_NAME_COL_NAME], case_sensitive=True
|
|
527
|
+
)
|
|
528
|
+
|
|
522
529
|
return None
|
|
523
530
|
|
|
524
531
|
def get_tag_value(
|
|
@@ -24,7 +24,7 @@ REQUIREMENTS = [
|
|
|
24
24
|
"scikit-learn<1.8",
|
|
25
25
|
"scipy>=1.9,<2",
|
|
26
26
|
"shap>=0.46.0,<1",
|
|
27
|
-
"snowflake-connector-python>=3.17.
|
|
27
|
+
"snowflake-connector-python>=3.17.3,<4",
|
|
28
28
|
"snowflake-snowpark-python>=1.17.0,<2,!=1.26.0",
|
|
29
29
|
"snowflake.core>=1.0.2,<2",
|
|
30
30
|
"sqlparse>=0.4,<1",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import uuid
|
|
1
2
|
from typing import Any, Union, cast, overload
|
|
2
3
|
|
|
3
4
|
import altair as alt
|
|
@@ -319,7 +320,8 @@ def _prepare_feature_values_for_streamlit(
|
|
|
319
320
|
import streamlit as st
|
|
320
321
|
|
|
321
322
|
feature_columns = feature_values_df.columns
|
|
322
|
-
|
|
323
|
+
unique_key = f"ml-explain-feature-select-{uuid.uuid4()}"
|
|
324
|
+
chosen_ft: str = st.selectbox("Feature:", feature_columns, key=unique_key)
|
|
323
325
|
feature_values = feature_values_df[chosen_ft]
|
|
324
326
|
shap_values = shap_values.iloc[:, feature_columns.get_loc(chosen_ft)]
|
|
325
327
|
return feature_values, shap_values, st
|
snowflake/ml/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# This is parsed by regex in conda recipe meta file. Make sure not to break it.
|
|
2
|
-
VERSION = "1.
|
|
2
|
+
VERSION = "1.19.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: snowflake-ml-python
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.19.0
|
|
4
4
|
Summary: The machine learning client library that is used for interacting with Snowflake to build machine learning solutions.
|
|
5
5
|
Author-email: "Snowflake, Inc" <support@snowflake.com>
|
|
6
6
|
License:
|
|
@@ -253,7 +253,7 @@ Requires-Dist: s3fs<2026,>=2024.6.1
|
|
|
253
253
|
Requires-Dist: scikit-learn<1.8
|
|
254
254
|
Requires-Dist: scipy<2,>=1.9
|
|
255
255
|
Requires-Dist: shap<1,>=0.46.0
|
|
256
|
-
Requires-Dist: snowflake-connector-python[pandas]<4,>=3.17.
|
|
256
|
+
Requires-Dist: snowflake-connector-python[pandas]<4,>=3.17.3
|
|
257
257
|
Requires-Dist: snowflake-snowpark-python!=1.26.0,<2,>=1.17.0
|
|
258
258
|
Requires-Dist: snowflake.core<2,>=1.0.2
|
|
259
259
|
Requires-Dist: sqlparse<1,>=0.4
|
|
@@ -285,6 +285,14 @@ Requires-Dist: tensorflow<3,>=2.17.0; extra == "keras"
|
|
|
285
285
|
Requires-Dist: torch<3,>=2.0.1; extra == "keras"
|
|
286
286
|
Provides-Extra: lightgbm
|
|
287
287
|
Requires-Dist: lightgbm<5,>=4.1.0; extra == "lightgbm"
|
|
288
|
+
Provides-Extra: llm
|
|
289
|
+
Requires-Dist: mlflow<3,>=2.16.0; extra == "llm"
|
|
290
|
+
Requires-Dist: sentence-transformers<4,>=2.7.0; extra == "llm"
|
|
291
|
+
Requires-Dist: sentencepiece<0.2.0,>=0.1.95; extra == "llm"
|
|
292
|
+
Requires-Dist: tokenizers<1,>=0.15.1; extra == "llm"
|
|
293
|
+
Requires-Dist: torch<3,>=2.0.1; extra == "llm"
|
|
294
|
+
Requires-Dist: torchdata<1,>=0.4; extra == "llm"
|
|
295
|
+
Requires-Dist: transformers!=4.51.3,<5,>=4.39.3; extra == "llm"
|
|
288
296
|
Provides-Extra: mlflow
|
|
289
297
|
Requires-Dist: mlflow<3,>=2.16.0; extra == "mlflow"
|
|
290
298
|
Provides-Extra: prophet
|
|
@@ -299,9 +307,7 @@ Requires-Dist: torchdata<1,>=0.4; extra == "torch"
|
|
|
299
307
|
Provides-Extra: transformers
|
|
300
308
|
Requires-Dist: sentence-transformers<4,>=2.7.0; extra == "transformers"
|
|
301
309
|
Requires-Dist: sentencepiece<0.2.0,>=0.1.95; extra == "transformers"
|
|
302
|
-
Requires-Dist: tokenizers<1,>=0.15.1; extra == "transformers"
|
|
303
310
|
Requires-Dist: torch<3,>=2.0.1; extra == "transformers"
|
|
304
|
-
Requires-Dist: transformers!=4.51.3,<5,>=4.39.3; extra == "transformers"
|
|
305
311
|
Dynamic: license-file
|
|
306
312
|
|
|
307
313
|
# Snowflake ML Python
|
|
@@ -409,6 +415,22 @@ NOTE: Version 1.7.0 is used as example here. Please choose the the latest versio
|
|
|
409
415
|
|
|
410
416
|
# Release History
|
|
411
417
|
|
|
418
|
+
## 1.19.0
|
|
419
|
+
|
|
420
|
+
### Bug Fixes
|
|
421
|
+
|
|
422
|
+
* Experiment Tracking (PrPr): No longer throw an exception in `list_artifacts` when run does not have artifacts.
|
|
423
|
+
* Registry: Fix `get_version_by_alias`: now requires an exact match of snowflake identifier.
|
|
424
|
+
|
|
425
|
+
### Behavior Changes
|
|
426
|
+
|
|
427
|
+
### New Features
|
|
428
|
+
|
|
429
|
+
* Online feature serving in Feature Store is in public preview.
|
|
430
|
+
* Experiment Tracking (`snowflake.ml.experiment`) is in public preview.
|
|
431
|
+
|
|
432
|
+
### Deprecations
|
|
433
|
+
|
|
412
434
|
## 1.18.0
|
|
413
435
|
|
|
414
436
|
### Bug Fixes
|
|
@@ -10,7 +10,7 @@ snowflake/cortex/_sse_client.py,sha256=sLYgqAfTOPADCnaWH2RWAJi8KbU_7gSRsTUDcDD5T
|
|
|
10
10
|
snowflake/cortex/_summarize.py,sha256=7GH8zqfIdOiHA5w4b6EvJEKEWhaTrL4YA6iDGbn7BNM,1307
|
|
11
11
|
snowflake/cortex/_translate.py,sha256=9ZGjvAnJFisbzJ_bXnt4pyug5UzhHJRXW8AhGQEersM,1652
|
|
12
12
|
snowflake/cortex/_util.py,sha256=krNTpbkFLXwdFqy1bd0xi7ZmOzOHRnIfHdQCPiLZJxk,3288
|
|
13
|
-
snowflake/ml/version.py,sha256=
|
|
13
|
+
snowflake/ml/version.py,sha256=E_REf6eP-Jb1wbXaox0ybf5CMbKewy8U_8Nru3GYxPU,99
|
|
14
14
|
snowflake/ml/_internal/env.py,sha256=EY_2KVe8oR3LgKWdaeRb5rRU-NDNXJppPDsFJmMZUUY,265
|
|
15
15
|
snowflake/ml/_internal/env_utils.py,sha256=x6ID94g6FYoMX3afp0zoUHzBvuvPyiE2F6RDpxx5Cq0,30967
|
|
16
16
|
snowflake/ml/_internal/file_utils.py,sha256=7sA6loOeSfmGP4yx16P4usT9ZtRqG3ycnXu7_Tk7dOs,14206
|
|
@@ -65,10 +65,10 @@ snowflake/ml/dataset/dataset_metadata.py,sha256=lcNvugBkP8YEkGMQqaV8SlHs5mwUKsUS
|
|
|
65
65
|
snowflake/ml/dataset/dataset_reader.py,sha256=mZsG9HyWUGgfotrGkLrunyEsOm_659mH-Sn2OyG6A-Q,5036
|
|
66
66
|
snowflake/ml/experiment/__init__.py,sha256=r7qdyPd3jwxzqvksim2ju5j_LrnYQrta0ZI6XpWUqmc,109
|
|
67
67
|
snowflake/ml/experiment/_experiment_info.py,sha256=iaJ65x6nzBYJ5djleSOzBtMpZUJCUDlRpaDw0pu-dcU,2533
|
|
68
|
-
snowflake/ml/experiment/experiment_tracking.py,sha256=
|
|
68
|
+
snowflake/ml/experiment/experiment_tracking.py,sha256=B_7_u0tOZ2_ftNQZJriY_-IfNVsAOEJonzAJahFRYis,16793
|
|
69
69
|
snowflake/ml/experiment/utils.py,sha256=3bpbkilc5vvFjnti-kcyhhjAd9Ga3LqiKqJDwORiATY,628
|
|
70
70
|
snowflake/ml/experiment/_client/artifact.py,sha256=R2WB4Y_kqv43BWLfXv8SEDINn1Bnevzgb-mH5LyvgGk,3035
|
|
71
|
-
snowflake/ml/experiment/_client/experiment_tracking_sql_client.py,sha256=
|
|
71
|
+
snowflake/ml/experiment/_client/experiment_tracking_sql_client.py,sha256=7AuC9VvDmH04PnyuCxSJt-YcwEm8cmkfmxixVN7dSbQ,8167
|
|
72
72
|
snowflake/ml/experiment/_entities/__init__.py,sha256=11XxkvAzosydf5owNmMzLwXZdQ2NtNKRM-MMra4ND2k,247
|
|
73
73
|
snowflake/ml/experiment/_entities/experiment.py,sha256=lKmQj59K8fGDWVwRqeIesxorrChb-m78vX_WUmI7PV0,225
|
|
74
74
|
snowflake/ml/experiment/_entities/run.py,sha256=JkhiS4UZWuRm3ZSLgc2uktedeag5Voih2r02YFr6DQk,1621
|
|
@@ -79,8 +79,8 @@ snowflake/ml/experiment/callback/xgboost.py,sha256=F547AXZ7Gv39cyIrgRdxVE8MQ3VlN
|
|
|
79
79
|
snowflake/ml/feature_store/__init__.py,sha256=MJr2Gp_EimDgDxD6DtenOEdLTzg6NYPfdNiPM-5rEtw,406
|
|
80
80
|
snowflake/ml/feature_store/access_manager.py,sha256=Q5ImMXRY8WA5X5dpBMzHnIJmeyKVShjNAlbn3cQb4N8,10654
|
|
81
81
|
snowflake/ml/feature_store/entity.py,sha256=ViOSlqCV17ouiO4iH-_KvkvJZqSzpf-nfsjijG6G1Uk,4047
|
|
82
|
-
snowflake/ml/feature_store/feature_store.py,sha256=
|
|
83
|
-
snowflake/ml/feature_store/feature_view.py,sha256=
|
|
82
|
+
snowflake/ml/feature_store/feature_store.py,sha256=wJliNeSifIK-zlx1a4aIhji9th0sExDxJs_MytzppZ4,172323
|
|
83
|
+
snowflake/ml/feature_store/feature_view.py,sha256=OHhhk33DJa1-P0YG0g9XQxlMrt761yRpZ3CO1y4mtwc,44329
|
|
84
84
|
snowflake/ml/feature_store/examples/example_helper.py,sha256=eaD2vLe7y4C5hMZQTeMXylbTtLacbq9gJcAluGHrkug,12470
|
|
85
85
|
snowflake/ml/feature_store/examples/airline_features/entities.py,sha256=mzHRS-InHpXON0eHds-QLmi7nK9ciOnCruhPZI4niLs,438
|
|
86
86
|
snowflake/ml/feature_store/examples/airline_features/source.yaml,sha256=kzl8ukOK8OuSPsxChEgJ9SPyPnzC-fPHqZC4O6aqd5o,247
|
|
@@ -107,11 +107,11 @@ snowflake/ml/fileset/embedded_stage_fs.py,sha256=Cw1L3Ktd1g0nWeADH6xjIxR0VweBbVt
|
|
|
107
107
|
snowflake/ml/fileset/fileset.py,sha256=ApMpHiiyzGRkyxQfJPdXPuKtw_wOXbOfQCXSH6pDwWE,26333
|
|
108
108
|
snowflake/ml/fileset/sfcfs.py,sha256=FJFc9-gc0KXaNyc10ZovN_87aUCShb0WztVwa02t0io,15517
|
|
109
109
|
snowflake/ml/fileset/snowfs.py,sha256=uF5QluYtiJ-HezGIhF55dONi3t0E6N7ByaVAIAlM3nk,5133
|
|
110
|
-
snowflake/ml/fileset/stage_fs.py,sha256=
|
|
110
|
+
snowflake/ml/fileset/stage_fs.py,sha256=SnkgCta6_5G6Ljl-Nzctr4yavhHUSlNKN3je0ojp54E,20685
|
|
111
111
|
snowflake/ml/jobs/__init__.py,sha256=h176wKqEylZs5cdWdzWHuUrSAcwctDdw4tUhIpy-mO4,657
|
|
112
112
|
snowflake/ml/jobs/decorators.py,sha256=mQgdWvvCwD7q79cSFKZHKegXGh2j1u8WM64UD3lCKr4,3428
|
|
113
|
-
snowflake/ml/jobs/job.py,sha256=
|
|
114
|
-
snowflake/ml/jobs/manager.py,sha256=
|
|
113
|
+
snowflake/ml/jobs/job.py,sha256=GeV8uCaoupuahHe8so4DyVPEvHoenEekdn-WLr-2Nj0,27580
|
|
114
|
+
snowflake/ml/jobs/manager.py,sha256=yYxY8E-0V8PIIwBTtDDaWCwqZHe8HpUM2C7nTu7gPLs,29110
|
|
115
115
|
snowflake/ml/jobs/_interop/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
116
116
|
snowflake/ml/jobs/_interop/data_utils.py,sha256=xUO5YlhUKFVCDtbjam5gP2lka3lfoknTLr7syNAVxK0,4074
|
|
117
117
|
snowflake/ml/jobs/_interop/dto_schema.py,sha256=NhoQ6WJa7uLO9VJojEENVVZhZMfL_G1VPPSSUYmmhO8,2750
|
|
@@ -152,7 +152,7 @@ snowflake/ml/model/_client/model/inference_engine_utils.py,sha256=L8HnoAEbnN5YAc
|
|
|
152
152
|
snowflake/ml/model/_client/model/model_impl.py,sha256=Yabrbir5vPMOnsVmQJ23YN7vqhi756Jcm6pfO8Aq92o,17469
|
|
153
153
|
snowflake/ml/model/_client/model/model_version_impl.py,sha256=v03RFKRnu7Gr8lovgRjE-MUK1MY_-RD5zjrrrbliJq4,60470
|
|
154
154
|
snowflake/ml/model/_client/ops/metadata_ops.py,sha256=qpK6PL3OyfuhyOmpvLCpHLy6vCxbZbp1HlEvakFGwv4,4884
|
|
155
|
-
snowflake/ml/model/_client/ops/model_ops.py,sha256=
|
|
155
|
+
snowflake/ml/model/_client/ops/model_ops.py,sha256=e6z-Pd-yslMFokzJV-ZKNK3m5dyIyl9Zk1TQX5lmgRY,50903
|
|
156
156
|
snowflake/ml/model/_client/ops/service_ops.py,sha256=Ey_yvKQvFnD4dafjFtPA3aaU1GTGqrdlgIpjrfYC8Ew,47143
|
|
157
157
|
snowflake/ml/model/_client/service/model_deployment_spec.py,sha256=n1i19opcjocXflWdr2jjtNk1GVqw8YSwip_ki2XyVMc,19628
|
|
158
158
|
snowflake/ml/model/_client/service/model_deployment_spec_schema.py,sha256=Nlw-rwCGmiGqPYwWjZrowPtcRvgYMInpmWZvsEC4sTI,2464
|
|
@@ -203,7 +203,7 @@ snowflake/ml/model/_packager/model_meta/model_meta_schema.py,sha256=mtKRbHQb6Hq2
|
|
|
203
203
|
snowflake/ml/model/_packager/model_meta_migrator/base_migrator.py,sha256=8zTgq3n6TBXv7Vcwmf7b9wjK3m-9HHMsY0Qy1Rs-sZ4,1305
|
|
204
204
|
snowflake/ml/model/_packager/model_meta_migrator/migrator_plans.py,sha256=5butM-lyaDRhCAO2BaCOIQufpAxAfSAinsNuGqbbjMU,1029
|
|
205
205
|
snowflake/ml/model/_packager/model_meta_migrator/migrator_v1.py,sha256=cyZVvBGM3nF1IVqDKfYstLCchNO-ZhSkPvLM4aU7J5c,2066
|
|
206
|
-
snowflake/ml/model/_packager/model_runtime/_snowml_inference_alternative_requirements.py,sha256=
|
|
206
|
+
snowflake/ml/model/_packager/model_runtime/_snowml_inference_alternative_requirements.py,sha256=pdqy_tKGOlQyhuSh5ZhmOXxmC2dK_VPycdghrWrq5PI,904
|
|
207
207
|
snowflake/ml/model/_packager/model_runtime/model_runtime.py,sha256=xEf-S9QurEOeQzrNxlc-4-S_VkHsVO1eNS4UR0hWwHU,5495
|
|
208
208
|
snowflake/ml/model/_packager/model_task/model_task_utils.py,sha256=_nm3Irl5W6Oa8_OnJyp3bLeA9QAbV9ygGCsgHI70GX4,6641
|
|
209
209
|
snowflake/ml/model/_signatures/base_handler.py,sha256=4CTZKKbg4WIz_CmXjyVy8tKZW-5OFcz0J8XVPHm2dfQ,1269
|
|
@@ -434,7 +434,7 @@ snowflake/ml/modeling/xgboost/xgb_classifier.py,sha256=dpJ7Y4ZRjejDxvE1vmxNUVIpg
|
|
|
434
434
|
snowflake/ml/modeling/xgboost/xgb_regressor.py,sha256=huczAVSfD5XpsXwxjC3fiaRnr_NLz1qtNyW0H_zIa6w,63580
|
|
435
435
|
snowflake/ml/modeling/xgboost/xgbrf_classifier.py,sha256=9ZyYqcdsx7nUQsrNJFMBohySPhZpFZHkbyL66-2vOJQ,64253
|
|
436
436
|
snowflake/ml/modeling/xgboost/xgbrf_regressor.py,sha256=Zvl3atGaaZpOjI5XizLsLqWuHWA3B-M59jGzYtjkq14,63778
|
|
437
|
-
snowflake/ml/monitoring/explain_visualize.py,sha256=
|
|
437
|
+
snowflake/ml/monitoring/explain_visualize.py,sha256=I5-JKHhpD7JD6inZYMGUxm1MEEflBB9jwQgXcrDStow,16234
|
|
438
438
|
snowflake/ml/monitoring/model_monitor.py,sha256=m-1eeQIhAYAvFQ-8mjMQ-PTzCpnN9XEcWpdHdQuEEus,4707
|
|
439
439
|
snowflake/ml/monitoring/shap.py,sha256=Dp9nYquPEZjxMTW62YYA9g9qUdmCEFxcSk7ejvOP7PE,3597
|
|
440
440
|
snowflake/ml/monitoring/_client/model_monitor_sql_client.py,sha256=6IVU1aQdiRu0GRhpZfNatJdzd5YgUNFlJ3Ti-mBxzN8,18027
|
|
@@ -451,8 +451,8 @@ snowflake/ml/utils/connection_params.py,sha256=NSBUgcs-DXPRHs1BKpxdSubbJx1yrFRlM
|
|
|
451
451
|
snowflake/ml/utils/html_utils.py,sha256=L4pzpvFd20SIk4rie2kTAtcQjbxBHfjKmxonMAT2OoA,7665
|
|
452
452
|
snowflake/ml/utils/sparse.py,sha256=zLBNh-ynhGpKH5TFtopk0YLkHGvv0yq1q-sV59YQKgg,3819
|
|
453
453
|
snowflake/ml/utils/sql_client.py,sha256=pSe2od6Pkh-8NwG3D-xqN76_uNf-ohOtVbT55HeQg1Y,668
|
|
454
|
-
snowflake_ml_python-1.
|
|
455
|
-
snowflake_ml_python-1.
|
|
456
|
-
snowflake_ml_python-1.
|
|
457
|
-
snowflake_ml_python-1.
|
|
458
|
-
snowflake_ml_python-1.
|
|
454
|
+
snowflake_ml_python-1.19.0.dist-info/licenses/LICENSE.txt,sha256=PdEp56Av5m3_kl21iFkVTX_EbHJKFGEdmYeIO1pL_Yk,11365
|
|
455
|
+
snowflake_ml_python-1.19.0.dist-info/METADATA,sha256=AgdELvFlnXyalB8a6NU6Fer0MffT245XRWf94InGRY4,97868
|
|
456
|
+
snowflake_ml_python-1.19.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
457
|
+
snowflake_ml_python-1.19.0.dist-info/top_level.txt,sha256=TY0gFSHKDdZy3THb0FGomyikWQasEGldIR1O0HGOHVw,10
|
|
458
|
+
snowflake_ml_python-1.19.0.dist-info/RECORD,,
|
|
File without changes
|
{snowflake_ml_python-1.18.0.dist-info → snowflake_ml_python-1.19.0.dist-info}/licenses/LICENSE.txt
RENAMED
|
File without changes
|
|
File without changes
|