mlrun 1.8.0rc4__py3-none-any.whl → 1.8.0rc7__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 +5 -3
- mlrun/alerts/alert.py +129 -2
- mlrun/artifacts/__init__.py +1 -1
- mlrun/artifacts/base.py +12 -1
- mlrun/artifacts/document.py +59 -38
- mlrun/common/constants.py +1 -0
- mlrun/common/model_monitoring/__init__.py +0 -2
- mlrun/common/model_monitoring/helpers.py +0 -28
- mlrun/common/schemas/__init__.py +2 -4
- mlrun/common/schemas/alert.py +80 -1
- mlrun/common/schemas/artifact.py +4 -0
- mlrun/common/schemas/client_spec.py +0 -1
- mlrun/common/schemas/model_monitoring/__init__.py +0 -6
- mlrun/common/schemas/model_monitoring/constants.py +11 -9
- mlrun/common/schemas/model_monitoring/model_endpoints.py +77 -149
- mlrun/common/schemas/notification.py +6 -0
- mlrun/common/schemas/project.py +3 -0
- mlrun/config.py +2 -3
- mlrun/datastore/datastore_profile.py +57 -17
- mlrun/datastore/sources.py +1 -2
- mlrun/datastore/vectorstore.py +67 -59
- mlrun/db/base.py +29 -19
- mlrun/db/factory.py +0 -3
- mlrun/db/httpdb.py +224 -161
- mlrun/db/nopdb.py +36 -17
- mlrun/execution.py +46 -32
- mlrun/feature_store/api.py +1 -0
- mlrun/model.py +7 -0
- mlrun/model_monitoring/__init__.py +3 -2
- mlrun/model_monitoring/api.py +55 -53
- mlrun/model_monitoring/applications/_application_steps.py +4 -2
- mlrun/model_monitoring/applications/base.py +165 -6
- mlrun/model_monitoring/applications/context.py +88 -37
- mlrun/model_monitoring/applications/evidently_base.py +0 -1
- mlrun/model_monitoring/applications/histogram_data_drift.py +3 -7
- mlrun/model_monitoring/controller.py +43 -37
- mlrun/model_monitoring/db/__init__.py +0 -2
- mlrun/model_monitoring/db/tsdb/base.py +2 -1
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +2 -1
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +43 -0
- mlrun/model_monitoring/helpers.py +79 -66
- mlrun/model_monitoring/stream_processing.py +83 -270
- mlrun/model_monitoring/writer.py +1 -10
- mlrun/projects/pipelines.py +37 -1
- mlrun/projects/project.py +171 -74
- mlrun/run.py +40 -0
- mlrun/runtimes/nuclio/function.py +7 -6
- mlrun/runtimes/nuclio/serving.py +9 -2
- mlrun/serving/routers.py +158 -145
- mlrun/serving/server.py +6 -0
- mlrun/serving/states.py +21 -7
- mlrun/serving/v2_serving.py +70 -61
- mlrun/utils/helpers.py +14 -30
- mlrun/utils/notifications/notification/mail.py +36 -9
- mlrun/utils/notifications/notification_pusher.py +43 -18
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/METADATA +5 -4
- {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/RECORD +62 -75
- mlrun/common/schemas/model_monitoring/model_endpoint_v2.py +0 -149
- mlrun/model_monitoring/db/stores/__init__.py +0 -136
- mlrun/model_monitoring/db/stores/base/__init__.py +0 -15
- mlrun/model_monitoring/db/stores/base/store.py +0 -154
- mlrun/model_monitoring/db/stores/sqldb/__init__.py +0 -13
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +0 -46
- mlrun/model_monitoring/db/stores/sqldb/models/base.py +0 -93
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +0 -47
- mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +0 -25
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +0 -408
- mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +0 -13
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +0 -464
- mlrun/model_monitoring/model_endpoint.py +0 -120
- {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/LICENSE +0 -0
- {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/WHEEL +0 -0
- {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/entry_points.txt +0 -0
- {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/top_level.txt +0 -0
mlrun/datastore/vectorstore.py
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
import inspect
|
|
16
|
-
from
|
|
16
|
+
from collections.abc import Iterable
|
|
17
17
|
from typing import Union
|
|
18
18
|
|
|
19
19
|
from mlrun.artifacts import DocumentArtifact
|
|
@@ -21,57 +21,27 @@ from mlrun.artifacts import DocumentArtifact
|
|
|
21
21
|
|
|
22
22
|
class VectorStoreCollection:
|
|
23
23
|
"""
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
add_documents(documents: list["Document"], **kwargs):
|
|
35
|
-
Adds a list of documents to the collection and updates the MLRun artifacts associated with the documents
|
|
36
|
-
if an MLRun context is present.
|
|
37
|
-
|
|
38
|
-
add_artifacts(artifacts: list[DocumentArtifact], splitter=None, **kwargs):
|
|
39
|
-
Adds a list of DocumentArtifact objects to the collection, optionally using a splitter to convert
|
|
40
|
-
artifacts to documents.
|
|
41
|
-
|
|
42
|
-
remove_itself_from_artifact(artifact: DocumentArtifact):
|
|
43
|
-
Removes the current object from the given artifact's collection and updates the artifact.
|
|
44
|
-
|
|
45
|
-
delete_artifacts(artifacts: list[DocumentArtifact]):
|
|
46
|
-
Deletes a list of DocumentArtifact objects from the collection and updates the MLRun context.
|
|
47
|
-
Raises NotImplementedError if the delete operation is not supported for the collection implementation.
|
|
24
|
+
A wrapper class for vector store collections with MLRun integration.
|
|
25
|
+
|
|
26
|
+
This class wraps a vector store implementation (like Milvus, Chroma) and provides
|
|
27
|
+
integration with MLRun context for document and artifact management. It delegates
|
|
28
|
+
most operations to the underlying vector store while handling MLRun-specific
|
|
29
|
+
functionality.
|
|
30
|
+
|
|
31
|
+
The class implements attribute delegation through __getattr__ and __setattr__,
|
|
32
|
+
allowing direct access to the underlying vector store's methods and attributes
|
|
33
|
+
while maintaining MLRun integration.
|
|
48
34
|
"""
|
|
49
35
|
|
|
50
36
|
def __init__(
|
|
51
37
|
self,
|
|
52
|
-
vector_store_class: str,
|
|
53
38
|
mlrun_context: Union["MlrunProject", "MLClientCtx"], # noqa: F821
|
|
54
|
-
datastore_profile: str,
|
|
55
39
|
collection_name: str,
|
|
56
|
-
|
|
40
|
+
vector_store: "VectorStore", # noqa: F821
|
|
57
41
|
):
|
|
58
|
-
# Import the vector store class dynamically
|
|
59
|
-
module_name, class_name = vector_store_class.rsplit(".", 1)
|
|
60
|
-
module = import_module(module_name)
|
|
61
|
-
vector_store_class = getattr(module, class_name)
|
|
62
|
-
|
|
63
|
-
signature = inspect.signature(vector_store_class)
|
|
64
|
-
|
|
65
|
-
# Create the vector store instance
|
|
66
|
-
if "collection_name" in signature.parameters.keys():
|
|
67
|
-
vector_store = vector_store_class(collection_name=collection_name, **kwargs)
|
|
68
|
-
else:
|
|
69
|
-
vector_store = vector_store_class(**kwargs)
|
|
70
|
-
|
|
71
42
|
self._collection_impl = vector_store
|
|
72
43
|
self._mlrun_context = mlrun_context
|
|
73
44
|
self.collection_name = collection_name
|
|
74
|
-
self.id = datastore_profile + "/" + collection_name
|
|
75
45
|
|
|
76
46
|
def __getattr__(self, name):
|
|
77
47
|
# This method is called when an attribute is not found in the usual places
|
|
@@ -112,40 +82,74 @@ class VectorStoreCollection:
|
|
|
112
82
|
)
|
|
113
83
|
if mlrun_uri:
|
|
114
84
|
artifact = self._mlrun_context.get_store_resource(mlrun_uri)
|
|
115
|
-
artifact.collection_add(self.
|
|
85
|
+
artifact.collection_add(self.collection_name)
|
|
116
86
|
self._mlrun_context.update_artifact(artifact)
|
|
87
|
+
|
|
117
88
|
return self._collection_impl.add_documents(documents, **kwargs)
|
|
118
89
|
|
|
119
90
|
def add_artifacts(self, artifacts: list[DocumentArtifact], splitter=None, **kwargs):
|
|
120
91
|
"""
|
|
121
|
-
Add a list of DocumentArtifact objects to the collection.
|
|
92
|
+
Add a list of DocumentArtifact objects to the vector store collection.
|
|
93
|
+
|
|
94
|
+
Converts artifacts to LangChain documents, adds them to the vector store, and
|
|
95
|
+
updates the MLRun context. If documents are split, the IDs are handled appropriately.
|
|
122
96
|
|
|
123
97
|
Args:
|
|
124
|
-
artifacts (list[DocumentArtifact]):
|
|
125
|
-
splitter (optional):
|
|
126
|
-
|
|
98
|
+
artifacts (list[DocumentArtifact]): List of DocumentArtifact objects to add
|
|
99
|
+
splitter (optional): Document splitter to break artifacts into smaller chunks.
|
|
100
|
+
If None, each artifact becomes a single document.
|
|
101
|
+
**kwargs: Additional arguments passed to the underlying add_documents method.
|
|
102
|
+
Special handling for 'ids' kwarg:
|
|
103
|
+
- If provided and document is split, IDs are generated as "{original_id}_{i}"
|
|
104
|
+
where i starts from 1 (e.g., "doc1_1", "doc1_2", etc.)
|
|
105
|
+
- If provided and document isn't split, original IDs are used as-is
|
|
127
106
|
|
|
128
107
|
Returns:
|
|
129
|
-
list:
|
|
108
|
+
list: List of IDs for all added documents. When no custom IDs are provided:
|
|
109
|
+
- Without splitting: Vector store generates IDs automatically
|
|
110
|
+
- With splitting: Vector store generates separate IDs for each chunk
|
|
111
|
+
When custom IDs are provided:
|
|
112
|
+
- Without splitting: Uses provided IDs directly
|
|
113
|
+
- With splitting: Generates sequential IDs as "{original_id}_{i}" for each chunk
|
|
130
114
|
"""
|
|
131
115
|
all_ids = []
|
|
132
|
-
|
|
116
|
+
user_ids = kwargs.pop("ids", None)
|
|
117
|
+
|
|
118
|
+
if user_ids:
|
|
119
|
+
if not isinstance(user_ids, Iterable):
|
|
120
|
+
raise ValueError("IDs must be an iterable collection")
|
|
121
|
+
if len(user_ids) != len(artifacts):
|
|
122
|
+
raise ValueError(
|
|
123
|
+
"The number of IDs should match the number of artifacts"
|
|
124
|
+
)
|
|
125
|
+
for index, artifact in enumerate(artifacts):
|
|
133
126
|
documents = artifact.to_langchain_documents(splitter)
|
|
134
|
-
artifact.collection_add(self.
|
|
135
|
-
self._mlrun_context
|
|
127
|
+
artifact.collection_add(self.collection_name)
|
|
128
|
+
if self._mlrun_context:
|
|
129
|
+
self._mlrun_context.update_artifact(artifact)
|
|
130
|
+
if user_ids:
|
|
131
|
+
num_of_documents = len(documents)
|
|
132
|
+
if num_of_documents > 1:
|
|
133
|
+
ids_to_pass = [
|
|
134
|
+
f"{user_ids[index]}_{i}" for i in range(1, num_of_documents + 1)
|
|
135
|
+
]
|
|
136
|
+
else:
|
|
137
|
+
ids_to_pass = [user_ids[index]]
|
|
138
|
+
kwargs["ids"] = ids_to_pass
|
|
136
139
|
ids = self._collection_impl.add_documents(documents, **kwargs)
|
|
137
140
|
all_ids.extend(ids)
|
|
138
141
|
return all_ids
|
|
139
142
|
|
|
140
|
-
def
|
|
143
|
+
def remove_from_artifact(self, artifact: DocumentArtifact):
|
|
141
144
|
"""
|
|
142
145
|
Remove the current object from the given artifact's collection and update the artifact.
|
|
143
146
|
|
|
144
147
|
Args:
|
|
145
148
|
artifact (DocumentArtifact): The artifact from which the current object should be removed.
|
|
146
149
|
"""
|
|
147
|
-
artifact.collection_remove(self.
|
|
148
|
-
self._mlrun_context
|
|
150
|
+
artifact.collection_remove(self.collection_name)
|
|
151
|
+
if self._mlrun_context:
|
|
152
|
+
self._mlrun_context.update_artifact(artifact)
|
|
149
153
|
|
|
150
154
|
def delete_artifacts(self, artifacts: list[DocumentArtifact]):
|
|
151
155
|
"""
|
|
@@ -162,13 +166,15 @@ class VectorStoreCollection:
|
|
|
162
166
|
"""
|
|
163
167
|
store_class = self._collection_impl.__class__.__name__.lower()
|
|
164
168
|
for artifact in artifacts:
|
|
165
|
-
artifact.collection_remove(self.
|
|
166
|
-
self._mlrun_context
|
|
169
|
+
artifact.collection_remove(self.collection_name)
|
|
170
|
+
if self._mlrun_context:
|
|
171
|
+
self._mlrun_context.update_artifact(artifact)
|
|
172
|
+
|
|
167
173
|
if store_class == "milvus":
|
|
168
|
-
expr = f"{DocumentArtifact.METADATA_SOURCE_KEY} == '{artifact.
|
|
174
|
+
expr = f"{DocumentArtifact.METADATA_SOURCE_KEY} == '{artifact.get_source()}'"
|
|
169
175
|
return self._collection_impl.delete(expr=expr)
|
|
170
176
|
elif store_class == "chroma":
|
|
171
|
-
where = {DocumentArtifact.METADATA_SOURCE_KEY: artifact.
|
|
177
|
+
where = {DocumentArtifact.METADATA_SOURCE_KEY: artifact.get_source()}
|
|
172
178
|
return self._collection_impl.delete(where=where)
|
|
173
179
|
|
|
174
180
|
elif (
|
|
@@ -177,7 +183,9 @@ class VectorStoreCollection:
|
|
|
177
183
|
in inspect.signature(self._collection_impl.delete).parameters
|
|
178
184
|
):
|
|
179
185
|
filter = {
|
|
180
|
-
"metadata": {
|
|
186
|
+
"metadata": {
|
|
187
|
+
DocumentArtifact.METADATA_SOURCE_KEY: artifact.get_source()
|
|
188
|
+
}
|
|
181
189
|
}
|
|
182
190
|
return self._collection_impl.delete(filter=filter)
|
|
183
191
|
else:
|
mlrun/db/base.py
CHANGED
|
@@ -370,7 +370,9 @@ class RunDBInterface(ABC):
|
|
|
370
370
|
pass
|
|
371
371
|
|
|
372
372
|
@abstractmethod
|
|
373
|
-
def get_project(
|
|
373
|
+
def get_project(
|
|
374
|
+
self, name: str
|
|
375
|
+
) -> Union[mlrun.common.schemas.Project, "mlrun.MlrunProject"]:
|
|
374
376
|
pass
|
|
375
377
|
|
|
376
378
|
@abstractmethod
|
|
@@ -663,16 +665,16 @@ class RunDBInterface(ABC):
|
|
|
663
665
|
@abstractmethod
|
|
664
666
|
def create_model_endpoint(
|
|
665
667
|
self,
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
model_endpoint: Union[mlrun.model_monitoring.ModelEndpoint, dict],
|
|
669
|
-
):
|
|
668
|
+
model_endpoint: mlrun.common.schemas.ModelEndpoint,
|
|
669
|
+
) -> mlrun.common.schemas.ModelEndpoint:
|
|
670
670
|
pass
|
|
671
671
|
|
|
672
672
|
@abstractmethod
|
|
673
673
|
def delete_model_endpoint(
|
|
674
674
|
self,
|
|
675
|
+
name: str,
|
|
675
676
|
project: str,
|
|
677
|
+
function_name: str,
|
|
676
678
|
endpoint_id: str,
|
|
677
679
|
):
|
|
678
680
|
pass
|
|
@@ -681,36 +683,40 @@ class RunDBInterface(ABC):
|
|
|
681
683
|
def list_model_endpoints(
|
|
682
684
|
self,
|
|
683
685
|
project: str,
|
|
684
|
-
|
|
685
|
-
|
|
686
|
+
name: Optional[str] = None,
|
|
687
|
+
function_name: Optional[str] = None,
|
|
688
|
+
model_name: Optional[str] = None,
|
|
686
689
|
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
687
|
-
start:
|
|
688
|
-
end:
|
|
689
|
-
|
|
690
|
+
start: Optional[datetime.datetime] = None,
|
|
691
|
+
end: Optional[datetime.datetime] = None,
|
|
692
|
+
tsdb_metrics: bool = True,
|
|
690
693
|
top_level: bool = False,
|
|
691
694
|
uids: Optional[list[str]] = None,
|
|
692
|
-
|
|
695
|
+
latest_only: bool = False,
|
|
696
|
+
) -> mlrun.common.schemas.ModelEndpointList:
|
|
693
697
|
pass
|
|
694
698
|
|
|
695
699
|
@abstractmethod
|
|
696
700
|
def get_model_endpoint(
|
|
697
701
|
self,
|
|
702
|
+
name: str,
|
|
698
703
|
project: str,
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
) -> mlrun.model_monitoring.ModelEndpoint:
|
|
704
|
+
function_name: Optional[str] = None,
|
|
705
|
+
endpoint_id: Optional[str] = None,
|
|
706
|
+
tsdb_metrics: bool = True,
|
|
707
|
+
feature_analysis: bool = False,
|
|
708
|
+
) -> mlrun.common.schemas.ModelEndpoint:
|
|
705
709
|
pass
|
|
706
710
|
|
|
707
711
|
@abstractmethod
|
|
708
712
|
def patch_model_endpoint(
|
|
709
713
|
self,
|
|
714
|
+
name: str,
|
|
710
715
|
project: str,
|
|
711
|
-
endpoint_id: str,
|
|
712
716
|
attributes: dict,
|
|
713
|
-
|
|
717
|
+
function_name: Optional[str] = None,
|
|
718
|
+
endpoint_id: Optional[str] = None,
|
|
719
|
+
) -> mlrun.common.schemas.ModelEndpoint:
|
|
714
720
|
pass
|
|
715
721
|
|
|
716
722
|
@abstractmethod
|
|
@@ -1051,3 +1057,7 @@ class RunDBInterface(ABC):
|
|
|
1051
1057
|
replace_creds: bool,
|
|
1052
1058
|
) -> None:
|
|
1053
1059
|
pass
|
|
1060
|
+
|
|
1061
|
+
@abstractmethod
|
|
1062
|
+
def get_project_summary(self, project: str) -> mlrun.common.schemas.ProjectSummary:
|
|
1063
|
+
pass
|
mlrun/db/factory.py
CHANGED
|
@@ -54,9 +54,6 @@ class RunDBFactory(
|
|
|
54
54
|
self._run_db = self._rundb_container.nop(url)
|
|
55
55
|
|
|
56
56
|
else:
|
|
57
|
-
# TODO: this practically makes the SQLRunDB a singleton, which mean that its session is shared, needs
|
|
58
|
-
# to be refreshed frequently and cannot be used concurrently.
|
|
59
|
-
# The SQLRunDB should always get its session from the FastAPI dependency injection.
|
|
60
57
|
self._run_db = self._rundb_container.run_db(url)
|
|
61
58
|
|
|
62
59
|
self._run_db.connect(secrets=secrets)
|