snowflake-ml-python 1.7.0__py3-none-any.whl → 1.7.2__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 (53) hide show
  1. snowflake/cortex/__init__.py +4 -0
  2. snowflake/cortex/_complete.py +107 -64
  3. snowflake/cortex/_finetune.py +273 -0
  4. snowflake/cortex/_sse_client.py +91 -28
  5. snowflake/cortex/_util.py +30 -1
  6. snowflake/ml/_internal/type_utils.py +3 -3
  7. snowflake/ml/_internal/utils/jwt_generator.py +141 -0
  8. snowflake/ml/data/__init__.py +5 -0
  9. snowflake/ml/model/_client/model/model_version_impl.py +26 -12
  10. snowflake/ml/model/_client/ops/model_ops.py +51 -30
  11. snowflake/ml/model/_client/ops/service_ops.py +25 -9
  12. snowflake/ml/model/_client/sql/model.py +0 -14
  13. snowflake/ml/model/_client/sql/service.py +25 -1
  14. snowflake/ml/model/_client/sql/stage.py +1 -1
  15. snowflake/ml/model/_model_composer/model_method/infer_function.py_template +2 -1
  16. snowflake/ml/model/_packager/model_env/model_env.py +12 -0
  17. snowflake/ml/model/_packager/model_handlers/_utils.py +1 -1
  18. snowflake/ml/model/_packager/model_handlers/catboost.py +1 -1
  19. snowflake/ml/model/_packager/model_handlers/custom.py +3 -1
  20. snowflake/ml/model/_packager/model_handlers/lightgbm.py +2 -1
  21. snowflake/ml/model/_packager/model_handlers/sklearn.py +50 -1
  22. snowflake/ml/model/_packager/model_handlers/snowmlmodel.py +1 -1
  23. snowflake/ml/model/_packager/model_handlers/tensorflow.py +23 -6
  24. snowflake/ml/model/_packager/model_handlers/torchscript.py +14 -14
  25. snowflake/ml/model/_packager/model_meta/_packaging_requirements.py +2 -3
  26. snowflake/ml/model/_packager/model_meta/model_meta_schema.py +5 -0
  27. snowflake/ml/model/_packager/model_runtime/_snowml_inference_alternative_requirements.py +2 -10
  28. snowflake/ml/model/_packager/model_runtime/model_runtime.py +4 -9
  29. snowflake/ml/model/_packager/model_task/model_task_utils.py +1 -1
  30. snowflake/ml/model/_signatures/core.py +63 -16
  31. snowflake/ml/model/_signatures/pandas_handler.py +71 -27
  32. snowflake/ml/model/_signatures/pytorch_handler.py +2 -2
  33. snowflake/ml/model/_signatures/snowpark_handler.py +2 -1
  34. snowflake/ml/model/_signatures/tensorflow_handler.py +2 -2
  35. snowflake/ml/model/_signatures/utils.py +4 -1
  36. snowflake/ml/model/model_signature.py +38 -9
  37. snowflake/ml/model/type_hints.py +1 -1
  38. snowflake/ml/modeling/lightgbm/lgbm_classifier.py +2 -4
  39. snowflake/ml/modeling/lightgbm/lgbm_regressor.py +2 -4
  40. snowflake/ml/monitoring/_client/model_monitor_sql_client.py +148 -1200
  41. snowflake/ml/monitoring/_manager/model_monitor_manager.py +114 -238
  42. snowflake/ml/monitoring/entities/model_monitor_config.py +38 -12
  43. snowflake/ml/monitoring/model_monitor.py +12 -86
  44. snowflake/ml/registry/registry.py +28 -40
  45. snowflake/ml/utils/authentication.py +75 -0
  46. snowflake/ml/version.py +1 -1
  47. {snowflake_ml_python-1.7.0.dist-info → snowflake_ml_python-1.7.2.dist-info}/METADATA +116 -52
  48. {snowflake_ml_python-1.7.0.dist-info → snowflake_ml_python-1.7.2.dist-info}/RECORD +51 -49
  49. {snowflake_ml_python-1.7.0.dist-info → snowflake_ml_python-1.7.2.dist-info}/WHEEL +1 -1
  50. snowflake/ml/monitoring/entities/model_monitor_interval.py +0 -46
  51. snowflake/ml/monitoring/entities/output_score_type.py +0 -90
  52. {snowflake_ml_python-1.7.0.dist-info → snowflake_ml_python-1.7.2.dist-info}/LICENSE.txt +0 -0
  53. {snowflake_ml_python-1.7.0.dist-info → snowflake_ml_python-1.7.2.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,7 @@
1
- from typing import List, Union
2
-
3
- import pandas as pd
4
-
5
1
  from snowflake import snowpark
6
2
  from snowflake.ml._internal import telemetry
7
3
  from snowflake.ml._internal.utils import sql_identifier
4
+ from snowflake.ml.monitoring import model_monitor_version
8
5
  from snowflake.ml.monitoring._client import model_monitor_sql_client
9
6
 
10
7
 
@@ -13,114 +10,43 @@ class ModelMonitor:
13
10
 
14
11
  name: sql_identifier.SqlIdentifier
15
12
  _model_monitor_client: model_monitor_sql_client.ModelMonitorSQLClient
16
- _fully_qualified_model_name: str
17
- _version_name: sql_identifier.SqlIdentifier
18
- _function_name: sql_identifier.SqlIdentifier
19
- _prediction_columns: List[sql_identifier.SqlIdentifier]
20
- _label_columns: List[sql_identifier.SqlIdentifier]
21
13
 
22
14
  def __init__(self) -> None:
23
- raise RuntimeError("ModelMonitor's initializer is not meant to be used.")
15
+ raise RuntimeError("Model Monitor's initializer is not meant to be used.")
24
16
 
25
17
  @classmethod
26
18
  def _ref(
27
19
  cls,
28
20
  model_monitor_client: model_monitor_sql_client.ModelMonitorSQLClient,
29
21
  name: sql_identifier.SqlIdentifier,
30
- *,
31
- fully_qualified_model_name: str,
32
- version_name: sql_identifier.SqlIdentifier,
33
- function_name: sql_identifier.SqlIdentifier,
34
- prediction_columns: List[sql_identifier.SqlIdentifier],
35
- label_columns: List[sql_identifier.SqlIdentifier],
36
22
  ) -> "ModelMonitor":
37
23
  self: "ModelMonitor" = object.__new__(cls)
38
24
  self.name = name
39
25
  self._model_monitor_client = model_monitor_client
40
- self._fully_qualified_model_name = fully_qualified_model_name
41
- self._version_name = version_name
42
- self._function_name = function_name
43
- self._prediction_columns = prediction_columns
44
- self._label_columns = label_columns
45
26
  return self
46
27
 
47
28
  @telemetry.send_api_usage_telemetry(
48
29
  project=telemetry.TelemetryProject.MLOPS.value,
49
30
  subproject=telemetry.TelemetrySubProject.MONITORING.value,
50
31
  )
51
- def set_baseline(self, baseline_df: Union[pd.DataFrame, snowpark.DataFrame]) -> None:
52
- """
53
- The baseline dataframe is compared with the monitored data once monitoring is enabled.
54
- The columns of the dataframe should match the columns of the source table that the
55
- ModelMonitor was configured with. Calling this method overwrites any existing baseline split data.
56
-
57
- Args:
58
- baseline_df: Snowpark dataframe containing baseline data.
59
-
60
- Raises:
61
- ValueError: baseline_df does not contain prediction or label columns
62
- """
63
- statement_params = telemetry.get_statement_params(
64
- project=telemetry.TelemetryProject.MLOPS.value,
65
- subproject=telemetry.TelemetrySubProject.MONITORING.value,
66
- )
67
-
68
- if isinstance(baseline_df, pd.DataFrame):
69
- baseline_df = self._model_monitor_client._sql_client._session.create_dataframe(baseline_df)
70
-
71
- column_names_identifiers: List[sql_identifier.SqlIdentifier] = [
72
- sql_identifier.SqlIdentifier(column_name) for column_name in baseline_df.columns
73
- ]
74
- prediction_cols_not_found = any(
75
- [prediction_col not in column_names_identifiers for prediction_col in self._prediction_columns]
76
- )
77
- label_cols_not_found = any(
78
- [label_col.identifier() not in column_names_identifiers for label_col in self._label_columns]
79
- )
80
-
81
- if prediction_cols_not_found:
82
- raise ValueError(
83
- "Specified prediction columns were not found in the baseline dataframe. "
84
- f"Columns provided were: {column_names_identifiers}. "
85
- f"Configured prediction columns were: {self._prediction_columns}."
86
- )
87
- if label_cols_not_found:
88
- raise ValueError(
89
- "Specified label columns were not found in the baseline dataframe."
90
- f"Columns provided in the baseline dataframe were: {column_names_identifiers}."
91
- f"Configured label columns were: {self._label_columns}."
92
- )
93
-
94
- # Create the table by materializing the df
95
- self._model_monitor_client.materialize_baseline_dataframe(
96
- baseline_df,
97
- self._fully_qualified_model_name,
98
- self._version_name,
99
- statement_params=statement_params,
100
- )
101
-
32
+ @snowpark._internal.utils.private_preview(version=model_monitor_version.SNOWFLAKE_ML_MONITORING_MIN_VERSION)
102
33
  def suspend(self) -> None:
103
- """Suspend pipeline for ModelMonitor"""
34
+ """Suspend the Model Monitor"""
104
35
  statement_params = telemetry.get_statement_params(
105
36
  telemetry.TelemetryProject.MLOPS.value,
106
37
  telemetry.TelemetrySubProject.MONITORING.value,
107
38
  )
108
- _, _, model_name = sql_identifier.parse_fully_qualified_name(self._fully_qualified_model_name)
109
- self._model_monitor_client.suspend_monitor_dynamic_tables(
110
- model_name=model_name,
111
- version_name=self._version_name,
112
- statement_params=statement_params,
113
- )
39
+ self._model_monitor_client.suspend_monitor(self.name, statement_params=statement_params)
114
40
 
41
+ @telemetry.send_api_usage_telemetry(
42
+ project=telemetry.TelemetryProject.MLOPS.value,
43
+ subproject=telemetry.TelemetrySubProject.MONITORING.value,
44
+ )
45
+ @snowpark._internal.utils.private_preview(version=model_monitor_version.SNOWFLAKE_ML_MONITORING_MIN_VERSION)
115
46
  def resume(self) -> None:
116
- """Resume pipeline for ModelMonitor"""
47
+ """Resume the Model Monitor"""
117
48
  statement_params = telemetry.get_statement_params(
118
49
  telemetry.TelemetryProject.MLOPS.value,
119
50
  telemetry.TelemetrySubProject.MONITORING.value,
120
51
  )
121
- _, _, model_name = sql_identifier.parse_fully_qualified_name(self._fully_qualified_model_name)
122
- self._model_monitor_client.resume_monitor_dynamic_tables(
123
- model_name=model_name,
124
- version_name=self._version_name,
125
- statement_params=statement_params,
126
- )
52
+ self._model_monitor_client.resume_monitor(self.name, statement_params=statement_params)
@@ -23,6 +23,11 @@ from snowflake.snowpark import session
23
23
  _TELEMETRY_PROJECT = "MLOps"
24
24
  _MODEL_TELEMETRY_SUBPROJECT = "ModelManagement"
25
25
 
26
+ _MODEL_MONITORING_UNIMPLEMENTED_ERROR = "Model Monitoring is not implemented in python yet."
27
+ _MODEL_MONITORING_DISABLED_ERROR = (
28
+ """Must enable monitoring to use this method. Please set `options={"enable_monitoring": True}` in the Registry"""
29
+ )
30
+
26
31
 
27
32
  class Registry:
28
33
  def __init__(
@@ -84,7 +89,6 @@ class Registry:
84
89
  session=session,
85
90
  database_name=self._database_name,
86
91
  schema_name=self._schema_name,
87
- create_if_not_exists=True, # TODO: Support static setup method to configure schema for monitoring.
88
92
  statement_params=monitor_statement_params,
89
93
  )
90
94
 
@@ -381,47 +385,38 @@ class Registry:
381
385
  def add_monitor(
382
386
  self,
383
387
  name: str,
384
- table_config: model_monitor_config.ModelMonitorTableConfig,
388
+ source_config: model_monitor_config.ModelMonitorSourceConfig,
385
389
  model_monitor_config: model_monitor_config.ModelMonitorConfig,
386
- *,
387
- add_dashboard_udtfs: bool = False,
388
390
  ) -> model_monitor.ModelMonitor:
389
- """Add a Model Monitor to the Registry
391
+ """Add a Model Monitor to the Registry.
390
392
 
391
393
  Args:
392
- name: Name of Model Monitor to create
393
- table_config: Configuration options of table for ModelMonitor.
394
- model_monitor_config: Configuration options of ModelMonitor.
395
- add_dashboard_udtfs: Add UDTFs useful for creating a dashboard.
394
+ name: Name of Model Monitor to create.
395
+ source_config: Configuration options of table for Model Monitor.
396
+ model_monitor_config: Configuration options of Model Monitor.
396
397
 
397
398
  Returns:
398
- The newly added ModelMonitor object.
399
+ The newly added Model Monitor object.
399
400
 
400
401
  Raises:
401
- ValueError: If monitoring feature flag is not enabled.
402
+ ValueError: If monitoring is not enabled in the Registry.
402
403
  """
403
404
  if not self.enable_monitoring:
404
- raise ValueError(
405
- "Must enable monitoring in Registry to use this method. Please set the `enable_monitoring=True` option"
406
- )
407
-
408
- # TODO: Change to fully qualified source table reference to allow table to live in different DB.
409
- return self._model_monitor_manager.add_monitor(
410
- name, table_config, model_monitor_config, add_dashboard_udtfs=add_dashboard_udtfs
411
- )
405
+ raise ValueError(_MODEL_MONITORING_DISABLED_ERROR)
406
+ return self._model_monitor_manager.add_monitor(name, source_config, model_monitor_config)
412
407
 
413
408
  @overload
414
409
  def get_monitor(self, model_version: model_version_impl.ModelVersion) -> model_monitor.ModelMonitor:
415
- """Get a Model Monitor on a ModelVersion from the Registry
410
+ """Get a Model Monitor on a Model Version from the Registry.
416
411
 
417
412
  Args:
418
- model_version: ModelVersion for which to retrieve the ModelMonitor.
413
+ model_version: Model Version for which to retrieve the Model Monitor.
419
414
  """
420
415
  ...
421
416
 
422
417
  @overload
423
418
  def get_monitor(self, name: str) -> model_monitor.ModelMonitor:
424
- """Get a Model Monitor from the Registry
419
+ """Get a Model Monitor by name from the Registry.
425
420
 
426
421
  Args:
427
422
  name: Name of Model Monitor to retrieve.
@@ -436,27 +431,24 @@ class Registry:
436
431
  def get_monitor(
437
432
  self, *, name: Optional[str] = None, model_version: Optional[model_version_impl.ModelVersion] = None
438
433
  ) -> model_monitor.ModelMonitor:
439
- """Get a Model Monitor from the Registry
434
+ """Get a Model Monitor from the Registry.
440
435
 
441
436
  Args:
442
437
  name: Name of Model Monitor to retrieve.
443
- model_version: ModelVersion for which to retrieve the ModelMonitor.
438
+ model_version: Model Version for which to retrieve the Model Monitor.
444
439
 
445
440
  Returns:
446
- The fetched ModelMonitor.
441
+ The fetched Model Monitor.
447
442
 
448
443
  Raises:
449
- ValueError: If monitoring feature flag is not enabled.
450
- ValueError: If neither name nor model_version specified.
444
+ ValueError: If monitoring is not enabled in the Registry.
451
445
  """
452
446
  if not self.enable_monitoring:
453
- raise ValueError(
454
- "Must enable monitoring in Registry to use this method. Please set the `enable_monitoring=True` option"
455
- )
447
+ raise ValueError(_MODEL_MONITORING_DISABLED_ERROR)
456
448
  if name is not None:
457
449
  return self._model_monitor_manager.get_monitor(name=name)
458
450
  elif model_version is not None:
459
- return self._model_monitor_manager.get_monitor_by_model_version(model_version=model_version)
451
+ return self._model_monitor_manager.get_monitor_by_model_version(model_version)
460
452
  else:
461
453
  raise ValueError("Must provide either `name` or `model_version` to get ModelMonitor")
462
454
 
@@ -472,12 +464,10 @@ class Registry:
472
464
  List of snowpark.Row containing metadata for each model monitor.
473
465
 
474
466
  Raises:
475
- ValueError: If monitoring feature flag is not enabled.
467
+ ValueError: If monitoring is not enabled in the Registry.
476
468
  """
477
469
  if not self.enable_monitoring:
478
- raise ValueError(
479
- "Must enable monitoring in Registry to use this method. Please set the `enable_monitoring=True` option"
480
- )
470
+ raise ValueError(_MODEL_MONITORING_DISABLED_ERROR)
481
471
  return self._model_monitor_manager.show_model_monitors()
482
472
 
483
473
  @telemetry.send_api_usage_telemetry(
@@ -486,16 +476,14 @@ class Registry:
486
476
  )
487
477
  @snowpark._internal.utils.private_preview(version=model_monitor_version.SNOWFLAKE_ML_MONITORING_MIN_VERSION)
488
478
  def delete_monitor(self, name: str) -> None:
489
- """Delete a Model Monitor from the Registry
479
+ """Delete a Model Monitor by name from the Registry.
490
480
 
491
481
  Args:
492
482
  name: Name of the Model Monitor to delete.
493
483
 
494
484
  Raises:
495
- ValueError: If monitoring feature flag is not enabled.
485
+ ValueError: If monitoring is not enabled in the registry.
496
486
  """
497
487
  if not self.enable_monitoring:
498
- raise ValueError(
499
- "Must enable monitoring in Registry to use this method. Please set the `enable_monitoring=True` option"
500
- )
488
+ raise ValueError(_MODEL_MONITORING_DISABLED_ERROR)
501
489
  self._model_monitor_manager.delete_monitor(name)
@@ -0,0 +1,75 @@
1
+ import http
2
+ import logging
3
+ from datetime import timedelta
4
+ from typing import Dict, Optional
5
+
6
+ import requests
7
+ from cryptography.hazmat.primitives.asymmetric import types
8
+ from requests import auth
9
+
10
+ from snowflake.ml._internal.utils import jwt_generator
11
+
12
+ logger = logging.getLogger(__name__)
13
+ _JWT_TOKEN_CACHE: Dict[str, Dict[int, str]] = {}
14
+
15
+
16
+ def get_jwt_token_generator(
17
+ account: str,
18
+ user: str,
19
+ private_key: types.PRIVATE_KEY_TYPES,
20
+ lifetime: Optional[timedelta] = None,
21
+ renewal_delay: Optional[timedelta] = None,
22
+ ) -> jwt_generator.JWTGenerator:
23
+ return jwt_generator.JWTGenerator(account, user, private_key, lifetime=lifetime, renewal_delay=renewal_delay)
24
+
25
+
26
+ def _get_snowflake_token_by_jwt(
27
+ jwt_token_generator: jwt_generator.JWTGenerator,
28
+ account: Optional[str] = None,
29
+ role: Optional[str] = None,
30
+ endpoint: Optional[str] = None,
31
+ snowflake_account_url: Optional[str] = None,
32
+ ) -> str:
33
+ scope_role = f"session:role:{role}" if role is not None else None
34
+ scope = " ".join(filter(None, [scope_role, endpoint]))
35
+ data = {
36
+ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
37
+ "scope": scope or None,
38
+ "assertion": jwt_token_generator.get_token(),
39
+ }
40
+ account = account or jwt_token_generator.account
41
+ url = f"https://{account}.snowflakecomputing.com/oauth/token"
42
+ if snowflake_account_url:
43
+ url = f"{snowflake_account_url}/oauth/token"
44
+
45
+ cache_key = hash(frozenset(data.items()))
46
+ if url in _JWT_TOKEN_CACHE:
47
+ if cache_key in _JWT_TOKEN_CACHE[url]:
48
+ return _JWT_TOKEN_CACHE[url][cache_key]
49
+ else:
50
+ _JWT_TOKEN_CACHE[url] = {}
51
+
52
+ response = requests.post(url, data=data)
53
+ if response.status_code != http.HTTPStatus.OK:
54
+ raise RuntimeError(f"Failed to get snowflake token: {response.status_code} {response.content!r}")
55
+ auth_token = response.text
56
+ _JWT_TOKEN_CACHE[url][cache_key] = auth_token
57
+ return auth_token
58
+
59
+
60
+ class SnowflakeJWTTokenAuth(auth.AuthBase):
61
+ def __init__(
62
+ self,
63
+ jwt_token_generator: jwt_generator.JWTGenerator,
64
+ account: Optional[str] = None,
65
+ role: Optional[str] = None,
66
+ endpoint: Optional[str] = None,
67
+ snowflake_account_url: Optional[str] = None,
68
+ ) -> None:
69
+ self.snowflake_token = _get_snowflake_token_by_jwt(
70
+ jwt_token_generator, account, role, endpoint, snowflake_account_url
71
+ )
72
+
73
+ def __call__(self, r: requests.PreparedRequest) -> requests.PreparedRequest:
74
+ r.headers["Authorization"] = f'Snowflake Token="{self.snowflake_token}"'
75
+ return r
snowflake/ml/version.py CHANGED
@@ -1 +1 @@
1
- VERSION="1.7.0"
1
+ VERSION="1.7.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: snowflake-ml-python
3
- Version: 1.7.0
3
+ Version: 1.7.2
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:
@@ -232,60 +232,62 @@ Classifier: Topic :: Scientific/Engineering :: Information Analysis
232
232
  Requires-Python: <3.12,>=3.9
233
233
  Description-Content-Type: text/markdown
234
234
  License-File: LICENSE.txt
235
- Requires-Dist: absl-py <2,>=0.15
236
- Requires-Dist: anyio <4,>=3.5.0
237
- Requires-Dist: cachetools <6,>=3.1.1
238
- Requires-Dist: cloudpickle >=2.0.0
239
- Requires-Dist: fsspec[http] <2024,>=2022.11
240
- Requires-Dist: importlib-resources <7,>=6.1.1
241
- Requires-Dist: numpy <2,>=1.23
242
- Requires-Dist: packaging <24,>=20.9
243
- Requires-Dist: pandas <3,>=1.0.0
235
+ Requires-Dist: absl-py<2,>=0.15
236
+ Requires-Dist: anyio<4,>=3.5.0
237
+ Requires-Dist: cachetools<6,>=3.1.1
238
+ Requires-Dist: cloudpickle>=2.0.0
239
+ Requires-Dist: cryptography
240
+ Requires-Dist: fsspec[http]<2024,>=2022.11
241
+ Requires-Dist: importlib_resources<7,>=6.1.1
242
+ Requires-Dist: numpy<2,>=1.23
243
+ Requires-Dist: packaging<25,>=20.9
244
+ Requires-Dist: pandas<3,>=1.0.0
244
245
  Requires-Dist: pyarrow
245
- Requires-Dist: pytimeparse <2,>=1.1.8
246
- Requires-Dist: pyyaml <7,>=6.0
247
- Requires-Dist: retrying <2,>=1.3.3
248
- Requires-Dist: s3fs <2024,>=2022.11
249
- Requires-Dist: scikit-learn <1.6,>=1.4
250
- Requires-Dist: scipy <2,>=1.9
251
- Requires-Dist: snowflake-connector-python[pandas] <4,>=3.5.0
252
- Requires-Dist: snowflake-snowpark-python <2,>=1.17.0
253
- Requires-Dist: sqlparse <1,>=0.4
254
- Requires-Dist: typing-extensions <5,>=4.1.0
255
- Requires-Dist: xgboost <3,>=1.7.3
246
+ Requires-Dist: pyjwt<3,>=2.0.0
247
+ Requires-Dist: pytimeparse<2,>=1.1.8
248
+ Requires-Dist: pyyaml<7,>=6.0
249
+ Requires-Dist: retrying<2,>=1.3.3
250
+ Requires-Dist: s3fs<2024,>=2022.11
251
+ Requires-Dist: scikit-learn<1.6,>=1.4
252
+ Requires-Dist: scipy<2,>=1.9
253
+ Requires-Dist: snowflake-connector-python[pandas]<4,>=3.5.0
254
+ Requires-Dist: snowflake-snowpark-python<2,>=1.17.0
255
+ Requires-Dist: sqlparse<1,>=0.4
256
+ Requires-Dist: typing-extensions<5,>=4.1.0
257
+ Requires-Dist: xgboost<3,>=1.7.3
256
258
  Provides-Extra: all
257
- Requires-Dist: catboost <2,>=1.2.0 ; extra == 'all'
258
- Requires-Dist: lightgbm <5,>=3.3.5 ; extra == 'all'
259
- Requires-Dist: mlflow <2.4,>=2.1.0 ; extra == 'all'
260
- Requires-Dist: peft <1,>=0.5.0 ; extra == 'all'
261
- Requires-Dist: sentence-transformers <3,>=2.2.2 ; extra == 'all'
262
- Requires-Dist: sentencepiece <1,>=0.1.95 ; extra == 'all'
263
- Requires-Dist: shap <1,>=0.46.0 ; extra == 'all'
264
- Requires-Dist: tensorflow <3,>=2.10 ; extra == 'all'
265
- Requires-Dist: tokenizers <1,>=0.10 ; extra == 'all'
266
- Requires-Dist: torch <2.3.0,>=2.0.1 ; extra == 'all'
267
- Requires-Dist: torchdata <1,>=0.4 ; extra == 'all'
268
- Requires-Dist: transformers <5,>=4.32.1 ; extra == 'all'
259
+ Requires-Dist: catboost<2,>=1.2.0; extra == "all"
260
+ Requires-Dist: lightgbm<5,>=4.1.0; extra == "all"
261
+ Requires-Dist: mlflow<2.4,>=2.1.0; extra == "all"
262
+ Requires-Dist: peft<1,>=0.5.0; extra == "all"
263
+ Requires-Dist: sentence-transformers<3,>=2.2.2; extra == "all"
264
+ Requires-Dist: sentencepiece<1,>=0.1.95; extra == "all"
265
+ Requires-Dist: shap<1,>=0.46.0; extra == "all"
266
+ Requires-Dist: tensorflow<3,>=2.10; extra == "all"
267
+ Requires-Dist: tokenizers<1,>=0.10; extra == "all"
268
+ Requires-Dist: torch<2.3.0,>=2.0.1; extra == "all"
269
+ Requires-Dist: torchdata<1,>=0.4; extra == "all"
270
+ Requires-Dist: transformers<5,>=4.32.1; extra == "all"
269
271
  Provides-Extra: catboost
270
- Requires-Dist: catboost <2,>=1.2.0 ; extra == 'catboost'
272
+ Requires-Dist: catboost<2,>=1.2.0; extra == "catboost"
271
273
  Provides-Extra: lightgbm
272
- Requires-Dist: lightgbm <5,>=3.3.5 ; extra == 'lightgbm'
274
+ Requires-Dist: lightgbm<5,>=4.1.0; extra == "lightgbm"
273
275
  Provides-Extra: llm
274
- Requires-Dist: peft <1,>=0.5.0 ; extra == 'llm'
276
+ Requires-Dist: peft<1,>=0.5.0; extra == "llm"
275
277
  Provides-Extra: mlflow
276
- Requires-Dist: mlflow <2.4,>=2.1.0 ; extra == 'mlflow'
278
+ Requires-Dist: mlflow<2.4,>=2.1.0; extra == "mlflow"
277
279
  Provides-Extra: shap
278
- Requires-Dist: shap <1,>=0.46.0 ; extra == 'shap'
280
+ Requires-Dist: shap<1,>=0.46.0; extra == "shap"
279
281
  Provides-Extra: tensorflow
280
- Requires-Dist: tensorflow <3,>=2.10 ; extra == 'tensorflow'
282
+ Requires-Dist: tensorflow<3,>=2.10; extra == "tensorflow"
281
283
  Provides-Extra: torch
282
- Requires-Dist: torch <2.3.0,>=2.0.1 ; extra == 'torch'
283
- Requires-Dist: torchdata <1,>=0.4 ; extra == 'torch'
284
+ Requires-Dist: torch<2.3.0,>=2.0.1; extra == "torch"
285
+ Requires-Dist: torchdata<1,>=0.4; extra == "torch"
284
286
  Provides-Extra: transformers
285
- Requires-Dist: sentence-transformers <3,>=2.2.2 ; extra == 'transformers'
286
- Requires-Dist: sentencepiece <1,>=0.1.95 ; extra == 'transformers'
287
- Requires-Dist: tokenizers <1,>=0.10 ; extra == 'transformers'
288
- Requires-Dist: transformers <5,>=4.32.1 ; extra == 'transformers'
287
+ Requires-Dist: sentence-transformers<3,>=2.2.2; extra == "transformers"
288
+ Requires-Dist: sentencepiece<1,>=0.1.95; extra == "transformers"
289
+ Requires-Dist: tokenizers<1,>=0.10; extra == "transformers"
290
+ Requires-Dist: transformers<5,>=4.32.1; extra == "transformers"
289
291
 
290
292
  # Snowpark ML
291
293
 
@@ -301,7 +303,7 @@ and deployment process, and includes two key components.
301
303
 
302
304
  ### Snowpark ML Development
303
305
 
304
- [Snowpark ML Development](https://docs.snowflake.com/en/developer-guide/snowpark-ml/index#snowpark-ml-development)
306
+ [Snowpark ML Development](https://docs.snowflake.com/en/developer-guide/snowpark-ml/index#ml-modeling)
305
307
  provides a collection of python APIs enabling efficient ML model development directly in Snowflake:
306
308
 
307
309
  1. Modeling API (`snowflake.ml.modeling`) for data preprocessing, feature engineering and model training in Snowflake.
@@ -315,14 +317,21 @@ their native data loader formats.
315
317
  1. FileSet API: FileSet provides a Python fsspec-compliant API for materializing data into a Snowflake internal stage
316
318
  from a query or Snowpark Dataframe along with a number of convenience APIs.
317
319
 
318
- ### Snowpark Model Management [Public Preview]
320
+ ### Snowflake MLOps
319
321
 
320
- [Snowpark Model Management](https://docs.snowflake.com/en/developer-guide/snowpark-ml/index#snowpark-ml-ops) complements
321
- the Snowpark ML Development API, and provides model management capabilities along with integrated deployment into Snowflake.
322
+ Snowflake MLOps contains suit of tools and objects to make ML development cycle. It complements
323
+ the Snowpark ML Development API, and provides end to end development to deployment within Snowflake.
322
324
  Currently, the API consists of:
323
325
 
324
- 1. Registry: A python API for managing models within Snowflake which also supports deployment of ML models into Snowflake
325
- as native MODEL object running with Snowflake Warehouse.
326
+ 1. [Registry](https://docs.snowflake.com/en/developer-guide/snowpark-ml/index#snowflake-model-registry): A python API
327
+ allows secure deployment and management of models in Snowflake, supporting models trained both inside and outside of
328
+ Snowflake.
329
+ 2. [Feature Store](https://docs.snowflake.com/en/developer-guide/snowpark-ml/index#snowflake-feature-store): A fully
330
+ integrated solution for defining, managing, storing and discovering ML features derived from your data. The
331
+ Snowflake Feature Store supports automated, incremental refresh from batch and streaming data sources, so that
332
+ feature pipelines need be defined only once to be continuously updated with new data.
333
+ 3. [Datasets](https://docs.snowflake.com/developer-guide/snowflake-ml/overview#snowflake-datasets): Dataset provide an
334
+ immutable, versioned snapshot of your data suitable for ingestion by your machine learning models.
326
335
 
327
336
  ## Getting started
328
337
 
@@ -370,9 +379,64 @@ conda install \
370
379
  Note that until a `snowflake-ml-python` package version is available in the official Snowflake conda channel, there may
371
380
  be compatibility issues. Server-side functionality that `snowflake-ml-python` depends on may not yet be released.
372
381
 
382
+ ### Verifying the package
383
+
384
+ 1. Install cosign.
385
+ This example is using golang installation: [installing-cosign-with-go](https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/#installing-cosign-with-go).
386
+ 1. Download the file from the repository like [pypi](https://pypi.org/project/snowflake-ml-python/#files).
387
+ 1. Download the signature files from the [release tag](https://github.com/snowflakedb/snowflake-ml-python/releases/tag/1.7.0).
388
+ 1. Verify signature on projects signed using Jenkins job:
389
+
390
+ ```sh
391
+ cosign verify-blob snowflake_ml_python-1.7.0.tar.gz --key snowflake-ml-python-1.7.0.pub --signature resources.linux.snowflake_ml_python-1.7.0.tar.gz.sig
392
+
393
+ cosign verify-blob snowflake_ml_python-1.7.0.tar.gz --key snowflake-ml-python-1.7.0.pub --signature resources.linux.snowflake_ml_python-1.7.0
394
+ ```
395
+
396
+ NOTE: Version 1.7.0 is used as example here. Please choose the the latest version.
397
+
373
398
  # Release History
374
399
 
375
- ## 1.7.0
400
+ ## 1.7.2
401
+
402
+ ### Bug Fixes
403
+
404
+ - Model Explainability: Fix issue that explain is enabled for scikit-learn pipeline
405
+ whose task is UNKNOWN and fails later when invoked.
406
+
407
+ ### Behavior Changes
408
+
409
+ ### New Features
410
+
411
+ - Registry: Support asynchronous model inference service creation with the `block` option
412
+ in `ModelVersion.create_service()` set to True by default.
413
+
414
+ ## 1.7.1 (2024-11-05)
415
+
416
+ ### Bug Fixes
417
+
418
+ - Registry: Null value is now allowed in the dataframe used in model signature inference. Null values will be ignored
419
+ and others will be used to infer the signature.
420
+ - Registry: Pandas Extension DTypes (`pandas.StringDType()`, `pandas.BooleanDType()`, etc.) are now supported in model
421
+ signature inference.
422
+ - Registry: Null value is now allowed in the dataframe used to predict.
423
+ - Data: Fix missing `snowflake.ml.data.*` module exports in wheel
424
+ - Dataset: Fix missing `snowflake.ml.dataset.*` module exports in wheel.
425
+ - Registry: Fix the issue that `tf_keras.Model` is not recognized as keras model when logging.
426
+
427
+ ### Behavior Changes
428
+
429
+ ### New Features
430
+
431
+ - Registry: Option to `enable_monitoring` set to False by default. This will gate access to preview features of Model Monitoring.
432
+ - Model Monitoring: `show_model_monitors` Registry method. This feature is still in Private Preview.
433
+ - Registry: Support `pd.Series` in input and output data.
434
+ - Model Monitoring: `add_monitor` Registry method. This feature is still in Private Preview.
435
+ - Model Monitoring: `resume` and `suspend` ModelMonitor. This feature is still in Private Preview.
436
+ - Model Monitoring: `get_monitor` Registry method. This feature is still in Private Preview.
437
+ - Model Monitoring: `delete_monitor` Registry method. This feature is still in Private Preview.
438
+
439
+ ## 1.7.0 (10-22-2024)
376
440
 
377
441
  ### Behavior Change
378
442