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.

Files changed (75) hide show
  1. mlrun/__init__.py +5 -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/constants.py +1 -0
  7. mlrun/common/model_monitoring/__init__.py +0 -2
  8. mlrun/common/model_monitoring/helpers.py +0 -28
  9. mlrun/common/schemas/__init__.py +2 -4
  10. mlrun/common/schemas/alert.py +80 -1
  11. mlrun/common/schemas/artifact.py +4 -0
  12. mlrun/common/schemas/client_spec.py +0 -1
  13. mlrun/common/schemas/model_monitoring/__init__.py +0 -6
  14. mlrun/common/schemas/model_monitoring/constants.py +11 -9
  15. mlrun/common/schemas/model_monitoring/model_endpoints.py +77 -149
  16. mlrun/common/schemas/notification.py +6 -0
  17. mlrun/common/schemas/project.py +3 -0
  18. mlrun/config.py +2 -3
  19. mlrun/datastore/datastore_profile.py +57 -17
  20. mlrun/datastore/sources.py +1 -2
  21. mlrun/datastore/vectorstore.py +67 -59
  22. mlrun/db/base.py +29 -19
  23. mlrun/db/factory.py +0 -3
  24. mlrun/db/httpdb.py +224 -161
  25. mlrun/db/nopdb.py +36 -17
  26. mlrun/execution.py +46 -32
  27. mlrun/feature_store/api.py +1 -0
  28. mlrun/model.py +7 -0
  29. mlrun/model_monitoring/__init__.py +3 -2
  30. mlrun/model_monitoring/api.py +55 -53
  31. mlrun/model_monitoring/applications/_application_steps.py +4 -2
  32. mlrun/model_monitoring/applications/base.py +165 -6
  33. mlrun/model_monitoring/applications/context.py +88 -37
  34. mlrun/model_monitoring/applications/evidently_base.py +0 -1
  35. mlrun/model_monitoring/applications/histogram_data_drift.py +3 -7
  36. mlrun/model_monitoring/controller.py +43 -37
  37. mlrun/model_monitoring/db/__init__.py +0 -2
  38. mlrun/model_monitoring/db/tsdb/base.py +2 -1
  39. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +2 -1
  40. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +43 -0
  41. mlrun/model_monitoring/helpers.py +79 -66
  42. mlrun/model_monitoring/stream_processing.py +83 -270
  43. mlrun/model_monitoring/writer.py +1 -10
  44. mlrun/projects/pipelines.py +37 -1
  45. mlrun/projects/project.py +171 -74
  46. mlrun/run.py +40 -0
  47. mlrun/runtimes/nuclio/function.py +7 -6
  48. mlrun/runtimes/nuclio/serving.py +9 -2
  49. mlrun/serving/routers.py +158 -145
  50. mlrun/serving/server.py +6 -0
  51. mlrun/serving/states.py +21 -7
  52. mlrun/serving/v2_serving.py +70 -61
  53. mlrun/utils/helpers.py +14 -30
  54. mlrun/utils/notifications/notification/mail.py +36 -9
  55. mlrun/utils/notifications/notification_pusher.py +43 -18
  56. mlrun/utils/version/version.json +2 -2
  57. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/METADATA +5 -4
  58. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/RECORD +62 -75
  59. mlrun/common/schemas/model_monitoring/model_endpoint_v2.py +0 -149
  60. mlrun/model_monitoring/db/stores/__init__.py +0 -136
  61. mlrun/model_monitoring/db/stores/base/__init__.py +0 -15
  62. mlrun/model_monitoring/db/stores/base/store.py +0 -154
  63. mlrun/model_monitoring/db/stores/sqldb/__init__.py +0 -13
  64. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +0 -46
  65. mlrun/model_monitoring/db/stores/sqldb/models/base.py +0 -93
  66. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +0 -47
  67. mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +0 -25
  68. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +0 -408
  69. mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +0 -13
  70. mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +0 -464
  71. mlrun/model_monitoring/model_endpoint.py +0 -120
  72. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/LICENSE +0 -0
  73. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/WHEEL +0 -0
  74. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/entry_points.txt +0 -0
  75. {mlrun-1.8.0rc4.dist-info → mlrun-1.8.0rc7.dist-info}/top_level.txt +0 -0
mlrun/db/httpdb.py CHANGED
@@ -28,7 +28,7 @@ from urllib.parse import urlparse
28
28
  import pydantic.v1
29
29
  import requests
30
30
  import semver
31
- from pydantic import parse_obj_as
31
+ from pydantic.v1 import parse_obj_as
32
32
 
33
33
  import mlrun
34
34
  import mlrun.common.constants
@@ -37,7 +37,6 @@ import mlrun.common.runtimes
37
37
  import mlrun.common.schemas
38
38
  import mlrun.common.schemas.model_monitoring.model_endpoints as mm_endpoints
39
39
  import mlrun.common.types
40
- import mlrun.model_monitoring.model_endpoint
41
40
  import mlrun.platforms
42
41
  import mlrun.projects
43
42
  import mlrun.runtimes.nuclio.api_gateway
@@ -49,6 +48,7 @@ from mlrun.errors import MLRunInvalidArgumentError, err_to_str
49
48
  from mlrun_pipelines.utils import compile_pipeline
50
49
 
51
50
  from ..artifacts import Artifact
51
+ from ..common.schemas import AlertActivations
52
52
  from ..config import config
53
53
  from ..datastore.datastore_profile import DatastoreProfile2Json
54
54
  from ..feature_store import FeatureSet, FeatureVector
@@ -558,10 +558,6 @@ class HTTPRunDB(RunDBInterface):
558
558
  server_cfg.get("external_platform_tracking")
559
559
  or config.external_platform_tracking
560
560
  )
561
- config.model_endpoint_monitoring.endpoint_store_connection = (
562
- server_cfg.get("model_endpoint_monitoring_endpoint_store_connection")
563
- or config.model_endpoint_monitoring.endpoint_store_connection
564
- )
565
561
  config.model_endpoint_monitoring.tsdb_connection = (
566
562
  server_cfg.get("model_monitoring_tsdb_connection")
567
563
  or config.model_endpoint_monitoring.tsdb_connection
@@ -1701,6 +1697,8 @@ class HTTPRunDB(RunDBInterface):
1701
1697
  name: Optional[str] = None,
1702
1698
  kind: mlrun.common.schemas.ScheduleKinds = None,
1703
1699
  include_last_run: bool = False,
1700
+ next_run_time_since: Optional[datetime] = None,
1701
+ next_run_time_until: Optional[datetime] = None,
1704
1702
  ) -> mlrun.common.schemas.SchedulesOutput:
1705
1703
  """Retrieve list of schedules of specific name or kind.
1706
1704
 
@@ -1709,10 +1707,18 @@ class HTTPRunDB(RunDBInterface):
1709
1707
  :param kind: Kind of schedule objects to retrieve, can be either ``job`` or ``pipeline``.
1710
1708
  :param include_last_run: Whether to return for each schedule returned also the results of the last run of
1711
1709
  that schedule.
1710
+ :param next_run_time_since: Return only schedules with next run time after this date.
1711
+ :param next_run_time_until: Return only schedules with next run time before this date.
1712
1712
  """
1713
1713
 
1714
1714
  project = project or config.default_project
1715
- params = {"kind": kind, "name": name, "include_last_run": include_last_run}
1715
+ params = {
1716
+ "kind": kind,
1717
+ "name": name,
1718
+ "include_last_run": include_last_run,
1719
+ "next_run_time_since": datetime_to_iso(next_run_time_since),
1720
+ "next_run_time_until": datetime_to_iso(next_run_time_until),
1721
+ }
1716
1722
  path = f"projects/{project}/schedules"
1717
1723
  error_message = f"Failed listing schedules for {project} ? {kind} {name}"
1718
1724
  resp = self.api_call("GET", path, error_message, params=params)
@@ -2260,6 +2266,75 @@ class HTTPRunDB(RunDBInterface):
2260
2266
 
2261
2267
  return resp.json()
2262
2268
 
2269
+ def retry_pipeline(
2270
+ self,
2271
+ run_id: str,
2272
+ namespace: Optional[str] = None,
2273
+ timeout: int = 30,
2274
+ project: Optional[str] = None,
2275
+ ):
2276
+ """
2277
+ Retry a specific pipeline run using its run ID. This function sends an API request
2278
+ to retry a pipeline run. If a project is specified, the run must belong to that
2279
+ project; otherwise, all projects are queried.
2280
+
2281
+ :param run_id: The unique ID of the pipeline run to retry.
2282
+ :param namespace: Kubernetes namespace where the pipeline is running. Optional.
2283
+ :param timeout: Timeout (in seconds) for the API call. Defaults to 30 seconds.
2284
+ :param project: Name of the MLRun project associated with the pipeline. Can be
2285
+ ``*`` to query across all projects. Optional.
2286
+
2287
+ :raises ValueError: Raised if the API response is not successful or contains an
2288
+ error.
2289
+
2290
+ :return: JSON response containing details of the retried pipeline run.
2291
+ """
2292
+
2293
+ params = {}
2294
+ if namespace:
2295
+ params["namespace"] = namespace
2296
+ project_path = project if project else "*"
2297
+
2298
+ resp_text = ""
2299
+ resp_code = None
2300
+ try:
2301
+ resp = self.api_call(
2302
+ "POST",
2303
+ f"projects/{project_path}/pipelines/{run_id}/retry",
2304
+ params=params,
2305
+ timeout=timeout,
2306
+ )
2307
+ resp_code = resp.status_code
2308
+ resp_text = resp.text
2309
+ if not resp.ok:
2310
+ raise mlrun.errors.MLRunHTTPError(
2311
+ f"Failed to retry pipeline run '{run_id}'. "
2312
+ f"HTTP {resp_code}: {resp_text}"
2313
+ )
2314
+ except Exception as exc:
2315
+ logger.error(
2316
+ "Retry pipeline API call encountered an error.",
2317
+ run_id=run_id,
2318
+ project=project_path,
2319
+ namespace=namespace,
2320
+ response_code=resp_code,
2321
+ response_text=resp_text,
2322
+ error=str(exc),
2323
+ )
2324
+ if isinstance(exc, mlrun.errors.MLRunHTTPError):
2325
+ raise exc # Re-raise known HTTP errors
2326
+ raise mlrun.errors.MLRunRuntimeError(
2327
+ f"Unexpected error while retrying pipeline run '{run_id}'."
2328
+ ) from exc
2329
+
2330
+ logger.info(
2331
+ "Successfully retried pipeline run",
2332
+ run_id=run_id,
2333
+ project=project_path,
2334
+ namespace=namespace,
2335
+ )
2336
+ return resp.json()
2337
+
2263
2338
  @staticmethod
2264
2339
  def _resolve_reference(tag, uid):
2265
2340
  if uid and tag:
@@ -3048,7 +3123,7 @@ class HTTPRunDB(RunDBInterface):
3048
3123
  for project_dict in response.json()["projects"]
3049
3124
  ]
3050
3125
 
3051
- def get_project(self, name: str) -> mlrun.projects.MlrunProject:
3126
+ def get_project(self, name: str) -> "mlrun.MlrunProject":
3052
3127
  """Get details for a specific project."""
3053
3128
 
3054
3129
  if not name:
@@ -3057,7 +3132,7 @@ class HTTPRunDB(RunDBInterface):
3057
3132
  path = f"projects/{name}"
3058
3133
  error_message = f"Failed retrieving project {name}"
3059
3134
  response = self.api_call("GET", path, error_message)
3060
- return mlrun.projects.MlrunProject.from_dict(response.json())
3135
+ return mlrun.MlrunProject.from_dict(response.json())
3061
3136
 
3062
3137
  def delete_project(
3063
3138
  self,
@@ -3504,217 +3579,180 @@ class HTTPRunDB(RunDBInterface):
3504
3579
 
3505
3580
  def create_model_endpoint(
3506
3581
  self,
3507
- project: str,
3508
- endpoint_id: str,
3509
- model_endpoint: Union[
3510
- mlrun.model_monitoring.model_endpoint.ModelEndpoint, dict
3511
- ],
3512
- ):
3582
+ model_endpoint: mlrun.common.schemas.ModelEndpoint,
3583
+ ) -> mlrun.common.schemas.ModelEndpoint:
3513
3584
  """
3514
3585
  Creates a DB record with the given model_endpoint record.
3515
3586
 
3516
- :param project: The name of the project.
3517
- :param endpoint_id: The id of the endpoint.
3518
3587
  :param model_endpoint: An object representing the model endpoint.
3519
- """
3520
3588
 
3521
- if isinstance(
3522
- model_endpoint, mlrun.model_monitoring.model_endpoint.ModelEndpoint
3523
- ):
3524
- model_endpoint = model_endpoint.to_dict()
3589
+ :return: The created model endpoint object.
3590
+ """
3525
3591
 
3526
- path = f"projects/{project}/model-endpoints/{endpoint_id}"
3527
- self.api_call(
3528
- method="POST",
3592
+ path = f"projects/{model_endpoint.metadata.project}/model-endpoints"
3593
+ response = self.api_call(
3594
+ method=mlrun.common.types.HTTPMethod.POST,
3529
3595
  path=path,
3530
- body=dict_to_json(model_endpoint),
3596
+ body=model_endpoint.json(),
3531
3597
  )
3598
+ return mlrun.common.schemas.ModelEndpoint(**response.json())
3532
3599
 
3533
3600
  def delete_model_endpoint(
3534
3601
  self,
3602
+ name: str,
3535
3603
  project: str,
3604
+ function_name: str,
3536
3605
  endpoint_id: str,
3537
3606
  ):
3538
3607
  """
3539
3608
  Deletes the DB record of a given model endpoint, project and endpoint_id are used for lookup
3540
3609
 
3610
+ :param name: The name of the model endpoint
3541
3611
  :param project: The name of the project
3612
+ :param function_name: The name of the function
3542
3613
  :param endpoint_id: The id of the endpoint
3543
3614
  """
3544
3615
 
3545
- path = f"projects/{project}/model-endpoints/{endpoint_id}"
3616
+ path = f"projects/{project}/model-endpoints/{name}"
3546
3617
  self.api_call(
3547
- method="DELETE",
3618
+ method=mlrun.common.types.HTTPMethod.DELETE,
3548
3619
  path=path,
3620
+ params={
3621
+ "function_name": function_name,
3622
+ "endpoint_id": endpoint_id,
3623
+ },
3549
3624
  )
3550
3625
 
3551
3626
  def list_model_endpoints(
3552
3627
  self,
3553
3628
  project: str,
3554
- model: Optional[str] = None,
3555
- function: Optional[str] = None,
3629
+ name: Optional[str] = None,
3630
+ function_name: Optional[str] = None,
3631
+ model_name: Optional[str] = None,
3556
3632
  labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
3557
- start: str = "now-1h",
3558
- end: str = "now",
3559
- metrics: Optional[list[str]] = None,
3633
+ start: Optional[datetime] = None,
3634
+ end: Optional[datetime] = None,
3635
+ tsdb_metrics: bool = True,
3560
3636
  top_level: bool = False,
3561
3637
  uids: Optional[list[str]] = None,
3562
- ) -> list[mlrun.model_monitoring.model_endpoint.ModelEndpoint]:
3638
+ latest_only: bool = False,
3639
+ ) -> mlrun.common.schemas.ModelEndpointList:
3640
+ """
3641
+ List model endpoints with optional filtering by name, function name, model name, labels, and time range.
3642
+
3643
+ :param project: The name of the project
3644
+ :param name: The name of the model endpoint
3645
+ :param function_name: The name of the function
3646
+ :param model_name: The name of the model
3647
+ :param labels: A list of labels to filter by. (see mlrun.common.schemas.LabelsModel)
3648
+ :param start: The start time to filter by.Corresponding to the `created` field.
3649
+ :param end: The end time to filter by. Corresponding to the `created` field.
3650
+ :param tsdb_metrics: Whether to include metrics from the time series DB.
3651
+ :param top_level: Whether to return only top level model endpoints.
3652
+ :param uids: A list of unique ids to filter by.
3653
+ :param latest_only: Whether to return only the latest model endpoint version.
3654
+ :return: A list of model endpoints.
3563
3655
  """
3564
- Returns a list of `ModelEndpoint` objects. Each `ModelEndpoint` object represents the current state of a
3565
- model endpoint. This functions supports filtering by the following parameters:
3566
- 1) model
3567
- 2) function
3568
- 3) labels
3569
- 4) top level
3570
- 5) uids
3571
- By default, when no filters are applied, all available endpoints for the given project will be listed.
3572
-
3573
- In addition, this functions provides a facade for listing endpoint related metrics. This facade is time-based
3574
- and depends on the 'start' and 'end' parameters. By default, when the metrics parameter is None, no metrics are
3575
- added to the output of this function.
3576
-
3577
- :param project: The name of the project
3578
- :param model: The name of the model to filter by
3579
- :param function: The name of the function to filter by
3580
- :param labels: Filter model endpoints by label key-value pairs or key existence. This can be provided as:
3581
- - A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
3582
- or `{"label": None}` to check for key existence.
3583
- - A list of strings formatted as `"label=value"` to match specific label key-value pairs,
3584
- or just `"label"` for key existence.
3585
- - A comma-separated string formatted as `"label1=value1,label2"` to match entities with
3586
- the specified key-value pairs or key existence.
3587
- :param metrics: A list of metrics to return for each endpoint, read more in 'TimeMetric'
3588
- :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339 time, a
3589
- Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
3590
- `m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
3591
- :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339 time, a
3592
- Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
3593
- `m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
3594
- :param top_level: if true will return only routers and endpoint that are NOT children of any router
3595
- :param uids: if passed will return a list `ModelEndpoint` object with uid in uids
3596
-
3597
- :returns: Returns a list of `ModelEndpoint` objects.
3598
- """
3599
-
3600
3656
  path = f"projects/{project}/model-endpoints"
3601
3657
  labels = self._parse_labels(labels)
3602
3658
 
3603
3659
  response = self.api_call(
3604
- method="GET",
3660
+ method=mlrun.common.types.HTTPMethod.GET,
3605
3661
  path=path,
3606
3662
  params={
3607
- "model": model,
3608
- "function": function,
3663
+ "name": name,
3664
+ "model_name": model_name,
3665
+ "function_name": function_name,
3609
3666
  "label": labels,
3610
- "start": start,
3611
- "end": end,
3612
- "metric": metrics or [],
3667
+ "start": datetime_to_iso(start),
3668
+ "end": datetime_to_iso(end),
3669
+ "tsdb_metrics": tsdb_metrics,
3613
3670
  "top-level": top_level,
3614
3671
  "uid": uids,
3672
+ "latest_only": latest_only,
3615
3673
  },
3616
3674
  )
3617
3675
 
3618
- # Generate a list of a model endpoint dictionaries
3619
- model_endpoints = response.json()["endpoints"]
3620
- if model_endpoints:
3621
- return [
3622
- mlrun.model_monitoring.model_endpoint.ModelEndpoint.from_dict(obj)
3623
- for obj in model_endpoints
3624
- ]
3625
- return []
3676
+ return mlrun.common.schemas.ModelEndpointList(**response.json())
3626
3677
 
3627
3678
  def get_model_endpoint(
3628
3679
  self,
3680
+ name: str,
3629
3681
  project: str,
3630
- endpoint_id: str,
3631
- start: Optional[str] = None,
3632
- end: Optional[str] = None,
3633
- metrics: Optional[list[str]] = None,
3682
+ function_name: Optional[str] = None,
3683
+ # TODO: function_tag
3684
+ endpoint_id: Optional[str] = None,
3685
+ tsdb_metrics: bool = True,
3634
3686
  feature_analysis: bool = False,
3635
- ) -> mlrun.model_monitoring.model_endpoint.ModelEndpoint:
3687
+ ) -> mlrun.common.schemas.ModelEndpoint:
3636
3688
  """
3637
3689
  Returns a single `ModelEndpoint` object with additional metrics and feature related data.
3638
3690
 
3691
+ :param name: The name of the model endpoint
3639
3692
  :param project: The name of the project
3640
- :param endpoint_id: The unique id of the model endpoint.
3641
- :param start: The start time of the metrics. Can be represented by a string containing an
3642
- RFC 3339 time, a Unix timestamp in milliseconds, a relative time
3643
- (`'now'` or `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
3644
- `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
3645
- :param end: The end time of the metrics. Can be represented by a string containing an
3646
- RFC 3339 time, a Unix timestamp in milliseconds, a relative time
3647
- (`'now'` or `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
3648
- `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
3649
- :param metrics: A list of metrics to return for the model endpoint. There are pre-defined
3650
- metrics for model endpoints such as predictions_per_second and
3651
- latency_avg_5m but also custom metrics defined by the user. Please note that
3652
- these metrics are stored in the time series DB and the results will be
3653
- appeared under model_endpoint.spec.metrics.
3654
- :param feature_analysis: When True, the base feature statistics and current feature statistics will
3655
- be added to the output of the resulting object.
3656
-
3657
- :returns: A `ModelEndpoint` object.
3658
- """
3659
-
3660
- path = f"projects/{project}/model-endpoints/{endpoint_id}"
3693
+ :param function_name: The name of the function
3694
+ :param endpoint_id: The id of the endpoint
3695
+ :param tsdb_metrics: Whether to include metrics from the time series DB.
3696
+ :param feature_analysis: Whether to include feature analysis data (feature_stats,
3697
+ current_stats & drift_measures).
3698
+
3699
+ :return: A `ModelEndpoint` object.
3700
+ """
3701
+
3702
+ path = f"projects/{project}/model-endpoints/{name}"
3661
3703
  response = self.api_call(
3662
- method="GET",
3704
+ method=mlrun.common.types.HTTPMethod.GET,
3663
3705
  path=path,
3664
3706
  params={
3665
- "start": start,
3666
- "end": end,
3667
- "metric": metrics or [],
3707
+ "function_name": function_name,
3708
+ "endpoint_id": endpoint_id,
3709
+ "tsdb_metrics": tsdb_metrics,
3668
3710
  "feature_analysis": feature_analysis,
3669
3711
  },
3670
3712
  )
3671
3713
 
3672
- return mlrun.model_monitoring.model_endpoint.ModelEndpoint.from_dict(
3673
- response.json()
3674
- )
3714
+ return mlrun.common.schemas.ModelEndpoint(**response.json())
3675
3715
 
3676
3716
  def patch_model_endpoint(
3677
3717
  self,
3718
+ name: str,
3678
3719
  project: str,
3679
- endpoint_id: str,
3680
3720
  attributes: dict,
3681
- ):
3682
- """
3683
- Updates model endpoint with provided attributes.
3684
-
3685
- :param project: The name of the project.
3686
- :param endpoint_id: The id of the endpoint.
3687
- :param attributes: Dictionary of attributes that will be used for update the model endpoint. The keys
3688
- of this dictionary should exist in the target table. Note that the values should be from type string or from
3689
- a valid numerical type such as int or float. More details about the model endpoint available attributes can
3690
- be found under :py:class:`~mlrun.common.schemas.ModelEndpoint`.
3691
-
3692
- Example::
3693
-
3694
- # Generate current stats for two features
3695
- current_stats = {'tvd_sum': 2.2,
3696
- 'tvd_mean': 0.5,
3697
- 'hellinger_sum': 3.6,
3698
- 'hellinger_mean': 0.9,
3699
- 'kld_sum': 24.2,
3700
- 'kld_mean': 6.0,
3701
- 'f1': {'tvd': 0.5, 'hellinger': 1.0, 'kld': 6.4},
3702
- 'f2': {'tvd': 0.5, 'hellinger': 1.0, 'kld': 6.5}}
3703
-
3704
- # Create attributes dictionary according to the required format
3705
- attributes = {`current_stats`: json.dumps(current_stats),
3706
- `drift_status`: "DRIFT_DETECTED"}
3707
-
3721
+ function_name: Optional[str] = None,
3722
+ endpoint_id: Optional[str] = None,
3723
+ ) -> mlrun.common.schemas.ModelEndpoint:
3708
3724
  """
3725
+ Updates a model endpoint with the given attributes.
3709
3726
 
3710
- attributes = {"attributes": _as_json(attributes)}
3711
- path = f"projects/{project}/model-endpoints/{endpoint_id}"
3712
- self.api_call(
3713
- method="PATCH",
3727
+ :param name: The name of the model endpoint
3728
+ :param project: The name of the project
3729
+ :param attributes: The attributes to update
3730
+ :param function_name: The name of the function
3731
+ :param endpoint_id: The id of the endpoint
3732
+ :return: The updated `ModelEndpoint` object.
3733
+ """
3734
+ attributes_keys = list(attributes.keys())
3735
+ attributes["name"] = name
3736
+ attributes["project"] = project
3737
+ attributes["uid"] = endpoint_id or ""
3738
+ model_endpoint = mlrun.common.schemas.ModelEndpoint.from_flat_dict(attributes)
3739
+ path = f"projects/{project}/model-endpoints"
3740
+ logger.info(
3741
+ "Patching model endpoint",
3742
+ attributes_keys=attributes_keys,
3743
+ model_endpoint=model_endpoint,
3744
+ )
3745
+ response = self.api_call(
3746
+ method=mlrun.common.types.HTTPMethod.PATCH,
3714
3747
  path=path,
3715
- params=attributes,
3748
+ params={
3749
+ "attribute-key": attributes_keys,
3750
+ },
3751
+ body=model_endpoint.json(),
3716
3752
  )
3717
3753
 
3754
+ return mlrun.common.schemas.ModelEndpoint(**response.json())
3755
+
3718
3756
  def update_model_monitoring_controller(
3719
3757
  self,
3720
3758
  project: str,
@@ -4707,7 +4745,7 @@ class HTTPRunDB(RunDBInterface):
4707
4745
  Union[mlrun.common.schemas.alert.EventEntityKind, str]
4708
4746
  ] = None,
4709
4747
  event_kind: Optional[Union[mlrun.common.schemas.alert.EventKind, str]] = None,
4710
- ) -> list[mlrun.common.schemas.AlertActivation]:
4748
+ ) -> mlrun.common.schemas.AlertActivations:
4711
4749
  """
4712
4750
  Retrieve a list of all alert activations.
4713
4751
 
@@ -4743,7 +4781,7 @@ class HTTPRunDB(RunDBInterface):
4743
4781
  page_size: Optional[int] = None,
4744
4782
  page_token: Optional[str] = None,
4745
4783
  **kwargs,
4746
- ) -> tuple[list, Optional[str]]:
4784
+ ) -> tuple[AlertActivations, Optional[str]]:
4747
4785
  """List alerts activations with support for pagination and various filtering options.
4748
4786
 
4749
4787
  This method retrieves a paginated list of alert activations based on the specified filter parameters.
@@ -4799,6 +4837,22 @@ class HTTPRunDB(RunDBInterface):
4799
4837
  **kwargs,
4800
4838
  )
4801
4839
 
4840
+ def get_project_summary(
4841
+ self, project: Optional[str] = None
4842
+ ) -> mlrun.common.schemas.ProjectSummary:
4843
+ """
4844
+ Retrieve the summary of a project.
4845
+
4846
+ :param project: Project name for which the summary belongs.
4847
+ :returns: A summary of the project.
4848
+ """
4849
+ project = project or config.default_project
4850
+
4851
+ endpoint_path = f"project-summaries/{project}"
4852
+ error_message = f"Failed retrieving project summary for {project}"
4853
+ response = self.api_call("GET", endpoint_path, error_message)
4854
+ return mlrun.common.schemas.ProjectSummary(**response.json())
4855
+
4802
4856
  @staticmethod
4803
4857
  def _parse_labels(
4804
4858
  labels: Optional[Union[str, dict[str, Optional[str]], list[str]]],
@@ -5031,9 +5085,11 @@ class HTTPRunDB(RunDBInterface):
5031
5085
  "name": name,
5032
5086
  "uid": uid,
5033
5087
  "label": labels,
5034
- "state": mlrun.utils.helpers.as_list(state)
5035
- if state is not None
5036
- else states or None,
5088
+ "state": (
5089
+ mlrun.utils.helpers.as_list(state)
5090
+ if state is not None
5091
+ else states or None
5092
+ ),
5037
5093
  "sort": bool2str(sort),
5038
5094
  "iter": bool2str(iter),
5039
5095
  "start_time_from": datetime_to_iso(start_time_from),
@@ -5074,7 +5130,11 @@ class HTTPRunDB(RunDBInterface):
5074
5130
  until: Optional[datetime] = None,
5075
5131
  entity: Optional[str] = None,
5076
5132
  severity: Optional[
5077
- list[Union[mlrun.common.schemas.alert.AlertSeverity, str]]
5133
+ Union[
5134
+ mlrun.common.schemas.alert.AlertSeverity,
5135
+ str,
5136
+ list[Union[mlrun.common.schemas.alert.AlertSeverity, str]],
5137
+ ]
5078
5138
  ] = None,
5079
5139
  entity_kind: Optional[
5080
5140
  Union[mlrun.common.schemas.alert.EventEntityKind, str]
@@ -5084,14 +5144,14 @@ class HTTPRunDB(RunDBInterface):
5084
5144
  page_size: Optional[int] = None,
5085
5145
  page_token: Optional[str] = None,
5086
5146
  return_all: bool = False,
5087
- ) -> tuple[list[mlrun.common.schemas.AlertActivation], Optional[str]]:
5147
+ ) -> tuple[mlrun.common.schemas.AlertActivations, Optional[str]]:
5088
5148
  project = project or config.default_project
5089
5149
  params = {
5090
5150
  "name": name,
5091
5151
  "since": datetime_to_iso(since),
5092
5152
  "until": datetime_to_iso(until),
5093
5153
  "entity": entity,
5094
- "severity": severity,
5154
+ "severity": mlrun.utils.helpers.as_list(severity) if severity else None,
5095
5155
  "entity-kind": entity_kind,
5096
5156
  "event-kind": event_kind,
5097
5157
  "page": page,
@@ -5108,9 +5168,12 @@ class HTTPRunDB(RunDBInterface):
5108
5168
  paginated_responses, token = self.process_paginated_responses(
5109
5169
  responses, "activations"
5110
5170
  )
5111
- paginated_results = [
5112
- mlrun.common.schemas.AlertActivation(**item) for item in paginated_responses
5113
- ]
5171
+ paginated_results = mlrun.common.schemas.AlertActivations(
5172
+ activations=[
5173
+ mlrun.common.schemas.AlertActivation(**item)
5174
+ for item in paginated_responses
5175
+ ]
5176
+ )
5114
5177
 
5115
5178
  return paginated_results, token
5116
5179
 
mlrun/db/nopdb.py CHANGED
@@ -22,6 +22,7 @@ import mlrun.common.runtimes.constants
22
22
  import mlrun.common.schemas
23
23
  import mlrun.errors
24
24
  import mlrun.lists
25
+ import mlrun.model_monitoring
25
26
 
26
27
  from ..config import config
27
28
  from ..utils import logger
@@ -573,39 +574,54 @@ class NopDB(RunDBInterface):
573
574
 
574
575
  def create_model_endpoint(
575
576
  self,
576
- project: str,
577
- endpoint_id: str,
578
577
  model_endpoint: mlrun.common.schemas.ModelEndpoint,
579
- ):
578
+ ) -> mlrun.common.schemas.ModelEndpoint:
580
579
  pass
581
580
 
582
- def delete_model_endpoint(self, project: str, endpoint_id: str):
581
+ def delete_model_endpoint(
582
+ self,
583
+ name: str,
584
+ project: str,
585
+ function_name: str,
586
+ endpoint_id: str,
587
+ ):
583
588
  pass
584
589
 
585
590
  def list_model_endpoints(
586
591
  self,
587
592
  project: str,
588
- model: Optional[str] = None,
589
- function: Optional[str] = None,
593
+ name: Optional[str] = None,
594
+ function_name: Optional[str] = None,
595
+ model_name: Optional[str] = None,
590
596
  labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
591
- start: str = "now-1h",
592
- end: str = "now",
593
- metrics: Optional[list[str]] = None,
594
- ):
597
+ start: Optional[datetime.datetime] = None,
598
+ end: Optional[datetime.datetime] = None,
599
+ tsdb_metrics: bool = True,
600
+ top_level: bool = False,
601
+ uids: Optional[list[str]] = None,
602
+ latest_only: bool = False,
603
+ ) -> mlrun.common.schemas.ModelEndpointList:
595
604
  pass
596
605
 
597
606
  def get_model_endpoint(
598
607
  self,
608
+ name: str,
599
609
  project: str,
600
- endpoint_id: str,
601
- start: Optional[str] = None,
602
- end: Optional[str] = None,
603
- metrics: Optional[list[str]] = None,
604
- features: bool = False,
605
- ):
610
+ function_name: Optional[str] = None,
611
+ endpoint_id: Optional[str] = None,
612
+ tsdb_metrics: bool = True,
613
+ feature_analysis: bool = False,
614
+ ) -> mlrun.common.schemas.ModelEndpoint:
606
615
  pass
607
616
 
608
- def patch_model_endpoint(self, project: str, endpoint_id: str, attributes: dict):
617
+ def patch_model_endpoint(
618
+ self,
619
+ name: str,
620
+ project: str,
621
+ attributes: dict,
622
+ function_name: Optional[str] = None,
623
+ endpoint_id: Optional[str] = None,
624
+ ) -> mlrun.common.schemas.ModelEndpoint:
609
625
  pass
610
626
 
611
627
  def create_hub_source(
@@ -902,3 +918,6 @@ class NopDB(RunDBInterface):
902
918
  **kwargs,
903
919
  ):
904
920
  pass
921
+
922
+ def get_project_summary(self, project: str):
923
+ pass