mlrun 1.8.0rc4__py3-none-any.whl → 1.8.0rc6__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 (69) hide show
  1. mlrun/__init__.py +4 -3
  2. mlrun/alerts/alert.py +129 -2
  3. mlrun/artifacts/__init__.py +1 -1
  4. mlrun/artifacts/base.py +12 -1
  5. mlrun/artifacts/document.py +59 -38
  6. mlrun/common/model_monitoring/__init__.py +0 -2
  7. mlrun/common/model_monitoring/helpers.py +0 -28
  8. mlrun/common/schemas/__init__.py +1 -4
  9. mlrun/common/schemas/alert.py +3 -0
  10. mlrun/common/schemas/artifact.py +4 -0
  11. mlrun/common/schemas/client_spec.py +0 -1
  12. mlrun/common/schemas/model_monitoring/__init__.py +0 -6
  13. mlrun/common/schemas/model_monitoring/constants.py +11 -9
  14. mlrun/common/schemas/model_monitoring/model_endpoints.py +77 -149
  15. mlrun/common/schemas/notification.py +6 -0
  16. mlrun/config.py +0 -2
  17. mlrun/datastore/datastore_profile.py +57 -17
  18. mlrun/datastore/vectorstore.py +67 -59
  19. mlrun/db/base.py +22 -18
  20. mlrun/db/factory.py +0 -3
  21. mlrun/db/httpdb.py +122 -150
  22. mlrun/db/nopdb.py +33 -17
  23. mlrun/execution.py +43 -29
  24. mlrun/model.py +7 -0
  25. mlrun/model_monitoring/__init__.py +3 -2
  26. mlrun/model_monitoring/api.py +40 -43
  27. mlrun/model_monitoring/applications/_application_steps.py +4 -2
  28. mlrun/model_monitoring/applications/base.py +65 -6
  29. mlrun/model_monitoring/applications/context.py +64 -33
  30. mlrun/model_monitoring/applications/evidently_base.py +0 -1
  31. mlrun/model_monitoring/applications/histogram_data_drift.py +2 -6
  32. mlrun/model_monitoring/controller.py +43 -37
  33. mlrun/model_monitoring/db/__init__.py +0 -2
  34. mlrun/model_monitoring/db/tsdb/base.py +2 -1
  35. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +2 -1
  36. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +43 -0
  37. mlrun/model_monitoring/helpers.py +12 -66
  38. mlrun/model_monitoring/stream_processing.py +83 -270
  39. mlrun/model_monitoring/writer.py +1 -10
  40. mlrun/projects/project.py +87 -74
  41. mlrun/runtimes/nuclio/function.py +7 -6
  42. mlrun/runtimes/nuclio/serving.py +7 -1
  43. mlrun/serving/routers.py +158 -145
  44. mlrun/serving/server.py +6 -0
  45. mlrun/serving/states.py +2 -0
  46. mlrun/serving/v2_serving.py +69 -60
  47. mlrun/utils/helpers.py +14 -30
  48. mlrun/utils/notifications/notification/mail.py +36 -9
  49. mlrun/utils/notifications/notification_pusher.py +34 -13
  50. mlrun/utils/version/version.json +2 -2
  51. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc6.dist-info}/METADATA +5 -4
  52. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc6.dist-info}/RECORD +56 -69
  53. mlrun/common/schemas/model_monitoring/model_endpoint_v2.py +0 -149
  54. mlrun/model_monitoring/db/stores/__init__.py +0 -136
  55. mlrun/model_monitoring/db/stores/base/__init__.py +0 -15
  56. mlrun/model_monitoring/db/stores/base/store.py +0 -154
  57. mlrun/model_monitoring/db/stores/sqldb/__init__.py +0 -13
  58. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +0 -46
  59. mlrun/model_monitoring/db/stores/sqldb/models/base.py +0 -93
  60. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +0 -47
  61. mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +0 -25
  62. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +0 -408
  63. mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +0 -13
  64. mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +0 -464
  65. mlrun/model_monitoring/model_endpoint.py +0 -120
  66. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc6.dist-info}/LICENSE +0 -0
  67. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc6.dist-info}/WHEEL +0 -0
  68. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc6.dist-info}/entry_points.txt +0 -0
  69. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc6.dist-info}/top_level.txt +0 -0
mlrun/projects/project.py CHANGED
@@ -28,7 +28,7 @@ import warnings
28
28
  import zipfile
29
29
  from copy import deepcopy
30
30
  from os import environ, makedirs, path
31
- from typing import Callable, Optional, Union
31
+ from typing import Callable, Optional, Union, cast
32
32
 
33
33
  import dotenv
34
34
  import git
@@ -62,7 +62,6 @@ from mlrun.alerts.alert import AlertConfig
62
62
  from mlrun.datastore.datastore_profile import (
63
63
  DatastoreProfile,
64
64
  DatastoreProfile2Json,
65
- VectorStoreProfile,
66
65
  datastore_profile_read,
67
66
  )
68
67
  from mlrun.datastore.vectorstore import VectorStoreCollection
@@ -1535,7 +1534,9 @@ class MlrunProject(ModelObj):
1535
1534
 
1536
1535
  def update_artifact(self, artifact_object: Artifact):
1537
1536
  artifacts_manager = self._get_artifact_manager()
1538
- artifacts_manager.update_artifact(artifact_object, artifact_object)
1537
+ project_tag = self._get_project_tag()
1538
+ producer, _ = self._resolve_artifact_producer(artifact_object, project_tag)
1539
+ artifacts_manager.update_artifact(producer, artifact_object)
1539
1540
 
1540
1541
  def _get_artifact_manager(self):
1541
1542
  if self._artifact_manager:
@@ -1732,7 +1733,7 @@ class MlrunProject(ModelObj):
1732
1733
  :param upload: upload to datastore (default is True)
1733
1734
  :param labels: a set of key/value labels to tag the artifact with
1734
1735
 
1735
- :returns: artifact object
1736
+ :returns: dataset artifact object
1736
1737
  """
1737
1738
  ds = DatasetArtifact(
1738
1739
  key,
@@ -1745,14 +1746,17 @@ class MlrunProject(ModelObj):
1745
1746
  **kwargs,
1746
1747
  )
1747
1748
 
1748
- item = self.log_artifact(
1749
- ds,
1750
- local_path=local_path,
1751
- artifact_path=artifact_path,
1752
- target_path=target_path,
1753
- tag=tag,
1754
- upload=upload,
1755
- labels=labels,
1749
+ item = cast(
1750
+ DatasetArtifact,
1751
+ self.log_artifact(
1752
+ ds,
1753
+ local_path=local_path,
1754
+ artifact_path=artifact_path,
1755
+ target_path=target_path,
1756
+ tag=tag,
1757
+ upload=upload,
1758
+ labels=labels,
1759
+ ),
1756
1760
  )
1757
1761
  return item
1758
1762
 
@@ -1820,7 +1824,7 @@ class MlrunProject(ModelObj):
1820
1824
  :param extra_data: key/value list of extra files/charts to link with this dataset
1821
1825
  value can be absolute path | relative path (to model dir) | bytes | artifact object
1822
1826
 
1823
- :returns: artifact object
1827
+ :returns: model artifact object
1824
1828
  """
1825
1829
 
1826
1830
  if training_set is not None and inputs:
@@ -1847,79 +1851,72 @@ class MlrunProject(ModelObj):
1847
1851
  if training_set is not None:
1848
1852
  model.infer_from_df(training_set, label_column)
1849
1853
 
1850
- item = self.log_artifact(
1851
- model,
1852
- artifact_path=artifact_path,
1853
- tag=tag,
1854
- upload=upload,
1855
- labels=labels,
1854
+ item = cast(
1855
+ ModelArtifact,
1856
+ self.log_artifact(
1857
+ model,
1858
+ artifact_path=artifact_path,
1859
+ tag=tag,
1860
+ upload=upload,
1861
+ labels=labels,
1862
+ ),
1856
1863
  )
1857
1864
  return item
1858
1865
 
1859
- def get_or_create_vector_store_collection(
1866
+ def get_vector_store_collection(
1860
1867
  self,
1861
1868
  collection_name: str,
1862
- profile: Union[str, VectorStoreProfile],
1863
- **kwargs,
1869
+ vector_store: "VectorStore", # noqa: F821
1864
1870
  ) -> VectorStoreCollection:
1865
- """
1866
- Create or retrieve a VectorStoreCollection.
1867
-
1868
- :param collection_name: Name of the collection
1869
- :param profile: Name of the VectorStoreProfile or a VectorStoreProfile object
1870
- :param kwargs: Additional arguments for the VectorStoreCollection
1871
- :return: VectorStoreCollection object
1872
- """
1873
- if isinstance(profile, str):
1874
- profile = datastore_profile_read(f"ds://{profile}")
1875
-
1876
- if not isinstance(profile, VectorStoreProfile):
1877
- raise ValueError(
1878
- "Profile must be a VectorStoreProfile object or a profile name"
1879
- )
1880
1871
  return VectorStoreCollection(
1881
- profile.vector_store_class,
1882
1872
  self,
1883
- profile.name,
1884
1873
  collection_name,
1885
- **profile.attributes(kwargs),
1874
+ vector_store,
1886
1875
  )
1887
1876
 
1888
1877
  def log_document(
1889
1878
  self,
1890
1879
  key: str,
1891
- artifact_path: Optional[str] = None,
1892
- document_loader: DocumentLoaderSpec = DocumentLoaderSpec(),
1893
1880
  tag: str = "",
1881
+ local_path: str = "",
1882
+ artifact_path: Optional[str] = None,
1883
+ document_loader_spec: Optional[DocumentLoaderSpec] = None,
1894
1884
  upload: Optional[bool] = False,
1895
1885
  labels: Optional[dict[str, str]] = None,
1886
+ target_path: Optional[str] = None,
1896
1887
  **kwargs,
1897
1888
  ) -> DocumentArtifact:
1898
1889
  """
1899
1890
  Log a document as an artifact.
1900
1891
 
1901
1892
  :param key: Artifact key
1902
- :param target_path: Path to the local file
1903
- :param artifact_path: Target path for artifact storage
1904
- :param document_loader: Spec to use to load the artifact as langchain document
1905
1893
  :param tag: Version tag
1894
+ :param local_path: path to the local file we upload, will also be use
1895
+ as the destination subpath (under "artifact_path")
1896
+ :param artifact_path: Target path for artifact storage
1897
+ :param document_loader_spec: Spec to use to load the artifact as langchain document
1906
1898
  :param upload: Whether to upload the artifact
1907
1899
  :param labels: Key-value labels
1900
+ :param target_path: Target file path
1908
1901
  :param kwargs: Additional keyword arguments
1909
1902
  :return: DocumentArtifact object
1910
1903
  """
1911
1904
  doc_artifact = DocumentArtifact(
1912
1905
  key=key,
1913
- document_loader=document_loader,
1906
+ original_source=local_path or target_path,
1907
+ document_loader_spec=document_loader_spec
1908
+ if document_loader_spec
1909
+ else DocumentLoaderSpec(),
1914
1910
  **kwargs,
1915
1911
  )
1916
-
1917
1912
  return self.log_artifact(
1918
- doc_artifact,
1919
- artifact_path=artifact_path,
1913
+ item=doc_artifact,
1920
1914
  tag=tag,
1915
+ local_path=local_path,
1916
+ artifact_path=artifact_path,
1921
1917
  upload=upload,
1922
1918
  labels=labels,
1919
+ target_path=target_path,
1923
1920
  )
1924
1921
 
1925
1922
  def import_artifact(
@@ -2408,7 +2405,7 @@ class MlrunProject(ModelObj):
2408
2405
 
2409
2406
  def set_function(
2410
2407
  self,
2411
- func: typing.Union[str, mlrun.runtimes.BaseRuntime] = None,
2408
+ func: typing.Union[str, mlrun.runtimes.BaseRuntime, None] = None,
2412
2409
  name: str = "",
2413
2410
  kind: str = "job",
2414
2411
  image: Optional[str] = None,
@@ -3407,7 +3404,6 @@ class MlrunProject(ModelObj):
3407
3404
  def set_model_monitoring_credentials(
3408
3405
  self,
3409
3406
  access_key: Optional[str] = None,
3410
- endpoint_store_connection: Optional[str] = None,
3411
3407
  stream_path: Optional[str] = None,
3412
3408
  tsdb_connection: Optional[str] = None,
3413
3409
  replace_creds: bool = False,
@@ -3418,7 +3414,6 @@ class MlrunProject(ModelObj):
3418
3414
  model monitoring or serving function.
3419
3415
 
3420
3416
  :param access_key: Model monitoring access key for managing user permissions.
3421
- :param endpoint_store_connection: Endpoint store connection string. By default, None. Options:
3422
3417
 
3423
3418
  * None - will be set from the system configuration.
3424
3419
  * v3io - for v3io endpoint store, pass `v3io` and the system will generate the
@@ -3451,7 +3446,6 @@ class MlrunProject(ModelObj):
3451
3446
  project=self.name,
3452
3447
  credentials={
3453
3448
  "access_key": access_key,
3454
- "endpoint_store_connection": endpoint_store_connection,
3455
3449
  "stream_path": stream_path,
3456
3450
  "tsdb_connection": tsdb_connection,
3457
3451
  },
@@ -3469,29 +3463,33 @@ class MlrunProject(ModelObj):
3469
3463
 
3470
3464
  def list_model_endpoints(
3471
3465
  self,
3472
- model: Optional[str] = None,
3473
- function: Optional[str] = None,
3466
+ name: Optional[str] = None,
3467
+ model_name: Optional[str] = None,
3468
+ function_name: Optional[str] = None,
3474
3469
  labels: Optional[list[str]] = None,
3475
- start: str = "now-1h",
3476
- end: str = "now",
3470
+ start: Optional[datetime.datetime] = None,
3471
+ end: Optional[datetime.datetime] = None,
3477
3472
  top_level: bool = False,
3478
3473
  uids: Optional[list[str]] = None,
3479
- ) -> list[mlrun.model_monitoring.model_endpoint.ModelEndpoint]:
3474
+ ) -> mlrun.common.schemas.ModelEndpointList:
3480
3475
  """
3481
3476
  Returns a list of `ModelEndpoint` objects. Each `ModelEndpoint` object represents the current state of a
3482
3477
  model endpoint. This functions supports filtering by the following parameters:
3483
- 1) model
3484
- 2) function
3485
- 3) labels
3486
- 4) top level
3487
- 5) uids
3478
+ 1) name
3479
+ 2) model_name
3480
+ 3) function_name
3481
+ 4) labels
3482
+ 5) top level
3483
+ 6) uids
3484
+ 7) start and end time, corresponding to the `created` field.
3488
3485
  By default, when no filters are applied, all available endpoints for the given project will be listed.
3489
3486
 
3490
3487
  In addition, this functions provides a facade for listing endpoint related metrics. This facade is time-based
3491
3488
  and depends on the 'start' and 'end' parameters.
3492
3489
 
3493
- :param model: The name of the model to filter by
3494
- :param function: The name of the function to filter by
3490
+ :param name: The name of the model to filter by
3491
+ :param model_name: The name of the model to filter by
3492
+ :param function_name: The name of the function to filter by
3495
3493
  :param labels: Filter model endpoints by label key-value pairs or key existence. This can be provided as:
3496
3494
  - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
3497
3495
  or `{"label": None}` to check for key existence.
@@ -3499,12 +3497,8 @@ class MlrunProject(ModelObj):
3499
3497
  or just `"label"` for key existence.
3500
3498
  - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
3501
3499
  the specified key-value pairs or key existence.
3502
- :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339 time, a
3503
- Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
3504
- `m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
3505
- :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339 time, a
3506
- Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
3507
- `m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
3500
+ :param start: The start time to filter by.Corresponding to the `created` field.
3501
+ :param end: The end time to filter by. Corresponding to the `created` field.
3508
3502
  :param top_level: if true will return only routers and endpoint that are NOT children of any router
3509
3503
  :param uids: if passed will return a list `ModelEndpoint` object with uid in uids
3510
3504
 
@@ -3513,8 +3507,9 @@ class MlrunProject(ModelObj):
3513
3507
  db = mlrun.db.get_run_db(secrets=self._secrets)
3514
3508
  return db.list_model_endpoints(
3515
3509
  project=self.name,
3516
- model=model,
3517
- function=function,
3510
+ name=name,
3511
+ model_name=model_name,
3512
+ function_name=function_name,
3518
3513
  labels=labels,
3519
3514
  start=start,
3520
3515
  end=end,
@@ -4496,6 +4491,25 @@ class MlrunProject(ModelObj):
4496
4491
  profile, self.name
4497
4492
  )
4498
4493
 
4494
+ def get_config_profile_attributes(self, name: str) -> dict:
4495
+ """
4496
+ Get the merged attributes from a named configuration profile.
4497
+
4498
+ Retrieves a profile from the datastore using the provided name and returns its
4499
+ merged public and private attributes as a dictionary.
4500
+
4501
+ Args:
4502
+ name (str): Name of the configuration profile to retrieve. Will be prefixed
4503
+ with "ds://" to form the full profile path.
4504
+
4505
+ Returns:
4506
+ dict: The merged attributes dictionary containing both public and private
4507
+ configuration settings from the profile. Returns nested dictionaries if
4508
+ the profile contains nested configurations.
4509
+ """
4510
+ profile = datastore_profile_read(f"ds://{name}", self.name)
4511
+ return profile.attributes()
4512
+
4499
4513
  def delete_datastore_profile(self, profile: str):
4500
4514
  mlrun.db.get_run_db(secrets=self._secrets).delete_datastore_profile(
4501
4515
  profile, self.name
@@ -4840,7 +4854,6 @@ class MlrunProject(ModelObj):
4840
4854
  page=page,
4841
4855
  page_size=page_size,
4842
4856
  page_token=page_token,
4843
- return_all=False,
4844
4857
  **kwargs,
4845
4858
  )
4846
4859
 
@@ -1192,9 +1192,6 @@ class RemoteRuntime(KubeResource):
1192
1192
  return results
1193
1193
 
1194
1194
  def _resolve_invocation_url(self, path, force_external_address):
1195
- if not path.startswith("/") and path != "":
1196
- path = f"/{path}"
1197
-
1198
1195
  # internal / external invocation urls is a nuclio >= 1.6.x feature
1199
1196
  # try to infer the invocation url from the internal and if not exists, use external.
1200
1197
  # $$$$ we do not want to use the external invocation url (e.g.: ingress, nodePort, etc.)
@@ -1203,12 +1200,16 @@ class RemoteRuntime(KubeResource):
1203
1200
  and self.status.internal_invocation_urls
1204
1201
  and mlrun.k8s_utils.is_running_inside_kubernetes_cluster()
1205
1202
  ):
1206
- return f"http://{self.status.internal_invocation_urls[0]}{path}"
1203
+ return mlrun.utils.helpers.join_urls(
1204
+ f"http://{self.status.internal_invocation_urls[0]}", path
1205
+ )
1207
1206
 
1208
1207
  if self.status.external_invocation_urls:
1209
- return f"http://{self.status.external_invocation_urls[0]}{path}"
1208
+ return mlrun.utils.helpers.join_urls(
1209
+ f"http://{self.status.external_invocation_urls[0]}", path
1210
+ )
1210
1211
  else:
1211
- return f"http://{self.status.address}{path}"
1212
+ return mlrun.utils.helpers.join_urls(f"http://{self.status.address}", path)
1212
1213
 
1213
1214
  def _update_credentials_from_remote_build(self, remote_data):
1214
1215
  self.metadata.credentials = remote_data.get("metadata", {}).get(
@@ -644,9 +644,12 @@ class ServingRuntime(RemoteRuntime):
644
644
 
645
645
  def _get_serving_spec(self):
646
646
  function_name_uri_map = {f.name: f.uri(self) for f in self.spec.function_refs}
647
-
648
647
  serving_spec = {
648
+ "function_name": self.metadata.name,
649
+ "function_tag": self.metadata.tag,
649
650
  "function_uri": self._function_uri(),
651
+ "function_hash": self.metadata.hash,
652
+ "project": self.metadata.project,
650
653
  "version": "v2",
651
654
  "parameters": self.spec.parameters,
652
655
  "graph": self.spec.graph.to_dict() if self.spec.graph else {},
@@ -707,6 +710,9 @@ class ServingRuntime(RemoteRuntime):
707
710
  function_uri=self._function_uri(),
708
711
  secret_sources=self.spec.secret_sources,
709
712
  default_content_type=self.spec.default_content_type,
713
+ function_name=self.metadata.name,
714
+ function_tag=self.metadata.tag,
715
+ project=self.metadata.project,
710
716
  **kwargs,
711
717
  )
712
718
  server.init_states(