mlrun 1.5.0rc11__py3-none-any.whl → 1.5.0rc13__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 (49) hide show
  1. mlrun/__main__.py +31 -2
  2. mlrun/api/api/endpoints/functions.py +110 -52
  3. mlrun/api/api/endpoints/model_endpoints.py +0 -56
  4. mlrun/api/crud/model_monitoring/deployment.py +208 -38
  5. mlrun/api/crud/model_monitoring/helpers.py +19 -6
  6. mlrun/api/crud/model_monitoring/model_endpoints.py +14 -31
  7. mlrun/api/db/sqldb/db.py +3 -1
  8. mlrun/api/utils/builder.py +2 -4
  9. mlrun/common/model_monitoring/helpers.py +19 -5
  10. mlrun/common/schemas/model_monitoring/constants.py +69 -0
  11. mlrun/common/schemas/model_monitoring/model_endpoints.py +22 -1
  12. mlrun/config.py +30 -12
  13. mlrun/datastore/__init__.py +1 -0
  14. mlrun/datastore/datastore_profile.py +2 -2
  15. mlrun/datastore/sources.py +4 -30
  16. mlrun/datastore/targets.py +106 -55
  17. mlrun/db/httpdb.py +20 -6
  18. mlrun/feature_store/__init__.py +2 -0
  19. mlrun/feature_store/api.py +3 -31
  20. mlrun/feature_store/feature_vector.py +1 -1
  21. mlrun/feature_store/retrieval/base.py +8 -3
  22. mlrun/launcher/remote.py +3 -3
  23. mlrun/lists.py +11 -0
  24. mlrun/model_monitoring/__init__.py +0 -1
  25. mlrun/model_monitoring/api.py +1 -1
  26. mlrun/model_monitoring/application.py +313 -0
  27. mlrun/model_monitoring/batch_application.py +526 -0
  28. mlrun/model_monitoring/batch_application_handler.py +32 -0
  29. mlrun/model_monitoring/evidently_application.py +89 -0
  30. mlrun/model_monitoring/helpers.py +39 -3
  31. mlrun/model_monitoring/stores/kv_model_endpoint_store.py +38 -7
  32. mlrun/model_monitoring/tracking_policy.py +4 -4
  33. mlrun/model_monitoring/writer.py +37 -0
  34. mlrun/projects/pipelines.py +38 -4
  35. mlrun/projects/project.py +257 -43
  36. mlrun/run.py +5 -2
  37. mlrun/runtimes/__init__.py +2 -0
  38. mlrun/runtimes/function.py +2 -1
  39. mlrun/utils/helpers.py +12 -0
  40. mlrun/utils/http.py +3 -0
  41. mlrun/utils/notifications/notification_pusher.py +22 -8
  42. mlrun/utils/version/version.json +2 -2
  43. {mlrun-1.5.0rc11.dist-info → mlrun-1.5.0rc13.dist-info}/METADATA +5 -5
  44. {mlrun-1.5.0rc11.dist-info → mlrun-1.5.0rc13.dist-info}/RECORD +49 -44
  45. /mlrun/model_monitoring/{model_monitoring_batch.py → batch.py} +0 -0
  46. {mlrun-1.5.0rc11.dist-info → mlrun-1.5.0rc13.dist-info}/LICENSE +0 -0
  47. {mlrun-1.5.0rc11.dist-info → mlrun-1.5.0rc13.dist-info}/WHEEL +0 -0
  48. {mlrun-1.5.0rc11.dist-info → mlrun-1.5.0rc13.dist-info}/entry_points.txt +0 -0
  49. {mlrun-1.5.0rc11.dist-info → mlrun-1.5.0rc13.dist-info}/top_level.txt +0 -0
mlrun/__main__.py CHANGED
@@ -17,6 +17,7 @@ import json
17
17
  import pathlib
18
18
  import socket
19
19
  import traceback
20
+ import warnings
20
21
  from ast import literal_eval
21
22
  from base64 import b64decode, b64encode
22
23
  from os import environ, path, remove
@@ -445,7 +446,7 @@ def run(
445
446
  @click.option("--archive", "-a", default="", help="destination archive for code (tar)")
446
447
  @click.option("--silent", is_flag=True, help="do not show build logs")
447
448
  @click.option("--with-mlrun", is_flag=True, help="add MLRun package")
448
- @click.option("--db", default="", help="save run results to path or DB url")
449
+ @click.option("--db", default="", help="save run results to DB url")
449
450
  @click.option(
450
451
  "--runtime", "-r", default="", help="function spec dict, for pipeline usage"
451
452
  )
@@ -591,6 +592,13 @@ def build(
591
592
  default="",
592
593
  help="path/url of function yaml or function " "yaml or db://<project>/<name>[:tag]",
593
594
  )
595
+ # TODO: Remove in 1.6.0
596
+ @click.option(
597
+ "--dashboard",
598
+ "-d",
599
+ default="",
600
+ help="Deprecated. Keep empty to allow auto-detect by MLRun API",
601
+ )
594
602
  @click.option("--project", "-p", default="", help="project name")
595
603
  @click.option("--model", "-m", multiple=True, help="model name and path (name=path)")
596
604
  @click.option("--kind", "-k", default=None, help="runtime sub kind")
@@ -609,6 +617,7 @@ def deploy(
609
617
  spec,
610
618
  source,
611
619
  func_url,
620
+ dashboard,
612
621
  project,
613
622
  model,
614
623
  tag,
@@ -669,6 +678,14 @@ def deploy(
669
678
  function.set_env(k, v)
670
679
  function.verbose = verbose
671
680
 
681
+ if dashboard:
682
+ warnings.warn(
683
+ "'--dashboard' is deprecated in 1.3.0, and will be removed in 1.6.0, "
684
+ "Keep '--dashboard' value empty to allow auto-detection by MLRun API.",
685
+ # TODO: Remove in 1.6.0
686
+ FutureWarning,
687
+ )
688
+
672
689
  try:
673
690
  addr = function.deploy(project=project, tag=tag)
674
691
  except Exception as err:
@@ -917,7 +934,9 @@ def version():
917
934
 
918
935
  @main.command()
919
936
  @click.argument("uid", type=str)
920
- @click.option("--project", "-p", help="project name")
937
+ @click.option(
938
+ "--project", "-p", help="project name (defaults to mlrun.mlconf.default_project)"
939
+ )
921
940
  @click.option("--offset", type=int, default=0, help="byte offset")
922
941
  @click.option("--db", help="api and db service path/url")
923
942
  @click.option("--watch", "-w", is_flag=True, help="watch/follow log")
@@ -1004,6 +1023,14 @@ def logs(uid, project, offset, db, watch):
1004
1023
  "https://apscheduler.readthedocs.io/en/3.x/modules/triggers/cron.html#module-apscheduler.triggers.cron."
1005
1024
  "For using the pre-defined workflow's schedule, set --schedule 'true'",
1006
1025
  )
1026
+ # TODO: Remove in 1.6.0
1027
+ @click.option(
1028
+ "--overwrite-schedule",
1029
+ "-os",
1030
+ is_flag=True,
1031
+ help="Deprecated (Saving schedules is now an upsert opertaion)."
1032
+ " Overwrite a schedule when submitting a new one with the same name.",
1033
+ )
1007
1034
  @click.option(
1008
1035
  "--save-secrets",
1009
1036
  is_flag=True,
@@ -1043,6 +1070,7 @@ def project(
1043
1070
  timeout,
1044
1071
  schedule,
1045
1072
  notifications,
1073
+ overwrite_schedule,
1046
1074
  save_secrets,
1047
1075
  save,
1048
1076
  ):
@@ -1132,6 +1160,7 @@ def project(
1132
1160
  local=local,
1133
1161
  schedule=schedule,
1134
1162
  timeout=timeout,
1163
+ overwrite=overwrite_schedule,
1135
1164
  )
1136
1165
  except Exception as err:
1137
1166
  print(traceback.format_exc())
@@ -47,6 +47,7 @@ import mlrun.api.utils.singletons.project_member
47
47
  import mlrun.common.model_monitoring
48
48
  import mlrun.common.model_monitoring.helpers
49
49
  import mlrun.common.schemas
50
+ import mlrun.common.schemas.model_monitoring.constants as mm_constants
50
51
  from mlrun.api.api import deps
51
52
  from mlrun.api.crud.secrets import Secrets, SecretsClientType
52
53
  from mlrun.api.utils.builder import build_runtime
@@ -729,35 +730,31 @@ def _build_function(
729
730
  launcher.enrich_runtime(runtime=fn, full=is_nuclio_runtime)
730
731
 
731
732
  fn.save(versioned=False)
732
- if is_nuclio_runtime:
733
- if fn.kind == RuntimeKinds.serving:
734
- # Handle model monitoring
733
+ if fn.kind in RuntimeKinds.nuclio_runtimes():
734
+ mlrun.api.api.utils.apply_enrichment_and_validation_on_function(
735
+ fn,
736
+ auth_info,
737
+ )
738
+ monitoring_application = (
739
+ fn.metadata.labels.get(mm_constants.ModelMonitoringAppTag.KEY)
740
+ == mm_constants.ModelMonitoringAppTag.VAL
741
+ )
742
+ serving_to_monitor = (
743
+ fn.kind == RuntimeKinds.serving and fn.spec.track_models
744
+ )
745
+ if serving_to_monitor or monitoring_application:
735
746
  try:
736
- if fn.spec.track_models:
737
- logger.info("Tracking enabled, initializing model monitoring")
738
-
739
- # Generating model monitoring access key
747
+ if not mlrun.mlconf.is_ce_mode():
748
+ model_monitoring_access_key = process_model_monitoring_secret(
749
+ db_session,
750
+ fn.metadata.project,
751
+ mlrun.common.schemas.model_monitoring.ProjectSecretKeys.ACCESS_KEY,
752
+ )
753
+ else:
740
754
  model_monitoring_access_key = None
741
- if not mlrun.mlconf.is_ce_mode():
742
- model_monitoring_access_key = process_model_monitoring_secret(
743
- db_session,
744
- fn.metadata.project,
745
- mlrun.common.schemas.model_monitoring.ProjectSecretKeys.ACCESS_KEY,
746
- )
747
-
748
- stream_path = (
749
- mlrun.api.crud.model_monitoring.get_stream_path(
750
- project=fn.metadata.project
751
- )
752
- )
753
-
754
- if stream_path.startswith("v3io://"):
755
- # Initialize model monitoring V3IO stream
756
- _create_model_monitoring_stream(
757
- project=fn.metadata.project,
758
- function=fn,
759
- stream_path=stream_path,
760
- )
755
+ if serving_to_monitor:
756
+ # Handle model monitoring
757
+ logger.info("Tracking enabled, initializing model monitoring")
761
758
 
762
759
  if fn.spec.tracking_policy:
763
760
  # Convert to `TrackingPolicy` object as `fn.spec.tracking_policy` is provided as a dict
@@ -768,7 +765,32 @@ def _build_function(
768
765
  # Initialize tracking policy with default values
769
766
  fn.spec.tracking_policy = TrackingPolicy()
770
767
 
771
- # deploy both model monitoring stream and model monitoring batch job
768
+ if not mlrun.mlconf.is_ce_mode():
769
+ # create v3io stream for model_monitoring_stream
770
+ _create_model_monitoring_stream(
771
+ project=fn.metadata.project,
772
+ function=fn,
773
+ monitoring_application=monitoring_application,
774
+ stream_path=mlrun.api.crud.model_monitoring.get_stream_path(
775
+ project=fn.metadata.project,
776
+ application_name=mm_constants.MonitoringFunctionNames.STREAM,
777
+ ),
778
+ )
779
+ if fn.spec.tracking_policy.application_batch:
780
+ # create v3io stream for model_monitoring_writer | model monitoring application
781
+ _create_model_monitoring_stream(
782
+ project=fn.metadata.project,
783
+ function=fn,
784
+ monitoring_application=monitoring_application,
785
+ stream_path=mlrun.api.crud.model_monitoring.get_stream_path(
786
+ project=fn.metadata.project,
787
+ application_name=mm_constants.MonitoringFunctionNames.WRITER,
788
+ ),
789
+ access_key=model_monitoring_access_key,
790
+ )
791
+
792
+ # deploy model monitoring stream, model monitoring batch job,
793
+ # model monitoring batch application job and model monitoring writer
772
794
  mlrun.api.crud.model_monitoring.deployment.MonitoringDeployment().deploy_monitoring_functions(
773
795
  project=fn.metadata.project,
774
796
  db_session=db_session,
@@ -776,9 +798,32 @@ def _build_function(
776
798
  tracking_policy=fn.spec.tracking_policy,
777
799
  model_monitoring_access_key=model_monitoring_access_key,
778
800
  )
801
+
802
+ if monitoring_application:
803
+ if not mlrun.mlconf.is_ce_mode():
804
+ # create v3io stream for model monitoring application
805
+ _create_model_monitoring_stream(
806
+ project=fn.metadata.project,
807
+ function=fn,
808
+ monitoring_application=monitoring_application,
809
+ stream_path=mlrun.api.crud.model_monitoring.get_stream_path(
810
+ project=fn.metadata.project,
811
+ application_name=fn.metadata.name,
812
+ ),
813
+ access_key=model_monitoring_access_key,
814
+ )
815
+ # apply stream trigger to monitoring application
816
+ fn = mlrun.api.crud.model_monitoring.deployment.MonitoringDeployment()._apply_stream_trigger(
817
+ project=fn.metadata.project,
818
+ function=fn,
819
+ model_monitoring_access_key=model_monitoring_access_key,
820
+ function_name=fn.metadata.name,
821
+ auth_info=auth_info,
822
+ )
779
823
  except Exception as exc:
780
824
  logger.warning(
781
- "Failed deploying model monitoring infrastructure for the project",
825
+ f"Failed deploying model monitoring infrastructure for the "
826
+ f"{'project' if serving_to_monitor else f'{fn.metadata.name} application'}",
782
827
  project=fn.metadata.project,
783
828
  exc=exc,
784
829
  traceback=traceback.format_exc(),
@@ -915,33 +960,46 @@ async def _get_function_status(data, auth_info: mlrun.common.schemas.AuthInfo):
915
960
  )
916
961
 
917
962
 
918
- def _create_model_monitoring_stream(project: str, function, stream_path):
919
- _init_serving_function_stream_args(fn=function)
963
+ def _create_model_monitoring_stream(
964
+ project: str,
965
+ function,
966
+ monitoring_application: bool,
967
+ stream_path: str,
968
+ access_key: str = None,
969
+ ):
970
+ if stream_path.startswith("v3io://"):
971
+ _init_serving_function_stream_args(fn=function)
920
972
 
921
- _, container, stream_path = parse_model_endpoint_store_prefix(stream_path)
973
+ _, container, stream_path = parse_model_endpoint_store_prefix(stream_path)
922
974
 
923
- # TODO: How should we configure sharding here?
924
- logger.info(
925
- "Creating model endpoint stream for project",
926
- project=project,
927
- stream_path=stream_path,
928
- container=container,
929
- endpoint=config.v3io_api,
930
- )
975
+ # TODO: How should we configure sharding here?
976
+ logger.info(
977
+ "Creating model endpoint stream for project",
978
+ project=project,
979
+ stream_path=stream_path,
980
+ container=container,
981
+ endpoint=config.v3io_api,
982
+ )
931
983
 
932
- v3io_client = v3io.dataplane.Client(
933
- endpoint=config.v3io_api, access_key=os.environ.get("V3IO_ACCESS_KEY")
934
- )
935
- response = v3io_client.create_stream(
936
- container=container,
937
- path=stream_path,
938
- shard_count=config.model_endpoint_monitoring.serving_stream_args.shard_count,
939
- retention_period_hours=config.model_endpoint_monitoring.serving_stream_args.retention_period_hours,
940
- raise_for_status=v3io.dataplane.RaiseForStatus.never,
941
- )
984
+ v3io_client = v3io.dataplane.Client(
985
+ endpoint=config.v3io_api, access_key=os.environ.get("V3IO_ACCESS_KEY")
986
+ )
987
+ stream_args = (
988
+ config.model_endpoint_monitoring.application_stream_args
989
+ if monitoring_application
990
+ else config.model_endpoint_monitoring.serving_stream_args
991
+ )
992
+ response = v3io_client.create_stream(
993
+ container=container,
994
+ path=stream_path,
995
+ shard_count=stream_args.shard_count,
996
+ retention_period_hours=stream_args.retention_period_hours,
997
+ raise_for_status=v3io.dataplane.RaiseForStatus.never,
998
+ access_key=access_key,
999
+ )
942
1000
 
943
- if not (response.status_code == 400 and "ResourceInUse" in str(response.body)):
944
- response.raise_for_status([409, 204])
1001
+ if not (response.status_code == 400 and "ResourceInUse" in str(response.body)):
1002
+ response.raise_for_status([409, 204])
945
1003
 
946
1004
 
947
1005
  def _init_serving_function_stream_args(fn: ServingRuntime):
@@ -13,8 +13,6 @@
13
13
  # limitations under the License.
14
14
  #
15
15
  import json
16
- import os
17
- import warnings
18
16
  from http import HTTPStatus
19
17
  from typing import List, Optional
20
18
 
@@ -32,60 +30,6 @@ from mlrun.errors import MLRunConflictError
32
30
  router = APIRouter(prefix="/projects/{project}/model-endpoints")
33
31
 
34
32
 
35
- @router.put(
36
- "/{endpoint_id}",
37
- response_model=mlrun.common.schemas.ModelEndpoint,
38
- )
39
- async def create_or_patch(
40
- project: str,
41
- endpoint_id: str,
42
- model_endpoint: mlrun.common.schemas.ModelEndpoint,
43
- auth_info: mlrun.common.schemas.AuthInfo = Depends(
44
- mlrun.api.api.deps.authenticate_request
45
- ),
46
- db_session: Session = Depends(mlrun.api.api.deps.get_db_session),
47
- ) -> mlrun.common.schemas.ModelEndpoint:
48
- """
49
- Either create or update the record of a given `ModelEndpoint` object.
50
- Leaving here for backwards compatibility.
51
- """
52
-
53
- warnings.warn(
54
- "This PUT call is deprecated, please use POST for create or PATCH for update"
55
- "This will be removed in 1.5.0",
56
- # TODO: Remove this API in 1.5.0
57
- FutureWarning,
58
- )
59
-
60
- await mlrun.api.utils.auth.verifier.AuthVerifier().query_project_resource_permissions(
61
- mlrun.common.schemas.AuthorizationResourceTypes.model_endpoint,
62
- project,
63
- endpoint_id,
64
- mlrun.common.schemas.AuthorizationAction.store,
65
- auth_info,
66
- )
67
- # get_access_key will validate the needed auth (which is used later) exists in the request
68
- mlrun.api.crud.model_monitoring.helpers.get_access_key(auth_info)
69
- if project != model_endpoint.metadata.project:
70
- raise MLRunConflictError(
71
- f"Can't store endpoint of project {model_endpoint.metadata.project} into project {project}"
72
- )
73
- if endpoint_id != model_endpoint.metadata.uid:
74
- raise MLRunConflictError(
75
- f"Mismatch between endpoint_id {endpoint_id} and ModelEndpoint.metadata.uid {model_endpoint.metadata.uid}."
76
- f"\nMake sure the supplied function_uri, and model are configured as intended"
77
- )
78
- # Since the endpoint records are created automatically, at point of serving function deployment, we need to use
79
- # V3IO_ACCESS_KEY here
80
- return await run_in_threadpool(
81
- mlrun.api.crud.ModelEndpoints().create_or_patch,
82
- db_session=db_session,
83
- access_key=os.environ.get("V3IO_ACCESS_KEY"),
84
- model_endpoint=model_endpoint,
85
- auth_info=auth_info,
86
- )
87
-
88
-
89
33
  @router.post(
90
34
  "/{endpoint_id}",
91
35
  response_model=mlrun.common.schemas.ModelEndpoint,