mlrun 1.10.0rc40__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.

Files changed (150) hide show
  1. mlrun/__init__.py +3 -2
  2. mlrun/__main__.py +0 -4
  3. mlrun/artifacts/dataset.py +2 -2
  4. mlrun/artifacts/plots.py +1 -1
  5. mlrun/{model_monitoring/db/tsdb/tdengine → auth}/__init__.py +2 -3
  6. mlrun/auth/nuclio.py +89 -0
  7. mlrun/auth/providers.py +429 -0
  8. mlrun/auth/utils.py +415 -0
  9. mlrun/common/constants.py +7 -0
  10. mlrun/common/model_monitoring/helpers.py +41 -4
  11. mlrun/common/runtimes/constants.py +28 -0
  12. mlrun/common/schemas/__init__.py +13 -3
  13. mlrun/common/schemas/alert.py +2 -2
  14. mlrun/common/schemas/api_gateway.py +3 -0
  15. mlrun/common/schemas/auth.py +10 -10
  16. mlrun/common/schemas/client_spec.py +4 -0
  17. mlrun/common/schemas/constants.py +25 -0
  18. mlrun/common/schemas/frontend_spec.py +1 -8
  19. mlrun/common/schemas/function.py +24 -0
  20. mlrun/common/schemas/hub.py +3 -2
  21. mlrun/common/schemas/model_monitoring/__init__.py +1 -1
  22. mlrun/common/schemas/model_monitoring/constants.py +2 -2
  23. mlrun/common/schemas/secret.py +17 -2
  24. mlrun/common/secrets.py +95 -1
  25. mlrun/common/types.py +10 -10
  26. mlrun/config.py +53 -15
  27. mlrun/data_types/infer.py +2 -2
  28. mlrun/datastore/__init__.py +2 -3
  29. mlrun/datastore/base.py +274 -10
  30. mlrun/datastore/datastore.py +1 -1
  31. mlrun/datastore/datastore_profile.py +49 -17
  32. mlrun/datastore/model_provider/huggingface_provider.py +6 -2
  33. mlrun/datastore/model_provider/model_provider.py +2 -2
  34. mlrun/datastore/model_provider/openai_provider.py +2 -2
  35. mlrun/datastore/s3.py +15 -16
  36. mlrun/datastore/sources.py +1 -1
  37. mlrun/datastore/store_resources.py +4 -4
  38. mlrun/datastore/storeytargets.py +16 -10
  39. mlrun/datastore/targets.py +1 -1
  40. mlrun/datastore/utils.py +16 -3
  41. mlrun/datastore/v3io.py +1 -1
  42. mlrun/db/base.py +36 -12
  43. mlrun/db/httpdb.py +316 -101
  44. mlrun/db/nopdb.py +29 -11
  45. mlrun/errors.py +4 -2
  46. mlrun/execution.py +11 -12
  47. mlrun/feature_store/api.py +1 -1
  48. mlrun/feature_store/common.py +1 -1
  49. mlrun/feature_store/feature_vector_utils.py +1 -1
  50. mlrun/feature_store/steps.py +8 -6
  51. mlrun/frameworks/_common/utils.py +3 -3
  52. mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
  53. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +2 -1
  54. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
  55. mlrun/frameworks/_ml_common/utils.py +2 -1
  56. mlrun/frameworks/auto_mlrun/auto_mlrun.py +4 -3
  57. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +2 -1
  58. mlrun/frameworks/onnx/dataset.py +2 -1
  59. mlrun/frameworks/onnx/mlrun_interface.py +2 -1
  60. mlrun/frameworks/pytorch/callbacks/logging_callback.py +5 -4
  61. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +2 -1
  62. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +2 -1
  63. mlrun/frameworks/pytorch/utils.py +2 -1
  64. mlrun/frameworks/sklearn/metric.py +2 -1
  65. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +5 -4
  66. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +2 -1
  67. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +2 -1
  68. mlrun/hub/__init__.py +37 -0
  69. mlrun/hub/base.py +142 -0
  70. mlrun/hub/module.py +67 -76
  71. mlrun/hub/step.py +113 -0
  72. mlrun/launcher/base.py +2 -1
  73. mlrun/launcher/local.py +2 -1
  74. mlrun/model.py +12 -2
  75. mlrun/model_monitoring/__init__.py +0 -1
  76. mlrun/model_monitoring/api.py +2 -2
  77. mlrun/model_monitoring/applications/base.py +20 -6
  78. mlrun/model_monitoring/applications/context.py +1 -0
  79. mlrun/model_monitoring/controller.py +7 -17
  80. mlrun/model_monitoring/db/_schedules.py +2 -16
  81. mlrun/model_monitoring/db/_stats.py +2 -13
  82. mlrun/model_monitoring/db/tsdb/__init__.py +9 -7
  83. mlrun/model_monitoring/db/tsdb/base.py +2 -4
  84. mlrun/model_monitoring/db/tsdb/preaggregate.py +234 -0
  85. mlrun/model_monitoring/db/tsdb/stream_graph_steps.py +63 -0
  86. mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_metrics_queries.py +414 -0
  87. mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_predictions_queries.py +376 -0
  88. mlrun/model_monitoring/db/tsdb/timescaledb/queries/timescaledb_results_queries.py +590 -0
  89. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_connection.py +434 -0
  90. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_connector.py +541 -0
  91. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_operations.py +808 -0
  92. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_schema.py +502 -0
  93. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_stream.py +163 -0
  94. mlrun/model_monitoring/db/tsdb/timescaledb/timescaledb_stream_graph_steps.py +60 -0
  95. mlrun/model_monitoring/db/tsdb/timescaledb/utils/timescaledb_dataframe_processor.py +141 -0
  96. mlrun/model_monitoring/db/tsdb/timescaledb/utils/timescaledb_query_builder.py +585 -0
  97. mlrun/model_monitoring/db/tsdb/timescaledb/writer_graph_steps.py +73 -0
  98. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +4 -6
  99. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +147 -79
  100. mlrun/model_monitoring/features_drift_table.py +2 -1
  101. mlrun/model_monitoring/helpers.py +2 -1
  102. mlrun/model_monitoring/stream_processing.py +18 -16
  103. mlrun/model_monitoring/writer.py +4 -3
  104. mlrun/package/__init__.py +2 -1
  105. mlrun/platforms/__init__.py +0 -44
  106. mlrun/platforms/iguazio.py +1 -1
  107. mlrun/projects/operations.py +11 -10
  108. mlrun/projects/project.py +81 -82
  109. mlrun/run.py +4 -7
  110. mlrun/runtimes/__init__.py +2 -204
  111. mlrun/runtimes/base.py +89 -21
  112. mlrun/runtimes/constants.py +225 -0
  113. mlrun/runtimes/daskjob.py +4 -2
  114. mlrun/runtimes/databricks_job/databricks_runtime.py +2 -1
  115. mlrun/runtimes/mounts.py +5 -0
  116. mlrun/runtimes/nuclio/__init__.py +12 -8
  117. mlrun/runtimes/nuclio/api_gateway.py +36 -6
  118. mlrun/runtimes/nuclio/application/application.py +200 -32
  119. mlrun/runtimes/nuclio/function.py +154 -49
  120. mlrun/runtimes/nuclio/serving.py +55 -42
  121. mlrun/runtimes/pod.py +59 -10
  122. mlrun/secrets.py +46 -2
  123. mlrun/serving/__init__.py +2 -0
  124. mlrun/serving/remote.py +5 -5
  125. mlrun/serving/routers.py +3 -3
  126. mlrun/serving/server.py +46 -43
  127. mlrun/serving/serving_wrapper.py +6 -2
  128. mlrun/serving/states.py +554 -207
  129. mlrun/serving/steps.py +1 -1
  130. mlrun/serving/system_steps.py +42 -33
  131. mlrun/track/trackers/mlflow_tracker.py +29 -31
  132. mlrun/utils/helpers.py +89 -16
  133. mlrun/utils/http.py +9 -2
  134. mlrun/utils/notifications/notification/git.py +1 -1
  135. mlrun/utils/notifications/notification/mail.py +39 -16
  136. mlrun/utils/notifications/notification_pusher.py +2 -2
  137. mlrun/utils/version/version.json +2 -2
  138. mlrun/utils/version/version.py +3 -4
  139. {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/METADATA +39 -49
  140. {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/RECORD +144 -130
  141. mlrun/db/auth_utils.py +0 -152
  142. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +0 -343
  143. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +0 -75
  144. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connection.py +0 -281
  145. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +0 -1368
  146. mlrun/model_monitoring/db/tsdb/tdengine/writer_graph_steps.py +0 -51
  147. {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/WHEEL +0 -0
  148. {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/entry_points.txt +0 -0
  149. {mlrun-1.10.0rc40.dist-info → mlrun-1.11.0rc16.dist-info}/licenses/LICENSE +0 -0
  150. {mlrun-1.10.0rc40.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