mlrun 1.10.0rc18__py3-none-any.whl → 1.11.0rc16__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/__init__.py +24 -3
- mlrun/__main__.py +0 -4
- mlrun/artifacts/dataset.py +2 -2
- mlrun/artifacts/document.py +6 -1
- mlrun/artifacts/llm_prompt.py +21 -15
- mlrun/artifacts/model.py +3 -3
- mlrun/artifacts/plots.py +1 -1
- mlrun/{model_monitoring/db/tsdb/tdengine → auth}/__init__.py +2 -3
- mlrun/auth/nuclio.py +89 -0
- mlrun/auth/providers.py +429 -0
- mlrun/auth/utils.py +415 -0
- mlrun/common/constants.py +14 -0
- mlrun/common/model_monitoring/helpers.py +123 -0
- mlrun/common/runtimes/constants.py +28 -0
- mlrun/common/schemas/__init__.py +14 -3
- mlrun/common/schemas/alert.py +2 -2
- mlrun/common/schemas/api_gateway.py +3 -0
- mlrun/common/schemas/auth.py +12 -10
- mlrun/common/schemas/client_spec.py +4 -0
- mlrun/common/schemas/constants.py +25 -0
- mlrun/common/schemas/frontend_spec.py +1 -8
- mlrun/common/schemas/function.py +34 -0
- mlrun/common/schemas/hub.py +33 -20
- mlrun/common/schemas/model_monitoring/__init__.py +2 -1
- mlrun/common/schemas/model_monitoring/constants.py +12 -15
- mlrun/common/schemas/model_monitoring/functions.py +13 -4
- mlrun/common/schemas/model_monitoring/model_endpoints.py +11 -0
- mlrun/common/schemas/pipeline.py +1 -1
- mlrun/common/schemas/secret.py +17 -2
- mlrun/common/secrets.py +95 -1
- mlrun/common/types.py +10 -10
- mlrun/config.py +69 -19
- mlrun/data_types/infer.py +2 -2
- mlrun/datastore/__init__.py +12 -5
- mlrun/datastore/azure_blob.py +162 -47
- mlrun/datastore/base.py +274 -10
- mlrun/datastore/datastore.py +7 -2
- mlrun/datastore/datastore_profile.py +84 -22
- mlrun/datastore/model_provider/huggingface_provider.py +225 -41
- mlrun/datastore/model_provider/mock_model_provider.py +87 -0
- mlrun/datastore/model_provider/model_provider.py +206 -74
- mlrun/datastore/model_provider/openai_provider.py +226 -66
- mlrun/datastore/s3.py +39 -18
- mlrun/datastore/sources.py +1 -1
- mlrun/datastore/store_resources.py +4 -4
- mlrun/datastore/storeytargets.py +17 -12
- mlrun/datastore/targets.py +1 -1
- mlrun/datastore/utils.py +25 -6
- mlrun/datastore/v3io.py +1 -1
- mlrun/db/base.py +63 -32
- mlrun/db/httpdb.py +373 -153
- mlrun/db/nopdb.py +54 -21
- mlrun/errors.py +4 -2
- mlrun/execution.py +66 -25
- mlrun/feature_store/api.py +1 -1
- mlrun/feature_store/common.py +1 -1
- mlrun/feature_store/feature_vector_utils.py +1 -1
- mlrun/feature_store/steps.py +8 -6
- mlrun/frameworks/_common/utils.py +3 -3
- mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +2 -1
- mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
- mlrun/frameworks/_ml_common/utils.py +2 -1
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +4 -3
- mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +2 -1
- mlrun/frameworks/onnx/dataset.py +2 -1
- mlrun/frameworks/onnx/mlrun_interface.py +2 -1
- mlrun/frameworks/pytorch/callbacks/logging_callback.py +5 -4
- mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +2 -1
- mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +2 -1
- mlrun/frameworks/pytorch/utils.py +2 -1
- mlrun/frameworks/sklearn/metric.py +2 -1
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +5 -4
- mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +2 -1
- mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +2 -1
- mlrun/hub/__init__.py +52 -0
- mlrun/hub/base.py +142 -0
- mlrun/hub/module.py +172 -0
- mlrun/hub/step.py +113 -0
- mlrun/k8s_utils.py +105 -16
- mlrun/launcher/base.py +15 -7
- mlrun/launcher/local.py +4 -1
- mlrun/model.py +14 -4
- mlrun/model_monitoring/__init__.py +0 -1
- mlrun/model_monitoring/api.py +65 -28
- mlrun/model_monitoring/applications/__init__.py +1 -1
- mlrun/model_monitoring/applications/base.py +299 -128
- mlrun/model_monitoring/applications/context.py +2 -4
- mlrun/model_monitoring/controller.py +132 -58
- mlrun/model_monitoring/db/_schedules.py +38 -29
- mlrun/model_monitoring/db/_stats.py +6 -16
- mlrun/model_monitoring/db/tsdb/__init__.py +9 -7
- mlrun/model_monitoring/db/tsdb/base.py +29 -9
- mlrun/model_monitoring/db/tsdb/preaggregate.py +234 -0
- mlrun/model_monitoring/db/tsdb/stream_graph_steps.py +63 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_metrics_queries.py +414 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_predictions_queries.py +376 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_results_queries.py +590 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_connection.py +434 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_connector.py +541 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_operations.py +808 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_schema.py +502 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_stream.py +163 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_stream_graph_steps.py +60 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/utils/timescaledb_dataframe_processor.py +141 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/utils/timescaledb_query_builder.py +585 -0
- mlrun/model_monitoring/db/tsdb/timescaledb/writer_graph_steps.py +73 -0
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +20 -9
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +235 -51
- mlrun/model_monitoring/features_drift_table.py +2 -1
- mlrun/model_monitoring/helpers.py +30 -6
- mlrun/model_monitoring/stream_processing.py +34 -28
- mlrun/model_monitoring/writer.py +224 -4
- mlrun/package/__init__.py +2 -1
- mlrun/platforms/__init__.py +0 -43
- mlrun/platforms/iguazio.py +8 -4
- mlrun/projects/operations.py +17 -11
- mlrun/projects/pipelines.py +2 -2
- mlrun/projects/project.py +187 -123
- mlrun/run.py +95 -21
- mlrun/runtimes/__init__.py +2 -186
- mlrun/runtimes/base.py +103 -25
- mlrun/runtimes/constants.py +225 -0
- mlrun/runtimes/daskjob.py +5 -2
- mlrun/runtimes/databricks_job/databricks_runtime.py +2 -1
- mlrun/runtimes/local.py +5 -2
- mlrun/runtimes/mounts.py +20 -2
- mlrun/runtimes/nuclio/__init__.py +12 -7
- mlrun/runtimes/nuclio/api_gateway.py +36 -6
- mlrun/runtimes/nuclio/application/application.py +339 -40
- mlrun/runtimes/nuclio/function.py +222 -72
- mlrun/runtimes/nuclio/serving.py +132 -42
- mlrun/runtimes/pod.py +213 -21
- mlrun/runtimes/utils.py +49 -9
- mlrun/secrets.py +99 -14
- mlrun/serving/__init__.py +2 -0
- mlrun/serving/remote.py +84 -11
- mlrun/serving/routers.py +26 -44
- mlrun/serving/server.py +138 -51
- mlrun/serving/serving_wrapper.py +6 -2
- mlrun/serving/states.py +997 -283
- mlrun/serving/steps.py +62 -0
- mlrun/serving/system_steps.py +149 -95
- mlrun/serving/v2_serving.py +9 -10
- mlrun/track/trackers/mlflow_tracker.py +29 -31
- mlrun/utils/helpers.py +292 -94
- mlrun/utils/http.py +9 -2
- mlrun/utils/notifications/notification/base.py +18 -0
- mlrun/utils/notifications/notification/git.py +3 -5
- mlrun/utils/notifications/notification/mail.py +39 -16
- mlrun/utils/notifications/notification/slack.py +2 -4
- mlrun/utils/notifications/notification/webhook.py +2 -5
- mlrun/utils/notifications/notification_pusher.py +3 -3
- mlrun/utils/version/version.json +2 -2
- mlrun/utils/version/version.py +3 -4
- {mlrun-1.10.0rc18.dist-info → mlrun-1.11.0rc16.dist-info}/METADATA +63 -74
- {mlrun-1.10.0rc18.dist-info → mlrun-1.11.0rc16.dist-info}/RECORD +161 -143
- mlrun/api/schemas/__init__.py +0 -259
- mlrun/db/auth_utils.py +0 -152
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +0 -344
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +0 -75
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connection.py +0 -281
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +0 -1266
- {mlrun-1.10.0rc18.dist-info → mlrun-1.11.0rc16.dist-info}/WHEEL +0 -0
- {mlrun-1.10.0rc18.dist-info → mlrun-1.11.0rc16.dist-info}/entry_points.txt +0 -0
- {mlrun-1.10.0rc18.dist-info → mlrun-1.11.0rc16.dist-info}/licenses/LICENSE +0 -0
- {mlrun-1.10.0rc18.dist-info → mlrun-1.11.0rc16.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Copyright 2025 Iguazio
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
|
|
17
|
+
import mlrun.feature_store.steps
|
|
18
|
+
from mlrun.common.schemas.model_monitoring import (
|
|
19
|
+
EventFieldType,
|
|
20
|
+
EventKeyMetrics,
|
|
21
|
+
StreamProcessingEvent,
|
|
22
|
+
WriterEvent,
|
|
23
|
+
)
|
|
24
|
+
from mlrun.model_monitoring.db.tsdb.stream_graph_steps import BaseErrorExtractor
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ProcessBeforeTimescaleDB(mlrun.feature_store.steps.MapClass):
|
|
28
|
+
"""
|
|
29
|
+
Process the data before writing to TimescaleDB. This step creates the relevant keys for the TimescaleDB table,
|
|
30
|
+
including project name, custom metrics, time column, and table name column.
|
|
31
|
+
|
|
32
|
+
:returns: Event as a dictionary
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def do(self, event):
|
|
36
|
+
if isinstance(event, list):
|
|
37
|
+
event = event[0]
|
|
38
|
+
event[EventFieldType.PROJECT] = event[EventFieldType.FUNCTION_URI].split("/")[0]
|
|
39
|
+
event[EventKeyMetrics.CUSTOM_METRICS] = json.dumps(
|
|
40
|
+
event.get(EventFieldType.METRICS, {})
|
|
41
|
+
)
|
|
42
|
+
# Map WHEN field to END_INFER_TIME for predictions data from model serving
|
|
43
|
+
if StreamProcessingEvent.WHEN in event:
|
|
44
|
+
event[WriterEvent.END_INFER_TIME] = event[StreamProcessingEvent.WHEN]
|
|
45
|
+
# For non-prediction events, use timestamp as END_INFER_TIME to maintain consistency
|
|
46
|
+
elif EventFieldType.TIMESTAMP in event:
|
|
47
|
+
event[WriterEvent.END_INFER_TIME] = event[EventFieldType.TIMESTAMP]
|
|
48
|
+
event[EventFieldType.TABLE_COLUMN] = f"_{event.get(EventFieldType.ENDPOINT_ID)}"
|
|
49
|
+
|
|
50
|
+
return event
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class TimescaleDBErrorExtractor(BaseErrorExtractor):
|
|
54
|
+
"""
|
|
55
|
+
TimescaleDB-specific error extractor.
|
|
56
|
+
|
|
57
|
+
Uses the shared base implementation with TimescaleDB-specific configuration.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
pass
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Copyright 2025 Iguazio
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
import pandas as pd
|
|
18
|
+
|
|
19
|
+
import mlrun.common.schemas.model_monitoring as mm_schemas
|
|
20
|
+
from mlrun.model_monitoring.db.tsdb.timescaledb.timescaledb_connection import (
|
|
21
|
+
QueryResult,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class TimescaleDBDataFrameProcessor:
|
|
26
|
+
"""Utility class for common DataFrame processing operations."""
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def from_query_result(result: Optional[QueryResult]) -> pd.DataFrame:
|
|
30
|
+
"""
|
|
31
|
+
Create a DataFrame from a QueryResult object.
|
|
32
|
+
|
|
33
|
+
:param result: QueryResult object from TimescaleDB connection
|
|
34
|
+
:return: pandas DataFrame
|
|
35
|
+
"""
|
|
36
|
+
return pd.DataFrame(
|
|
37
|
+
result.data if result else [], columns=result.fields if result else []
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
@staticmethod
|
|
41
|
+
def apply_column_mapping(
|
|
42
|
+
df: pd.DataFrame, mapping_config: dict[str, str]
|
|
43
|
+
) -> pd.DataFrame:
|
|
44
|
+
"""
|
|
45
|
+
Apply column name mapping to a DataFrame.
|
|
46
|
+
|
|
47
|
+
:param df: Input DataFrame
|
|
48
|
+
:param mapping_config: Dictionary mapping old column names to new names
|
|
49
|
+
:return: DataFrame with renamed columns
|
|
50
|
+
"""
|
|
51
|
+
if df.empty or not mapping_config:
|
|
52
|
+
return df
|
|
53
|
+
|
|
54
|
+
if valid_mapping := {
|
|
55
|
+
old: new for old, new in mapping_config.items() if old in df.columns
|
|
56
|
+
}:
|
|
57
|
+
df = df.rename(columns=valid_mapping)
|
|
58
|
+
|
|
59
|
+
return df
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def handle_empty_dataframe(
|
|
63
|
+
full_name: str, metric_type: str = "METRIC"
|
|
64
|
+
) -> mm_schemas.ModelEndpointMonitoringMetricNoData:
|
|
65
|
+
"""
|
|
66
|
+
Create a standardized response for empty query results.
|
|
67
|
+
|
|
68
|
+
:param full_name: Full metric name
|
|
69
|
+
:param metric_type: Type of metric (METRIC or RESULT)
|
|
70
|
+
:return: ModelEndpointMonitoringMetricNoData object
|
|
71
|
+
"""
|
|
72
|
+
return mm_schemas.ModelEndpointMonitoringMetricNoData(
|
|
73
|
+
full_name=full_name,
|
|
74
|
+
type=getattr(
|
|
75
|
+
mm_schemas.ModelEndpointMonitoringMetricType,
|
|
76
|
+
metric_type,
|
|
77
|
+
mm_schemas.ModelEndpointMonitoringMetricType.METRIC,
|
|
78
|
+
),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
def build_flexible_column_mapping(
|
|
83
|
+
df: pd.DataFrame, target_patterns: dict[str, list[str]]
|
|
84
|
+
) -> dict[str, str]:
|
|
85
|
+
"""
|
|
86
|
+
Build column mapping by finding columns that match target patterns.
|
|
87
|
+
|
|
88
|
+
This handles cases where pre-aggregate queries return columns with different names
|
|
89
|
+
than expected (e.g., "avg_latency" vs "latency").
|
|
90
|
+
|
|
91
|
+
LIMITATION: This method uses first-match logic and cannot handle multiple aggregates
|
|
92
|
+
of the same base column (e.g., both "avg_latency" and "max_latency" in the same DataFrame).
|
|
93
|
+
It's designed for single-aggregate scenarios or pre-aggregate fallback mapping.
|
|
94
|
+
|
|
95
|
+
For multi-aggregate support, each aggregate should have distinct target patterns.
|
|
96
|
+
|
|
97
|
+
:param df: Input DataFrame
|
|
98
|
+
:param target_patterns: Dict mapping target names to lists of patterns to search for.
|
|
99
|
+
Each target should map to only one expected column in the DataFrame.
|
|
100
|
+
:return: Dictionary mapping found column names to target names
|
|
101
|
+
"""
|
|
102
|
+
if df.empty:
|
|
103
|
+
return {}
|
|
104
|
+
|
|
105
|
+
# Pre-compute all patterns once
|
|
106
|
+
exact_patterns = {} # pattern -> target_name (case-insensitive)
|
|
107
|
+
fuzzy_patterns = [] # (target_name, pattern_words_set) for O(1) word lookups
|
|
108
|
+
|
|
109
|
+
for target_name, patterns in target_patterns.items():
|
|
110
|
+
for pattern in patterns:
|
|
111
|
+
pattern_lower = pattern.lower()
|
|
112
|
+
exact_patterns[pattern_lower] = target_name
|
|
113
|
+
|
|
114
|
+
# Use set for O(1) word lookup instead of list
|
|
115
|
+
pattern_words = set(pattern_lower.split("_"))
|
|
116
|
+
fuzzy_patterns.append((target_name, pattern_words))
|
|
117
|
+
|
|
118
|
+
mapping = {}
|
|
119
|
+
|
|
120
|
+
# Process columns with early termination
|
|
121
|
+
for col in df.columns:
|
|
122
|
+
col_lower = col.lower()
|
|
123
|
+
|
|
124
|
+
# Exact match - O(1)
|
|
125
|
+
if target_name := exact_patterns.get(col_lower):
|
|
126
|
+
if col != target_name: # Only add if different
|
|
127
|
+
mapping[col] = target_name
|
|
128
|
+
continue
|
|
129
|
+
|
|
130
|
+
# Fuzzy match - optimized with set operations
|
|
131
|
+
col_words = set(col_lower.split("_"))
|
|
132
|
+
|
|
133
|
+
for target_name, pattern_words in fuzzy_patterns:
|
|
134
|
+
# Require ALL pattern words to be present (subset match)
|
|
135
|
+
# This ensures "avg_latency" pattern only matches columns containing both words
|
|
136
|
+
if pattern_words.issubset(col_words):
|
|
137
|
+
if col != target_name:
|
|
138
|
+
mapping[col] = target_name
|
|
139
|
+
break
|
|
140
|
+
|
|
141
|
+
return mapping
|