mlrun 1.7.0rc20__py3-none-any.whl → 1.7.0rc28__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.
Potentially problematic release.
This version of mlrun might be problematic. Click here for more details.
- mlrun/__main__.py +10 -8
- mlrun/alerts/alert.py +55 -18
- mlrun/api/schemas/__init__.py +3 -3
- mlrun/artifacts/manager.py +26 -0
- mlrun/common/constants.py +3 -2
- mlrun/common/formatters/__init__.py +1 -0
- mlrun/common/formatters/artifact.py +26 -3
- mlrun/common/formatters/base.py +44 -9
- mlrun/common/formatters/function.py +12 -7
- mlrun/common/formatters/run.py +26 -0
- mlrun/common/helpers.py +11 -0
- mlrun/common/schemas/__init__.py +4 -0
- mlrun/common/schemas/alert.py +5 -9
- mlrun/common/schemas/api_gateway.py +64 -16
- mlrun/common/schemas/artifact.py +11 -0
- mlrun/common/schemas/constants.py +3 -0
- mlrun/common/schemas/feature_store.py +58 -28
- mlrun/common/schemas/model_monitoring/constants.py +21 -12
- mlrun/common/schemas/model_monitoring/model_endpoints.py +0 -12
- mlrun/common/schemas/pipeline.py +16 -0
- mlrun/common/schemas/project.py +17 -0
- mlrun/common/schemas/runs.py +17 -0
- mlrun/common/schemas/schedule.py +1 -1
- mlrun/common/types.py +6 -0
- mlrun/config.py +17 -25
- mlrun/datastore/azure_blob.py +2 -1
- mlrun/datastore/datastore.py +3 -3
- mlrun/datastore/google_cloud_storage.py +6 -2
- mlrun/datastore/snowflake_utils.py +3 -1
- mlrun/datastore/sources.py +26 -11
- mlrun/datastore/store_resources.py +2 -0
- mlrun/datastore/targets.py +68 -16
- mlrun/db/base.py +83 -2
- mlrun/db/httpdb.py +280 -63
- mlrun/db/nopdb.py +60 -3
- mlrun/errors.py +5 -3
- mlrun/execution.py +28 -13
- mlrun/feature_store/feature_vector.py +8 -0
- mlrun/feature_store/retrieval/spark_merger.py +13 -2
- mlrun/launcher/local.py +4 -0
- mlrun/launcher/remote.py +1 -0
- mlrun/model.py +32 -3
- mlrun/model_monitoring/api.py +7 -52
- mlrun/model_monitoring/applications/base.py +5 -7
- mlrun/model_monitoring/applications/histogram_data_drift.py +1 -1
- mlrun/model_monitoring/db/stores/__init__.py +37 -24
- mlrun/model_monitoring/db/stores/base/store.py +40 -1
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +42 -87
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +27 -35
- mlrun/model_monitoring/db/tsdb/__init__.py +15 -15
- mlrun/model_monitoring/db/tsdb/base.py +1 -14
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +22 -18
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +86 -56
- mlrun/model_monitoring/helpers.py +34 -9
- mlrun/model_monitoring/stream_processing.py +12 -11
- mlrun/model_monitoring/writer.py +11 -11
- mlrun/projects/operations.py +5 -0
- mlrun/projects/pipelines.py +35 -21
- mlrun/projects/project.py +216 -107
- mlrun/render.py +10 -5
- mlrun/run.py +15 -5
- mlrun/runtimes/__init__.py +2 -0
- mlrun/runtimes/base.py +17 -4
- mlrun/runtimes/daskjob.py +8 -1
- mlrun/runtimes/databricks_job/databricks_runtime.py +1 -0
- mlrun/runtimes/local.py +23 -4
- mlrun/runtimes/nuclio/application/application.py +0 -2
- mlrun/runtimes/nuclio/function.py +31 -2
- mlrun/runtimes/nuclio/serving.py +9 -6
- mlrun/runtimes/pod.py +5 -29
- mlrun/runtimes/remotesparkjob.py +8 -2
- mlrun/serving/__init__.py +8 -1
- mlrun/serving/routers.py +75 -59
- mlrun/serving/server.py +11 -0
- mlrun/serving/states.py +80 -8
- mlrun/serving/utils.py +19 -11
- mlrun/serving/v2_serving.py +66 -39
- mlrun/utils/helpers.py +91 -11
- mlrun/utils/logger.py +36 -2
- mlrun/utils/notifications/notification/base.py +43 -7
- mlrun/utils/notifications/notification/git.py +21 -0
- mlrun/utils/notifications/notification/slack.py +9 -14
- mlrun/utils/notifications/notification/webhook.py +41 -1
- mlrun/utils/notifications/notification_pusher.py +3 -9
- mlrun/utils/regex.py +9 -0
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/METADATA +16 -9
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/RECORD +92 -91
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/WHEEL +1 -1
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc20.dist-info → mlrun-1.7.0rc28.dist-info}/top_level.txt +0 -0
|
@@ -30,6 +30,27 @@ class GitNotification(NotificationBase):
|
|
|
30
30
|
API/Client notification for setting a rich run statuses git issue comment (github/gitlab)
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
+
@classmethod
|
|
34
|
+
def validate_params(cls, params):
|
|
35
|
+
git_repo = params.get("repo", None)
|
|
36
|
+
git_issue = params.get("issue", None)
|
|
37
|
+
git_merge_request = params.get("merge_request", None)
|
|
38
|
+
token = (
|
|
39
|
+
params.get("token", None)
|
|
40
|
+
or params.get("GIT_TOKEN", None)
|
|
41
|
+
or params.get("GITHUB_TOKEN", None)
|
|
42
|
+
)
|
|
43
|
+
if not git_repo:
|
|
44
|
+
raise ValueError("Parameter 'repo' is required for GitNotification")
|
|
45
|
+
|
|
46
|
+
if not token:
|
|
47
|
+
raise ValueError("Parameter 'token' is required for GitNotification")
|
|
48
|
+
|
|
49
|
+
if not git_issue and not git_merge_request:
|
|
50
|
+
raise ValueError(
|
|
51
|
+
"At least one of 'issue' or 'merge_request' is required for GitNotification"
|
|
52
|
+
)
|
|
53
|
+
|
|
33
54
|
async def push(
|
|
34
55
|
self,
|
|
35
56
|
message: str,
|
|
@@ -35,6 +35,14 @@ class SlackNotification(NotificationBase):
|
|
|
35
35
|
"skipped": ":zzz:",
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
@classmethod
|
|
39
|
+
def validate_params(cls, params):
|
|
40
|
+
webhook = params.get("webhook", None) or mlrun.get_secret_or_env(
|
|
41
|
+
"SLACK_WEBHOOK"
|
|
42
|
+
)
|
|
43
|
+
if not webhook:
|
|
44
|
+
raise ValueError("Parameter 'webhook' is required for SlackNotification")
|
|
45
|
+
|
|
38
46
|
async def push(
|
|
39
47
|
self,
|
|
40
48
|
message: str,
|
|
@@ -153,20 +161,7 @@ class SlackNotification(NotificationBase):
|
|
|
153
161
|
data_text = "\n".join(data_lines)
|
|
154
162
|
line.append(self._get_slack_row(f"*Event data:*\n{data_text}"))
|
|
155
163
|
|
|
156
|
-
|
|
157
|
-
event_data.entity.kind == mlrun.common.schemas.alert.EventEntityKind.JOB
|
|
158
|
-
): # JOB entity
|
|
159
|
-
uid = event_data.value_dict.get("uid")
|
|
160
|
-
url = mlrun.utils.helpers.get_ui_url(alert.project, uid)
|
|
161
|
-
overview_type = "Job overview"
|
|
162
|
-
else: # MODEL entity
|
|
163
|
-
model_name = event_data.value_dict.get("model")
|
|
164
|
-
model_endpoint_id = event_data.value_dict.get("model_endpoint_id")
|
|
165
|
-
url = mlrun.utils.helpers.get_model_endpoint_url(
|
|
166
|
-
alert.project, model_name, model_endpoint_id
|
|
167
|
-
)
|
|
168
|
-
overview_type = "Model endpoint"
|
|
169
|
-
|
|
164
|
+
overview_type, url = self._get_overview_type_and_url(alert, event_data)
|
|
170
165
|
line.append(self._get_slack_row(f"*Overview:*\n<{url}|*{overview_type}*>"))
|
|
171
166
|
|
|
172
167
|
return line
|
|
@@ -28,6 +28,12 @@ class WebhookNotification(NotificationBase):
|
|
|
28
28
|
API/Client notification for sending run statuses in a http request
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
|
+
@classmethod
|
|
32
|
+
def validate_params(cls, params):
|
|
33
|
+
url = params.get("url", None)
|
|
34
|
+
if not url:
|
|
35
|
+
raise ValueError("Parameter 'url' is required for WebhookNotification")
|
|
36
|
+
|
|
31
37
|
async def push(
|
|
32
38
|
self,
|
|
33
39
|
message: str,
|
|
@@ -63,7 +69,7 @@ class WebhookNotification(NotificationBase):
|
|
|
63
69
|
request_body["custom_html"] = custom_html
|
|
64
70
|
|
|
65
71
|
if override_body:
|
|
66
|
-
request_body = override_body
|
|
72
|
+
request_body = self._serialize_runs_in_request_body(override_body, runs)
|
|
67
73
|
|
|
68
74
|
# Specify the `verify_ssl` parameter value only for HTTPS urls.
|
|
69
75
|
# The `ClientSession` allows using `ssl=None` for the default SSL check,
|
|
@@ -77,3 +83,37 @@ class WebhookNotification(NotificationBase):
|
|
|
77
83
|
url, headers=headers, json=request_body, ssl=verify_ssl
|
|
78
84
|
)
|
|
79
85
|
response.raise_for_status()
|
|
86
|
+
|
|
87
|
+
@staticmethod
|
|
88
|
+
def _serialize_runs_in_request_body(override_body, runs):
|
|
89
|
+
str_parsed_runs = ""
|
|
90
|
+
runs = runs or []
|
|
91
|
+
|
|
92
|
+
def parse_runs():
|
|
93
|
+
parsed_runs = []
|
|
94
|
+
for run in runs:
|
|
95
|
+
if hasattr(run, "to_dict"):
|
|
96
|
+
run = run.to_dict()
|
|
97
|
+
if isinstance(run, dict):
|
|
98
|
+
parsed_run = {
|
|
99
|
+
"project": run["metadata"]["project"],
|
|
100
|
+
"name": run["metadata"]["name"],
|
|
101
|
+
"host": run["metadata"]["labels"]["host"],
|
|
102
|
+
"status": {"state": run["status"]["state"]},
|
|
103
|
+
}
|
|
104
|
+
if run["status"].get("error", None):
|
|
105
|
+
parsed_run["status"]["error"] = run["status"]["error"]
|
|
106
|
+
elif run["status"].get("results", None):
|
|
107
|
+
parsed_run["status"]["results"] = run["status"]["results"]
|
|
108
|
+
parsed_runs.append(parsed_run)
|
|
109
|
+
return str(parsed_runs)
|
|
110
|
+
|
|
111
|
+
if isinstance(override_body, dict):
|
|
112
|
+
for key, value in override_body.items():
|
|
113
|
+
if "{{ runs }}" or "{{runs}}" in value:
|
|
114
|
+
if not str_parsed_runs:
|
|
115
|
+
str_parsed_runs = parse_runs()
|
|
116
|
+
override_body[key] = value.replace(
|
|
117
|
+
"{{ runs }}", str_parsed_runs
|
|
118
|
+
).replace("{{runs}}", str_parsed_runs)
|
|
119
|
+
return override_body
|
|
@@ -20,9 +20,9 @@ import traceback
|
|
|
20
20
|
import typing
|
|
21
21
|
from concurrent.futures import ThreadPoolExecutor
|
|
22
22
|
|
|
23
|
-
import kfp
|
|
24
23
|
import mlrun_pipelines.common.ops
|
|
25
24
|
import mlrun_pipelines.models
|
|
25
|
+
import mlrun_pipelines.utils
|
|
26
26
|
|
|
27
27
|
import mlrun.common.constants as mlrun_constants
|
|
28
28
|
import mlrun.common.runtimes.constants
|
|
@@ -397,7 +397,7 @@ class NotificationPusher(_NotificationPusherBase):
|
|
|
397
397
|
try:
|
|
398
398
|
_run = db.list_runs(
|
|
399
399
|
project=run.metadata.project,
|
|
400
|
-
labels=f"mlrun_constants.MLRunInternalLabels.runner_pod={_step.node_name}",
|
|
400
|
+
labels=f"{mlrun_constants.MLRunInternalLabels.runner_pod}={_step.node_name}",
|
|
401
401
|
)[0]
|
|
402
402
|
except IndexError:
|
|
403
403
|
_run = {
|
|
@@ -484,13 +484,7 @@ class NotificationPusher(_NotificationPusherBase):
|
|
|
484
484
|
def _get_workflow_manifest(
|
|
485
485
|
workflow_id: str,
|
|
486
486
|
) -> typing.Optional[mlrun_pipelines.models.PipelineManifest]:
|
|
487
|
-
|
|
488
|
-
if not kfp_url:
|
|
489
|
-
raise mlrun.errors.MLRunNotFoundError(
|
|
490
|
-
"KubeFlow Pipelines is not configured"
|
|
491
|
-
)
|
|
492
|
-
|
|
493
|
-
kfp_client = kfp.Client(host=kfp_url)
|
|
487
|
+
kfp_client = mlrun_pipelines.utils.get_client(mlrun.mlconf)
|
|
494
488
|
|
|
495
489
|
# arbitrary timeout of 5 seconds, the workflow should be done by now
|
|
496
490
|
kfp_run = kfp_client.wait_for_run_completion(workflow_id, 5)
|
mlrun/utils/regex.py
CHANGED
|
@@ -92,3 +92,12 @@ artifact_key = [r"[^\/\\]+$"]
|
|
|
92
92
|
# must be alphanumeric or _
|
|
93
93
|
# max 256 length
|
|
94
94
|
v3io_stream_consumer_group = [r"^(?!_)[a-zA-Z0-9_]{1,256}$"]
|
|
95
|
+
|
|
96
|
+
# URI patterns
|
|
97
|
+
run_uri_pattern = r"^(?P<project>.*)@(?P<uid>.*)\#(?P<iteration>.*?)(:(?P<tag>.*))?$"
|
|
98
|
+
|
|
99
|
+
artifact_uri_pattern = r"^((?P<project>.*)/)?(?P<key>.*?)(\#(?P<iteration>.*?))?(:(?P<tag>.*?))?(@(?P<tree>.*))?$"
|
|
100
|
+
|
|
101
|
+
artifact_producer_uri_pattern = (
|
|
102
|
+
r"^((?P<project>.*)/)?(?P<uid>.*?)(\-(?P<iteration>.*?))?$"
|
|
103
|
+
)
|
mlrun/utils/version/version.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mlrun
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.0rc28
|
|
4
4
|
Summary: Tracking and config of machine learning runs
|
|
5
5
|
Home-page: https://github.com/mlrun/mlrun
|
|
6
6
|
Author: Yaron Haviv
|
|
@@ -28,30 +28,30 @@ Requires-Dist: aiohttp-retry ~=2.8
|
|
|
28
28
|
Requires-Dist: click ~=8.1
|
|
29
29
|
Requires-Dist: nest-asyncio ~=1.0
|
|
30
30
|
Requires-Dist: ipython ~=8.10
|
|
31
|
-
Requires-Dist: nuclio-jupyter ~=0.
|
|
31
|
+
Requires-Dist: nuclio-jupyter ~=0.10.0
|
|
32
32
|
Requires-Dist: numpy <1.27.0,>=1.16.5
|
|
33
33
|
Requires-Dist: pandas <2.2,>=1.2
|
|
34
34
|
Requires-Dist: pyarrow <15,>=10.0
|
|
35
|
-
Requires-Dist: pyyaml
|
|
35
|
+
Requires-Dist: pyyaml <7,>=5.4.1
|
|
36
36
|
Requires-Dist: requests ~=2.31
|
|
37
37
|
Requires-Dist: tabulate ~=0.8.6
|
|
38
38
|
Requires-Dist: v3io ~=0.6.4
|
|
39
39
|
Requires-Dist: pydantic <1.10.15,>=1.10.8
|
|
40
40
|
Requires-Dist: mergedeep ~=1.3
|
|
41
|
-
Requires-Dist: v3io-frames ~=0.10.
|
|
41
|
+
Requires-Dist: v3io-frames ~=0.10.14
|
|
42
42
|
Requires-Dist: semver ~=3.0
|
|
43
43
|
Requires-Dist: dependency-injector ~=4.41
|
|
44
44
|
Requires-Dist: fsspec <2024.4,>=2023.9.2
|
|
45
45
|
Requires-Dist: v3iofs ~=0.1.17
|
|
46
|
-
Requires-Dist: storey ~=1.7.
|
|
46
|
+
Requires-Dist: storey ~=1.7.20
|
|
47
47
|
Requires-Dist: inflection ~=0.5.0
|
|
48
48
|
Requires-Dist: python-dotenv ~=0.17.0
|
|
49
49
|
Requires-Dist: setuptools ~=69.1
|
|
50
50
|
Requires-Dist: deprecated ~=1.2
|
|
51
51
|
Requires-Dist: jinja2 >=3.1.3,~=3.1
|
|
52
52
|
Requires-Dist: orjson <4,>=3.9.15
|
|
53
|
-
Requires-Dist: mlrun-pipelines-kfp-common ~=0.1.
|
|
54
|
-
Requires-Dist: mlrun-pipelines-kfp-v1-8 ~=0.1.
|
|
53
|
+
Requires-Dist: mlrun-pipelines-kfp-common ~=0.1.2
|
|
54
|
+
Requires-Dist: mlrun-pipelines-kfp-v1-8 ~=0.1.2
|
|
55
55
|
Provides-Extra: alibaba-oss
|
|
56
56
|
Requires-Dist: ossfs ==2023.12.0 ; extra == 'alibaba-oss'
|
|
57
57
|
Requires-Dist: oss2 ==2.18.1 ; extra == 'alibaba-oss'
|
|
@@ -81,6 +81,7 @@ Requires-Dist: plotly <5.12.0,~=5.4 ; extra == 'all'
|
|
|
81
81
|
Requires-Dist: pyopenssl >=23 ; extra == 'all'
|
|
82
82
|
Requires-Dist: redis ~=4.3 ; extra == 'all'
|
|
83
83
|
Requires-Dist: s3fs <2024.4,>=2023.9.2 ; extra == 'all'
|
|
84
|
+
Requires-Dist: snowflake-connector-python ~=3.7 ; extra == 'all'
|
|
84
85
|
Requires-Dist: sqlalchemy ~=1.4 ; extra == 'all'
|
|
85
86
|
Requires-Dist: taos-ws-py ~=0.3.2 ; extra == 'all'
|
|
86
87
|
Provides-Extra: api
|
|
@@ -88,13 +89,14 @@ Requires-Dist: uvicorn ~=0.27.1 ; extra == 'api'
|
|
|
88
89
|
Requires-Dist: dask-kubernetes ~=0.11.0 ; extra == 'api'
|
|
89
90
|
Requires-Dist: apscheduler <4,>=3.10.3 ; extra == 'api'
|
|
90
91
|
Requires-Dist: objgraph ~=3.6 ; extra == 'api'
|
|
91
|
-
Requires-Dist: igz-mgmt ~=0.
|
|
92
|
+
Requires-Dist: igz-mgmt ~=0.2.0 ; extra == 'api'
|
|
92
93
|
Requires-Dist: humanfriendly ~=10.0 ; extra == 'api'
|
|
93
94
|
Requires-Dist: fastapi ~=0.110.0 ; extra == 'api'
|
|
94
95
|
Requires-Dist: sqlalchemy ~=1.4 ; extra == 'api'
|
|
95
96
|
Requires-Dist: pymysql ~=1.0 ; extra == 'api'
|
|
96
97
|
Requires-Dist: alembic ~=1.9 ; extra == 'api'
|
|
97
98
|
Requires-Dist: timelength ~=1.1 ; extra == 'api'
|
|
99
|
+
Requires-Dist: memray ~=1.12 ; extra == 'api'
|
|
98
100
|
Provides-Extra: azure-blob-storage
|
|
99
101
|
Requires-Dist: msrest ~=0.6.21 ; extra == 'azure-blob-storage'
|
|
100
102
|
Requires-Dist: azure-core ~=1.24 ; extra == 'azure-blob-storage'
|
|
@@ -129,6 +131,7 @@ Requires-Dist: plotly <5.12.0,~=5.4 ; extra == 'complete'
|
|
|
129
131
|
Requires-Dist: pyopenssl >=23 ; extra == 'complete'
|
|
130
132
|
Requires-Dist: redis ~=4.3 ; extra == 'complete'
|
|
131
133
|
Requires-Dist: s3fs <2024.4,>=2023.9.2 ; extra == 'complete'
|
|
134
|
+
Requires-Dist: snowflake-connector-python ~=3.7 ; extra == 'complete'
|
|
132
135
|
Requires-Dist: sqlalchemy ~=1.4 ; extra == 'complete'
|
|
133
136
|
Requires-Dist: taos-ws-py ~=0.3.2 ; extra == 'complete'
|
|
134
137
|
Provides-Extra: complete-api
|
|
@@ -150,8 +153,9 @@ Requires-Dist: gcsfs <2024.4,>=2023.9.2 ; extra == 'complete-api'
|
|
|
150
153
|
Requires-Dist: google-cloud-bigquery[bqstorage,pandas] ==3.14.1 ; extra == 'complete-api'
|
|
151
154
|
Requires-Dist: graphviz ~=0.20.0 ; extra == 'complete-api'
|
|
152
155
|
Requires-Dist: humanfriendly ~=10.0 ; extra == 'complete-api'
|
|
153
|
-
Requires-Dist: igz-mgmt ~=0.
|
|
156
|
+
Requires-Dist: igz-mgmt ~=0.2.0 ; extra == 'complete-api'
|
|
154
157
|
Requires-Dist: kafka-python ~=2.0 ; extra == 'complete-api'
|
|
158
|
+
Requires-Dist: memray ~=1.12 ; extra == 'complete-api'
|
|
155
159
|
Requires-Dist: mlflow ~=2.8 ; extra == 'complete-api'
|
|
156
160
|
Requires-Dist: msrest ~=0.6.21 ; extra == 'complete-api'
|
|
157
161
|
Requires-Dist: objgraph ~=3.6 ; extra == 'complete-api'
|
|
@@ -162,6 +166,7 @@ Requires-Dist: pymysql ~=1.0 ; extra == 'complete-api'
|
|
|
162
166
|
Requires-Dist: pyopenssl >=23 ; extra == 'complete-api'
|
|
163
167
|
Requires-Dist: redis ~=4.3 ; extra == 'complete-api'
|
|
164
168
|
Requires-Dist: s3fs <2024.4,>=2023.9.2 ; extra == 'complete-api'
|
|
169
|
+
Requires-Dist: snowflake-connector-python ~=3.7 ; extra == 'complete-api'
|
|
165
170
|
Requires-Dist: sqlalchemy ~=1.4 ; extra == 'complete-api'
|
|
166
171
|
Requires-Dist: taos-ws-py ~=0.3.2 ; extra == 'complete-api'
|
|
167
172
|
Requires-Dist: timelength ~=1.1 ; extra == 'complete-api'
|
|
@@ -194,6 +199,8 @@ Provides-Extra: s3
|
|
|
194
199
|
Requires-Dist: boto3 <1.29.0,>=1.28.0 ; extra == 's3'
|
|
195
200
|
Requires-Dist: aiobotocore <2.8,>=2.5.0 ; extra == 's3'
|
|
196
201
|
Requires-Dist: s3fs <2024.4,>=2023.9.2 ; extra == 's3'
|
|
202
|
+
Provides-Extra: snowflake
|
|
203
|
+
Requires-Dist: snowflake-connector-python ~=3.7 ; extra == 'snowflake'
|
|
197
204
|
Provides-Extra: sqlalchemy
|
|
198
205
|
Requires-Dist: sqlalchemy ~=1.4 ; extra == 'sqlalchemy'
|
|
199
206
|
Provides-Extra: tdengine
|