mlrun 1.3.3rc1__py3-none-any.whl → 1.4.0__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 +3 -3
- mlrun/__main__.py +79 -37
- mlrun/api/__init__.py +1 -1
- mlrun/api/api/__init__.py +1 -1
- mlrun/api/api/api.py +4 -4
- mlrun/api/api/deps.py +10 -21
- mlrun/api/api/endpoints/__init__.py +1 -1
- mlrun/api/api/endpoints/artifacts.py +64 -36
- mlrun/api/api/endpoints/auth.py +4 -4
- mlrun/api/api/endpoints/background_tasks.py +11 -11
- mlrun/api/api/endpoints/client_spec.py +5 -5
- mlrun/api/api/endpoints/clusterization_spec.py +6 -4
- mlrun/api/api/endpoints/feature_store.py +124 -115
- mlrun/api/api/endpoints/files.py +22 -14
- mlrun/api/api/endpoints/frontend_spec.py +28 -21
- mlrun/api/api/endpoints/functions.py +142 -87
- mlrun/api/api/endpoints/grafana_proxy.py +89 -442
- mlrun/api/api/endpoints/healthz.py +20 -7
- mlrun/api/api/endpoints/hub.py +320 -0
- mlrun/api/api/endpoints/internal/__init__.py +1 -1
- mlrun/api/api/endpoints/internal/config.py +1 -1
- mlrun/api/api/endpoints/internal/memory_reports.py +9 -9
- mlrun/api/api/endpoints/logs.py +11 -11
- mlrun/api/api/endpoints/model_endpoints.py +74 -70
- mlrun/api/api/endpoints/operations.py +13 -9
- mlrun/api/api/endpoints/pipelines.py +93 -88
- mlrun/api/api/endpoints/projects.py +35 -35
- mlrun/api/api/endpoints/runs.py +69 -27
- mlrun/api/api/endpoints/runtime_resources.py +28 -28
- mlrun/api/api/endpoints/schedules.py +98 -41
- mlrun/api/api/endpoints/secrets.py +37 -32
- mlrun/api/api/endpoints/submit.py +12 -12
- mlrun/api/api/endpoints/tags.py +20 -22
- mlrun/api/api/utils.py +251 -42
- mlrun/api/constants.py +1 -1
- mlrun/api/crud/__init__.py +18 -15
- mlrun/api/crud/artifacts.py +10 -10
- mlrun/api/crud/client_spec.py +4 -4
- mlrun/api/crud/clusterization_spec.py +3 -3
- mlrun/api/crud/feature_store.py +54 -46
- mlrun/api/crud/functions.py +3 -3
- mlrun/api/crud/hub.py +312 -0
- mlrun/api/crud/logs.py +11 -9
- mlrun/api/crud/model_monitoring/__init__.py +3 -3
- mlrun/api/crud/model_monitoring/grafana.py +435 -0
- mlrun/api/crud/model_monitoring/model_endpoints.py +352 -129
- mlrun/api/crud/notifications.py +149 -0
- mlrun/api/crud/pipelines.py +67 -52
- mlrun/api/crud/projects.py +51 -23
- mlrun/api/crud/runs.py +7 -5
- mlrun/api/crud/runtime_resources.py +13 -13
- mlrun/api/{db/filedb → crud/runtimes}/__init__.py +1 -1
- mlrun/api/crud/runtimes/nuclio/__init__.py +14 -0
- mlrun/api/crud/runtimes/nuclio/function.py +505 -0
- mlrun/api/crud/runtimes/nuclio/helpers.py +310 -0
- mlrun/api/crud/secrets.py +88 -46
- mlrun/api/crud/tags.py +5 -5
- mlrun/api/db/__init__.py +1 -1
- mlrun/api/db/base.py +102 -54
- mlrun/api/db/init_db.py +2 -3
- mlrun/api/db/session.py +4 -12
- mlrun/api/db/sqldb/__init__.py +1 -1
- mlrun/api/db/sqldb/db.py +439 -196
- mlrun/api/db/sqldb/helpers.py +1 -1
- mlrun/api/db/sqldb/models/__init__.py +3 -3
- mlrun/api/db/sqldb/models/models_mysql.py +82 -64
- mlrun/api/db/sqldb/models/models_sqlite.py +76 -64
- mlrun/api/db/sqldb/session.py +27 -20
- mlrun/api/initial_data.py +82 -24
- mlrun/api/launcher.py +196 -0
- mlrun/api/main.py +91 -22
- mlrun/api/middlewares.py +6 -5
- mlrun/api/migrations_mysql/env.py +1 -1
- mlrun/api/migrations_mysql/versions/28383af526f3_market_place_to_hub.py +40 -0
- mlrun/api/migrations_mysql/versions/32bae1b0e29c_increase_timestamp_fields_precision.py +1 -1
- mlrun/api/migrations_mysql/versions/4903aef6a91d_tag_foreign_key_and_cascades.py +1 -1
- mlrun/api/migrations_mysql/versions/5f1351c88a19_adding_background_tasks_table.py +1 -1
- mlrun/api/migrations_mysql/versions/88e656800d6a_add_requested_logs_column_and_index_to_.py +1 -1
- mlrun/api/migrations_mysql/versions/9d16de5f03a7_adding_data_versions_table.py +1 -1
- mlrun/api/migrations_mysql/versions/b86f5b53f3d7_adding_name_and_updated_to_runs_table.py +1 -1
- mlrun/api/migrations_mysql/versions/c4af40b0bf61_init.py +1 -1
- mlrun/api/migrations_mysql/versions/c905d15bd91d_notifications.py +72 -0
- mlrun/api/migrations_mysql/versions/ee041e8fdaa0_adding_next_run_time_column_to_schedule_.py +1 -1
- mlrun/api/migrations_sqlite/env.py +1 -1
- mlrun/api/migrations_sqlite/versions/11f8dd2dc9fe_init.py +1 -1
- mlrun/api/migrations_sqlite/versions/1c954f8cb32d_schedule_last_run_uri.py +1 -1
- mlrun/api/migrations_sqlite/versions/2b6d23c715aa_adding_feature_sets.py +1 -1
- mlrun/api/migrations_sqlite/versions/4acd9430b093_market_place_to_hub.py +77 -0
- mlrun/api/migrations_sqlite/versions/6401142f2d7c_adding_next_run_time_column_to_schedule_.py +1 -1
- mlrun/api/migrations_sqlite/versions/64d90a1a69bc_adding_background_tasks_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/803438ecd005_add_requested_logs_column_to_runs.py +1 -1
- mlrun/api/migrations_sqlite/versions/863114f0c659_refactoring_feature_set.py +1 -1
- mlrun/api/migrations_sqlite/versions/959ae00528ad_notifications.py +63 -0
- mlrun/api/migrations_sqlite/versions/accf9fc83d38_adding_data_versions_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/b68e8e897a28_schedule_labels.py +1 -1
- mlrun/api/migrations_sqlite/versions/bcd0c1f9720c_adding_project_labels.py +1 -1
- mlrun/api/migrations_sqlite/versions/cf21882f938e_schedule_id.py +1 -1
- mlrun/api/migrations_sqlite/versions/d781f58f607f_tag_object_name_string.py +1 -1
- mlrun/api/migrations_sqlite/versions/deac06871ace_adding_marketplace_sources_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/e1dd5983c06b_schedule_concurrency_limit.py +1 -1
- mlrun/api/migrations_sqlite/versions/e5594ed3ab53_adding_name_and_updated_to_runs_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/f4249b4ba6fa_adding_feature_vectors.py +1 -1
- mlrun/api/migrations_sqlite/versions/f7b5a1a03629_adding_feature_labels.py +1 -1
- mlrun/api/schemas/__init__.py +216 -138
- mlrun/api/utils/__init__.py +1 -1
- mlrun/api/utils/asyncio.py +1 -1
- mlrun/api/utils/auth/__init__.py +1 -1
- mlrun/api/utils/auth/providers/__init__.py +1 -1
- mlrun/api/utils/auth/providers/base.py +7 -7
- mlrun/api/utils/auth/providers/nop.py +6 -7
- mlrun/api/utils/auth/providers/opa.py +17 -17
- mlrun/api/utils/auth/verifier.py +36 -34
- mlrun/api/utils/background_tasks.py +24 -24
- mlrun/{builder.py → api/utils/builder.py} +216 -123
- mlrun/api/utils/clients/__init__.py +1 -1
- mlrun/api/utils/clients/chief.py +19 -4
- mlrun/api/utils/clients/iguazio.py +106 -60
- mlrun/api/utils/clients/log_collector.py +1 -1
- mlrun/api/utils/clients/nuclio.py +23 -23
- mlrun/api/utils/clients/protocols/grpc.py +2 -2
- mlrun/api/utils/db/__init__.py +1 -1
- mlrun/api/utils/db/alembic.py +1 -1
- mlrun/api/utils/db/backup.py +1 -1
- mlrun/api/utils/db/mysql.py +24 -25
- mlrun/api/utils/db/sql_collation.py +1 -1
- mlrun/api/utils/db/sqlite_migration.py +2 -2
- mlrun/api/utils/events/__init__.py +14 -0
- mlrun/api/utils/events/base.py +57 -0
- mlrun/api/utils/events/events_factory.py +41 -0
- mlrun/api/utils/events/iguazio.py +217 -0
- mlrun/api/utils/events/nop.py +55 -0
- mlrun/api/utils/helpers.py +16 -13
- mlrun/api/utils/memory_reports.py +1 -1
- mlrun/api/utils/periodic.py +6 -3
- mlrun/api/utils/projects/__init__.py +1 -1
- mlrun/api/utils/projects/follower.py +33 -33
- mlrun/api/utils/projects/leader.py +36 -34
- mlrun/api/utils/projects/member.py +27 -27
- mlrun/api/utils/projects/remotes/__init__.py +1 -1
- mlrun/api/utils/projects/remotes/follower.py +13 -13
- mlrun/api/utils/projects/remotes/leader.py +10 -10
- mlrun/api/utils/projects/remotes/nop_follower.py +27 -21
- mlrun/api/utils/projects/remotes/nop_leader.py +17 -16
- mlrun/api/utils/scheduler.py +140 -51
- mlrun/api/utils/singletons/__init__.py +1 -1
- mlrun/api/utils/singletons/db.py +9 -15
- mlrun/api/utils/singletons/k8s.py +677 -5
- mlrun/api/utils/singletons/logs_dir.py +1 -1
- mlrun/api/utils/singletons/project_member.py +1 -1
- mlrun/api/utils/singletons/scheduler.py +1 -1
- mlrun/artifacts/__init__.py +2 -2
- mlrun/artifacts/base.py +8 -2
- mlrun/artifacts/dataset.py +5 -3
- mlrun/artifacts/manager.py +7 -1
- mlrun/artifacts/model.py +15 -4
- mlrun/artifacts/plots.py +1 -1
- mlrun/common/__init__.py +1 -1
- mlrun/common/constants.py +15 -0
- mlrun/common/model_monitoring.py +209 -0
- mlrun/common/schemas/__init__.py +167 -0
- mlrun/{api → common}/schemas/artifact.py +13 -14
- mlrun/{api → common}/schemas/auth.py +10 -8
- mlrun/{api → common}/schemas/background_task.py +3 -3
- mlrun/{api → common}/schemas/client_spec.py +1 -1
- mlrun/{api → common}/schemas/clusterization_spec.py +3 -3
- mlrun/{api → common}/schemas/constants.py +21 -8
- mlrun/common/schemas/events.py +36 -0
- mlrun/{api → common}/schemas/feature_store.py +2 -1
- mlrun/{api → common}/schemas/frontend_spec.py +7 -6
- mlrun/{api → common}/schemas/function.py +5 -5
- mlrun/{api → common}/schemas/http.py +3 -3
- mlrun/common/schemas/hub.py +134 -0
- mlrun/{api → common}/schemas/k8s.py +3 -3
- mlrun/{api → common}/schemas/memory_reports.py +1 -1
- mlrun/common/schemas/model_endpoints.py +342 -0
- mlrun/common/schemas/notification.py +57 -0
- mlrun/{api → common}/schemas/object.py +6 -6
- mlrun/{api → common}/schemas/pipeline.py +3 -3
- mlrun/{api → common}/schemas/project.py +6 -5
- mlrun/common/schemas/regex.py +24 -0
- mlrun/common/schemas/runs.py +30 -0
- mlrun/{api → common}/schemas/runtime_resource.py +3 -3
- mlrun/{api → common}/schemas/schedule.py +19 -7
- mlrun/{api → common}/schemas/secret.py +3 -3
- mlrun/{api → common}/schemas/tag.py +2 -2
- mlrun/common/types.py +25 -0
- mlrun/config.py +152 -20
- mlrun/data_types/__init__.py +7 -2
- mlrun/data_types/data_types.py +4 -2
- mlrun/data_types/infer.py +1 -1
- mlrun/data_types/spark.py +10 -3
- mlrun/datastore/__init__.py +10 -3
- mlrun/datastore/azure_blob.py +1 -1
- mlrun/datastore/base.py +185 -53
- mlrun/datastore/datastore.py +1 -1
- mlrun/datastore/filestore.py +1 -1
- mlrun/datastore/google_cloud_storage.py +1 -1
- mlrun/datastore/inmem.py +4 -1
- mlrun/datastore/redis.py +1 -1
- mlrun/datastore/s3.py +1 -1
- mlrun/datastore/sources.py +192 -70
- mlrun/datastore/spark_udf.py +44 -0
- mlrun/datastore/store_resources.py +4 -4
- mlrun/datastore/targets.py +115 -45
- mlrun/datastore/utils.py +127 -5
- mlrun/datastore/v3io.py +1 -1
- mlrun/datastore/wasbfs/__init__.py +1 -1
- mlrun/datastore/wasbfs/fs.py +1 -1
- mlrun/db/__init__.py +7 -5
- mlrun/db/base.py +112 -68
- mlrun/db/httpdb.py +445 -277
- mlrun/db/nopdb.py +491 -0
- mlrun/db/sqldb.py +112 -65
- mlrun/errors.py +6 -1
- mlrun/execution.py +44 -22
- mlrun/feature_store/__init__.py +1 -1
- mlrun/feature_store/api.py +143 -95
- mlrun/feature_store/common.py +16 -20
- mlrun/feature_store/feature_set.py +42 -12
- mlrun/feature_store/feature_vector.py +32 -21
- mlrun/feature_store/ingestion.py +9 -12
- mlrun/feature_store/retrieval/__init__.py +3 -2
- mlrun/feature_store/retrieval/base.py +388 -66
- mlrun/feature_store/retrieval/dask_merger.py +63 -151
- mlrun/feature_store/retrieval/job.py +30 -12
- mlrun/feature_store/retrieval/local_merger.py +40 -133
- mlrun/feature_store/retrieval/spark_merger.py +129 -127
- mlrun/feature_store/retrieval/storey_merger.py +173 -0
- mlrun/feature_store/steps.py +132 -15
- mlrun/features.py +8 -3
- mlrun/frameworks/__init__.py +1 -1
- mlrun/frameworks/_common/__init__.py +1 -1
- mlrun/frameworks/_common/artifacts_library.py +1 -1
- mlrun/frameworks/_common/mlrun_interface.py +1 -1
- mlrun/frameworks/_common/model_handler.py +1 -1
- mlrun/frameworks/_common/plan.py +1 -1
- mlrun/frameworks/_common/producer.py +1 -1
- mlrun/frameworks/_common/utils.py +1 -1
- mlrun/frameworks/_dl_common/__init__.py +1 -1
- mlrun/frameworks/_dl_common/loggers/__init__.py +1 -1
- mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
- mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +1 -1
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +1 -1
- mlrun/frameworks/_dl_common/model_handler.py +1 -1
- mlrun/frameworks/_dl_common/utils.py +1 -1
- mlrun/frameworks/_ml_common/__init__.py +1 -1
- mlrun/frameworks/_ml_common/artifacts_library.py +1 -1
- mlrun/frameworks/_ml_common/loggers/__init__.py +1 -1
- mlrun/frameworks/_ml_common/loggers/logger.py +1 -1
- mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
- mlrun/frameworks/_ml_common/model_handler.py +1 -1
- mlrun/frameworks/_ml_common/pkl_model_server.py +13 -1
- mlrun/frameworks/_ml_common/plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/__init__.py +1 -1
- mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +1 -6
- mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/dataset_plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +1 -1
- mlrun/frameworks/_ml_common/producer.py +1 -1
- mlrun/frameworks/_ml_common/utils.py +1 -1
- mlrun/frameworks/auto_mlrun/__init__.py +1 -1
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +1 -1
- mlrun/frameworks/huggingface/__init__.py +1 -1
- mlrun/frameworks/huggingface/model_server.py +1 -1
- mlrun/frameworks/lgbm/__init__.py +1 -1
- mlrun/frameworks/lgbm/callbacks/__init__.py +1 -1
- mlrun/frameworks/lgbm/callbacks/callback.py +1 -1
- mlrun/frameworks/lgbm/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/model_mlrun_interface.py +1 -1
- mlrun/frameworks/lgbm/model_handler.py +1 -1
- mlrun/frameworks/lgbm/model_server.py +1 -1
- mlrun/frameworks/lgbm/utils.py +1 -1
- mlrun/frameworks/onnx/__init__.py +1 -1
- mlrun/frameworks/onnx/dataset.py +1 -1
- mlrun/frameworks/onnx/mlrun_interface.py +1 -1
- mlrun/frameworks/onnx/model_handler.py +1 -1
- mlrun/frameworks/onnx/model_server.py +1 -1
- mlrun/frameworks/parallel_coordinates.py +1 -1
- mlrun/frameworks/pytorch/__init__.py +1 -1
- mlrun/frameworks/pytorch/callbacks/__init__.py +1 -1
- mlrun/frameworks/pytorch/callbacks/callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks_handler.py +1 -1
- mlrun/frameworks/pytorch/mlrun_interface.py +1 -1
- mlrun/frameworks/pytorch/model_handler.py +1 -1
- mlrun/frameworks/pytorch/model_server.py +1 -1
- mlrun/frameworks/pytorch/utils.py +1 -1
- mlrun/frameworks/sklearn/__init__.py +1 -1
- mlrun/frameworks/sklearn/estimator.py +1 -1
- mlrun/frameworks/sklearn/metric.py +1 -1
- mlrun/frameworks/sklearn/metrics_library.py +1 -1
- mlrun/frameworks/sklearn/mlrun_interface.py +1 -1
- mlrun/frameworks/sklearn/model_handler.py +1 -1
- mlrun/frameworks/sklearn/utils.py +1 -1
- mlrun/frameworks/tf_keras/__init__.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/mlrun_interface.py +1 -1
- mlrun/frameworks/tf_keras/model_handler.py +1 -1
- mlrun/frameworks/tf_keras/model_server.py +1 -1
- mlrun/frameworks/tf_keras/utils.py +1 -1
- mlrun/frameworks/xgboost/__init__.py +1 -1
- mlrun/frameworks/xgboost/mlrun_interface.py +1 -1
- mlrun/frameworks/xgboost/model_handler.py +1 -1
- mlrun/frameworks/xgboost/utils.py +1 -1
- mlrun/k8s_utils.py +14 -765
- mlrun/kfpops.py +14 -17
- mlrun/launcher/__init__.py +13 -0
- mlrun/launcher/base.py +406 -0
- mlrun/launcher/client.py +159 -0
- mlrun/launcher/factory.py +50 -0
- mlrun/launcher/local.py +276 -0
- mlrun/launcher/remote.py +178 -0
- mlrun/lists.py +10 -2
- mlrun/mlutils/__init__.py +1 -1
- mlrun/mlutils/data.py +1 -1
- mlrun/mlutils/models.py +1 -1
- mlrun/mlutils/plots.py +1 -1
- mlrun/model.py +252 -14
- mlrun/model_monitoring/__init__.py +41 -0
- mlrun/model_monitoring/features_drift_table.py +1 -1
- mlrun/model_monitoring/helpers.py +123 -38
- mlrun/model_monitoring/model_endpoint.py +144 -0
- mlrun/model_monitoring/model_monitoring_batch.py +310 -259
- mlrun/model_monitoring/stores/__init__.py +106 -0
- mlrun/model_monitoring/stores/kv_model_endpoint_store.py +448 -0
- mlrun/model_monitoring/stores/model_endpoint_store.py +147 -0
- mlrun/model_monitoring/stores/models/__init__.py +23 -0
- mlrun/model_monitoring/stores/models/base.py +18 -0
- mlrun/model_monitoring/stores/models/mysql.py +100 -0
- mlrun/model_monitoring/stores/models/sqlite.py +98 -0
- mlrun/model_monitoring/stores/sql_model_endpoint_store.py +370 -0
- mlrun/model_monitoring/stream_processing_fs.py +239 -271
- mlrun/package/__init__.py +163 -0
- mlrun/package/context_handler.py +325 -0
- mlrun/package/errors.py +47 -0
- mlrun/package/packager.py +298 -0
- mlrun/{runtimes/package → package/packagers}/__init__.py +3 -1
- mlrun/package/packagers/default_packager.py +422 -0
- mlrun/package/packagers/numpy_packagers.py +612 -0
- mlrun/package/packagers/pandas_packagers.py +968 -0
- mlrun/package/packagers/python_standard_library_packagers.py +616 -0
- mlrun/package/packagers_manager.py +786 -0
- mlrun/package/utils/__init__.py +53 -0
- mlrun/package/utils/_archiver.py +226 -0
- mlrun/package/utils/_formatter.py +211 -0
- mlrun/package/utils/_pickler.py +234 -0
- mlrun/package/utils/_supported_format.py +71 -0
- mlrun/package/utils/log_hint_utils.py +93 -0
- mlrun/package/utils/type_hint_utils.py +298 -0
- mlrun/platforms/__init__.py +1 -1
- mlrun/platforms/iguazio.py +34 -2
- mlrun/platforms/other.py +1 -1
- mlrun/projects/__init__.py +1 -1
- mlrun/projects/operations.py +14 -9
- mlrun/projects/pipelines.py +31 -13
- mlrun/projects/project.py +762 -238
- mlrun/render.py +49 -19
- mlrun/run.py +57 -326
- mlrun/runtimes/__init__.py +3 -9
- mlrun/runtimes/base.py +247 -784
- mlrun/runtimes/constants.py +1 -1
- mlrun/runtimes/daskjob.py +45 -41
- mlrun/runtimes/funcdoc.py +43 -7
- mlrun/runtimes/function.py +66 -656
- mlrun/runtimes/function_reference.py +1 -1
- mlrun/runtimes/generators.py +1 -1
- mlrun/runtimes/kubejob.py +99 -116
- mlrun/runtimes/local.py +59 -66
- mlrun/runtimes/mpijob/__init__.py +1 -1
- mlrun/runtimes/mpijob/abstract.py +13 -15
- mlrun/runtimes/mpijob/v1.py +3 -1
- mlrun/runtimes/mpijob/v1alpha1.py +1 -1
- mlrun/runtimes/nuclio.py +1 -1
- mlrun/runtimes/pod.py +51 -26
- mlrun/runtimes/remotesparkjob.py +3 -1
- mlrun/runtimes/serving.py +12 -4
- mlrun/runtimes/sparkjob/__init__.py +1 -2
- mlrun/runtimes/sparkjob/abstract.py +44 -31
- mlrun/runtimes/sparkjob/spark3job.py +11 -9
- mlrun/runtimes/utils.py +61 -42
- mlrun/secrets.py +16 -18
- mlrun/serving/__init__.py +3 -2
- mlrun/serving/merger.py +1 -1
- mlrun/serving/remote.py +1 -1
- mlrun/serving/routers.py +39 -42
- mlrun/serving/server.py +23 -13
- mlrun/serving/serving_wrapper.py +1 -1
- mlrun/serving/states.py +172 -39
- mlrun/serving/utils.py +1 -1
- mlrun/serving/v1_serving.py +1 -1
- mlrun/serving/v2_serving.py +29 -21
- mlrun/utils/__init__.py +1 -2
- mlrun/utils/async_http.py +8 -1
- mlrun/utils/azure_vault.py +1 -1
- mlrun/utils/clones.py +2 -2
- mlrun/utils/condition_evaluator.py +65 -0
- mlrun/utils/db.py +52 -0
- mlrun/utils/helpers.py +188 -13
- mlrun/utils/http.py +89 -54
- mlrun/utils/logger.py +48 -8
- mlrun/utils/model_monitoring.py +132 -100
- mlrun/utils/notifications/__init__.py +1 -1
- mlrun/utils/notifications/notification/__init__.py +8 -6
- mlrun/utils/notifications/notification/base.py +20 -14
- mlrun/utils/notifications/notification/console.py +7 -4
- mlrun/utils/notifications/notification/git.py +36 -19
- mlrun/utils/notifications/notification/ipython.py +10 -8
- mlrun/utils/notifications/notification/slack.py +18 -13
- mlrun/utils/notifications/notification_pusher.py +377 -56
- mlrun/utils/regex.py +6 -1
- mlrun/utils/singleton.py +1 -1
- mlrun/utils/v3io_clients.py +1 -1
- mlrun/utils/vault.py +270 -269
- mlrun/utils/version/__init__.py +1 -1
- mlrun/utils/version/version.json +2 -2
- mlrun/utils/version/version.py +1 -1
- {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/METADATA +16 -10
- mlrun-1.4.0.dist-info/RECORD +434 -0
- mlrun/api/api/endpoints/marketplace.py +0 -257
- mlrun/api/crud/marketplace.py +0 -221
- mlrun/api/crud/model_monitoring/model_endpoint_store.py +0 -847
- mlrun/api/db/filedb/db.py +0 -518
- mlrun/api/schemas/marketplace.py +0 -128
- mlrun/api/schemas/model_endpoints.py +0 -185
- mlrun/db/filedb.py +0 -891
- mlrun/feature_store/retrieval/online.py +0 -92
- mlrun/model_monitoring/constants.py +0 -67
- mlrun/runtimes/package/context_handler.py +0 -711
- mlrun/runtimes/sparkjob/spark2job.py +0 -59
- mlrun-1.3.3rc1.dist-info/RECORD +0 -381
- {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
- {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
- {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
- {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
|
@@ -1,847 +0,0 @@
|
|
|
1
|
-
# Copyright 2018 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
|
-
|
|
16
|
-
import enum
|
|
17
|
-
import json
|
|
18
|
-
import typing
|
|
19
|
-
from abc import ABC, abstractmethod
|
|
20
|
-
|
|
21
|
-
import v3io.dataplane
|
|
22
|
-
import v3io_frames
|
|
23
|
-
|
|
24
|
-
import mlrun
|
|
25
|
-
import mlrun.api.schemas
|
|
26
|
-
import mlrun.model_monitoring.constants as model_monitoring_constants
|
|
27
|
-
import mlrun.utils.model_monitoring
|
|
28
|
-
import mlrun.utils.v3io_clients
|
|
29
|
-
from mlrun.utils import logger
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class _ModelEndpointStore(ABC):
|
|
33
|
-
"""
|
|
34
|
-
An abstract class to handle the model endpoint in the DB target.
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
def __init__(self, project: str):
|
|
38
|
-
"""
|
|
39
|
-
Initialize a new model endpoint target.
|
|
40
|
-
|
|
41
|
-
:param project: The name of the project.
|
|
42
|
-
"""
|
|
43
|
-
self.project = project
|
|
44
|
-
|
|
45
|
-
@abstractmethod
|
|
46
|
-
def write_model_endpoint(self, endpoint: mlrun.api.schemas.ModelEndpoint):
|
|
47
|
-
"""
|
|
48
|
-
Create a new endpoint record in the DB table.
|
|
49
|
-
|
|
50
|
-
:param endpoint: ModelEndpoint object that will be written into the DB.
|
|
51
|
-
"""
|
|
52
|
-
pass
|
|
53
|
-
|
|
54
|
-
@abstractmethod
|
|
55
|
-
def update_model_endpoint(self, endpoint_id: str, attributes: dict):
|
|
56
|
-
"""
|
|
57
|
-
Update a model endpoint record with a given attributes.
|
|
58
|
-
|
|
59
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
60
|
-
:param attributes: Dictionary of attributes that will be used for update the model endpoint. Note that the keys
|
|
61
|
-
of the attributes dictionary should exist in the KV table.
|
|
62
|
-
|
|
63
|
-
"""
|
|
64
|
-
pass
|
|
65
|
-
|
|
66
|
-
@abstractmethod
|
|
67
|
-
def delete_model_endpoint(self, endpoint_id: str):
|
|
68
|
-
"""
|
|
69
|
-
Deletes the record of a given model endpoint id.
|
|
70
|
-
|
|
71
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
72
|
-
"""
|
|
73
|
-
pass
|
|
74
|
-
|
|
75
|
-
@abstractmethod
|
|
76
|
-
def delete_model_endpoints_resources(
|
|
77
|
-
self, endpoints: mlrun.api.schemas.model_endpoints.ModelEndpointList
|
|
78
|
-
):
|
|
79
|
-
"""
|
|
80
|
-
Delete all model endpoints resources.
|
|
81
|
-
|
|
82
|
-
:param endpoints: An object of ModelEndpointList which is literally a list of model endpoints along with some
|
|
83
|
-
metadata. To get a standard list of model endpoints use ModelEndpointList.endpoints.
|
|
84
|
-
"""
|
|
85
|
-
pass
|
|
86
|
-
|
|
87
|
-
@abstractmethod
|
|
88
|
-
def get_model_endpoint(
|
|
89
|
-
self,
|
|
90
|
-
metrics: typing.List[str] = None,
|
|
91
|
-
start: str = "now-1h",
|
|
92
|
-
end: str = "now",
|
|
93
|
-
feature_analysis: bool = False,
|
|
94
|
-
endpoint_id: str = None,
|
|
95
|
-
) -> mlrun.api.schemas.ModelEndpoint:
|
|
96
|
-
"""
|
|
97
|
-
Get a single model endpoint object. You can apply different time series metrics that will be added to the
|
|
98
|
-
result.
|
|
99
|
-
|
|
100
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
101
|
-
:param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
|
|
102
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
103
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
104
|
-
earliest time.
|
|
105
|
-
:param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
|
|
106
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
107
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
108
|
-
earliest time.
|
|
109
|
-
:param metrics: A list of metrics to return for the model endpoint. There are pre-defined metrics for
|
|
110
|
-
model endpoints such as predictions_per_second and latency_avg_5m but also custom
|
|
111
|
-
metrics defined by the user. Please note that these metrics are stored in the time
|
|
112
|
-
series DB and the results will be appeared under model_endpoint.spec.metrics.
|
|
113
|
-
:param feature_analysis: When True, the base feature statistics and current feature statistics will be added to
|
|
114
|
-
the output of the resulting object.
|
|
115
|
-
|
|
116
|
-
:return: A ModelEndpoint object.
|
|
117
|
-
"""
|
|
118
|
-
pass
|
|
119
|
-
|
|
120
|
-
@abstractmethod
|
|
121
|
-
def list_model_endpoints(
|
|
122
|
-
self, model: str, function: str, labels: typing.List, top_level: bool
|
|
123
|
-
):
|
|
124
|
-
"""
|
|
125
|
-
Returns a list of endpoint unique ids, supports filtering by model, function,
|
|
126
|
-
labels or top level. By default, when no filters are applied, all available endpoint ids for the given project
|
|
127
|
-
will be listed.
|
|
128
|
-
|
|
129
|
-
:param model: The name of the model to filter by.
|
|
130
|
-
:param function: The name of the function to filter by.
|
|
131
|
-
:param labels: A list of labels to filter by. Label filters work by either filtering a specific value
|
|
132
|
-
of a label (i.e. list("key==value")) or by looking for the existence of a given
|
|
133
|
-
key (i.e. "key").
|
|
134
|
-
:param top_level: If True will return only routers and endpoint that are NOT children of any router.
|
|
135
|
-
|
|
136
|
-
:return: List of model endpoints unique ids.
|
|
137
|
-
"""
|
|
138
|
-
pass
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
class _ModelEndpointKVStore(_ModelEndpointStore):
|
|
142
|
-
"""
|
|
143
|
-
Handles the DB operations when the DB target is from type KV. For the KV operations, we use an instance of V3IO
|
|
144
|
-
client and usually the KV table can be found under v3io:///users/pipelines/project-name/model-endpoints/endpoints/.
|
|
145
|
-
"""
|
|
146
|
-
|
|
147
|
-
def __init__(self, access_key: str, project: str):
|
|
148
|
-
super().__init__(project=project)
|
|
149
|
-
# Initialize a V3IO client instance
|
|
150
|
-
self.access_key = access_key
|
|
151
|
-
self.client = mlrun.utils.v3io_clients.get_v3io_client(
|
|
152
|
-
endpoint=mlrun.mlconf.v3io_api, access_key=self.access_key
|
|
153
|
-
)
|
|
154
|
-
# Get the KV table path and container
|
|
155
|
-
self.path, self.container = self._get_path_and_container()
|
|
156
|
-
|
|
157
|
-
def write_model_endpoint(self, endpoint: mlrun.api.schemas.ModelEndpoint):
|
|
158
|
-
"""
|
|
159
|
-
Create a new endpoint record in the KV table.
|
|
160
|
-
|
|
161
|
-
:param endpoint: ModelEndpoint object that will be written into the DB.
|
|
162
|
-
"""
|
|
163
|
-
|
|
164
|
-
# Flatten the model endpoint structure in order to write it into the DB table.
|
|
165
|
-
# More details about the model endpoint available attributes can be found under
|
|
166
|
-
# :py:class:`~mlrun.api.schemas.ModelEndpoint`.`
|
|
167
|
-
attributes = self.flatten_model_endpoint_attributes(endpoint)
|
|
168
|
-
|
|
169
|
-
# Create or update the model endpoint record
|
|
170
|
-
self.client.kv.put(
|
|
171
|
-
container=self.container,
|
|
172
|
-
table_path=self.path,
|
|
173
|
-
key=endpoint.metadata.uid,
|
|
174
|
-
attributes=attributes,
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
def update_model_endpoint(self, endpoint_id: str, attributes: dict):
|
|
178
|
-
"""
|
|
179
|
-
Update a model endpoint record with a given attributes.
|
|
180
|
-
|
|
181
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
182
|
-
:param attributes: Dictionary of attributes that will be used for update the model endpoint. Note that the keys
|
|
183
|
-
of the attributes dictionary should exist in the KV table. More details about the model
|
|
184
|
-
endpoint available attributes can be found under
|
|
185
|
-
:py:class:`~mlrun.api.schemas.ModelEndpoint`.
|
|
186
|
-
|
|
187
|
-
"""
|
|
188
|
-
|
|
189
|
-
self.client.kv.update(
|
|
190
|
-
container=self.container,
|
|
191
|
-
table_path=self.path,
|
|
192
|
-
key=endpoint_id,
|
|
193
|
-
attributes=attributes,
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
logger.info("Model endpoint table updated", endpoint_id=endpoint_id)
|
|
197
|
-
|
|
198
|
-
def delete_model_endpoint(
|
|
199
|
-
self,
|
|
200
|
-
endpoint_id: str,
|
|
201
|
-
):
|
|
202
|
-
"""
|
|
203
|
-
Deletes the KV record of a given model endpoint id.
|
|
204
|
-
|
|
205
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
206
|
-
"""
|
|
207
|
-
|
|
208
|
-
self.client.kv.delete(
|
|
209
|
-
container=self.container,
|
|
210
|
-
table_path=self.path,
|
|
211
|
-
key=endpoint_id,
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
logger.info("Model endpoint table cleared", endpoint_id=endpoint_id)
|
|
215
|
-
|
|
216
|
-
def get_model_endpoint(
|
|
217
|
-
self,
|
|
218
|
-
endpoint_id: str = None,
|
|
219
|
-
start: str = "now-1h",
|
|
220
|
-
end: str = "now",
|
|
221
|
-
metrics: typing.List[str] = None,
|
|
222
|
-
feature_analysis: bool = False,
|
|
223
|
-
) -> mlrun.api.schemas.ModelEndpoint:
|
|
224
|
-
"""
|
|
225
|
-
Get a single model endpoint object. You can apply different time series metrics that will be added to the
|
|
226
|
-
result.
|
|
227
|
-
|
|
228
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
229
|
-
:param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
|
|
230
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
231
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
232
|
-
earliest time.
|
|
233
|
-
:param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
|
|
234
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
235
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
236
|
-
earliest time.
|
|
237
|
-
:param metrics: A list of metrics to return for the model endpoint. There are pre-defined metrics for
|
|
238
|
-
model endpoints such as predictions_per_second and latency_avg_5m but also custom
|
|
239
|
-
metrics defined by the user. Please note that these metrics are stored in the time
|
|
240
|
-
series DB and the results will be appeared under model_endpoint.spec.metrics.
|
|
241
|
-
:param feature_analysis: When True, the base feature statistics and current feature statistics will be added to
|
|
242
|
-
the output of the resulting object.
|
|
243
|
-
|
|
244
|
-
:return: A ModelEndpoint object.
|
|
245
|
-
"""
|
|
246
|
-
logger.info(
|
|
247
|
-
"Getting model endpoint record from kv",
|
|
248
|
-
endpoint_id=endpoint_id,
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
# Getting the raw data from the KV table
|
|
252
|
-
endpoint = self.client.kv.get(
|
|
253
|
-
container=self.container,
|
|
254
|
-
table_path=self.path,
|
|
255
|
-
key=endpoint_id,
|
|
256
|
-
raise_for_status=v3io.dataplane.RaiseForStatus.never,
|
|
257
|
-
access_key=self.access_key,
|
|
258
|
-
)
|
|
259
|
-
endpoint = endpoint.output.item
|
|
260
|
-
|
|
261
|
-
if not endpoint:
|
|
262
|
-
raise mlrun.errors.MLRunNotFoundError(f"Endpoint {endpoint_id} not found")
|
|
263
|
-
|
|
264
|
-
# Generate a model endpoint object from the model endpoint KV record
|
|
265
|
-
endpoint_obj = self._convert_into_model_endpoint_object(
|
|
266
|
-
endpoint, start, end, metrics, feature_analysis
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
return endpoint_obj
|
|
270
|
-
|
|
271
|
-
def _convert_into_model_endpoint_object(
|
|
272
|
-
self, endpoint, start, end, metrics, feature_analysis
|
|
273
|
-
):
|
|
274
|
-
"""
|
|
275
|
-
Create a ModelEndpoint object according to a provided endpoint record from the DB.
|
|
276
|
-
|
|
277
|
-
:param endpoint: KV record of model endpoint which need to be converted into a valid ModelEndpoint
|
|
278
|
-
object.
|
|
279
|
-
:param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
|
|
280
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
281
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
282
|
-
earliest time.
|
|
283
|
-
:param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
|
|
284
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
285
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
286
|
-
earliest time.
|
|
287
|
-
:param metrics: A list of metrics to return for the model endpoint. There are pre-defined metrics for
|
|
288
|
-
model endpoints such as predictions_per_second and latency_avg_5m but also custom
|
|
289
|
-
metrics defined by the user. Please note that these metrics are stored in the time
|
|
290
|
-
series DB and the results will be appeared under model_endpoint.spec.metrics.
|
|
291
|
-
:param feature_analysis: When True, the base feature statistics and current feature statistics will be added to
|
|
292
|
-
the output of the resulting object.
|
|
293
|
-
|
|
294
|
-
:return: A ModelEndpoint object.
|
|
295
|
-
"""
|
|
296
|
-
|
|
297
|
-
# Parse JSON values into a dictionary
|
|
298
|
-
feature_names = self._json_loads_if_not_none(endpoint.get("feature_names"))
|
|
299
|
-
label_names = self._json_loads_if_not_none(endpoint.get("label_names"))
|
|
300
|
-
feature_stats = self._json_loads_if_not_none(endpoint.get("feature_stats"))
|
|
301
|
-
current_stats = self._json_loads_if_not_none(endpoint.get("current_stats"))
|
|
302
|
-
children = self._json_loads_if_not_none(endpoint.get("children"))
|
|
303
|
-
monitor_configuration = self._json_loads_if_not_none(
|
|
304
|
-
endpoint.get("monitor_configuration")
|
|
305
|
-
)
|
|
306
|
-
endpoint_type = self._json_loads_if_not_none(endpoint.get("endpoint_type"))
|
|
307
|
-
children_uids = self._json_loads_if_not_none(endpoint.get("children_uids"))
|
|
308
|
-
labels = self._json_loads_if_not_none(endpoint.get("labels"))
|
|
309
|
-
|
|
310
|
-
# Convert into model endpoint object
|
|
311
|
-
endpoint_obj = mlrun.api.schemas.ModelEndpoint(
|
|
312
|
-
metadata=mlrun.api.schemas.ModelEndpointMetadata(
|
|
313
|
-
project=endpoint.get("project"),
|
|
314
|
-
labels=labels,
|
|
315
|
-
uid=endpoint.get("endpoint_id"),
|
|
316
|
-
),
|
|
317
|
-
spec=mlrun.api.schemas.ModelEndpointSpec(
|
|
318
|
-
function_uri=endpoint.get("function_uri"),
|
|
319
|
-
model=endpoint.get("model"),
|
|
320
|
-
model_class=endpoint.get("model_class"),
|
|
321
|
-
model_uri=endpoint.get("model_uri"),
|
|
322
|
-
feature_names=feature_names or None,
|
|
323
|
-
label_names=label_names or None,
|
|
324
|
-
stream_path=endpoint.get("stream_path"),
|
|
325
|
-
algorithm=endpoint.get("algorithm"),
|
|
326
|
-
monitor_configuration=monitor_configuration or None,
|
|
327
|
-
active=endpoint.get("active"),
|
|
328
|
-
monitoring_mode=endpoint.get("monitoring_mode"),
|
|
329
|
-
),
|
|
330
|
-
status=mlrun.api.schemas.ModelEndpointStatus(
|
|
331
|
-
state=endpoint.get("state") or None,
|
|
332
|
-
feature_stats=feature_stats or None,
|
|
333
|
-
current_stats=current_stats or None,
|
|
334
|
-
children=children or None,
|
|
335
|
-
first_request=endpoint.get("first_request"),
|
|
336
|
-
last_request=endpoint.get("last_request"),
|
|
337
|
-
accuracy=endpoint.get("accuracy"),
|
|
338
|
-
error_count=endpoint.get("error_count"),
|
|
339
|
-
drift_status=endpoint.get("drift_status"),
|
|
340
|
-
endpoint_type=endpoint_type or None,
|
|
341
|
-
children_uids=children_uids or None,
|
|
342
|
-
monitoring_feature_set_uri=endpoint.get("monitoring_feature_set_uri")
|
|
343
|
-
or None,
|
|
344
|
-
),
|
|
345
|
-
)
|
|
346
|
-
|
|
347
|
-
# If feature analysis was applied, add feature stats and current stats to the model endpoint result
|
|
348
|
-
if feature_analysis and feature_names:
|
|
349
|
-
endpoint_features = self.get_endpoint_features(
|
|
350
|
-
feature_names=feature_names,
|
|
351
|
-
feature_stats=feature_stats,
|
|
352
|
-
current_stats=current_stats,
|
|
353
|
-
)
|
|
354
|
-
if endpoint_features:
|
|
355
|
-
endpoint_obj.status.features = endpoint_features
|
|
356
|
-
# Add the latest drift measures results (calculated by the model monitoring batch)
|
|
357
|
-
drift_measures = self._json_loads_if_not_none(
|
|
358
|
-
endpoint.get("drift_measures")
|
|
359
|
-
)
|
|
360
|
-
endpoint_obj.status.drift_measures = drift_measures
|
|
361
|
-
|
|
362
|
-
# If time metrics were provided, retrieve the results from the time series DB
|
|
363
|
-
if metrics:
|
|
364
|
-
endpoint_metrics = self.get_endpoint_metrics(
|
|
365
|
-
endpoint_id=endpoint_obj.metadata.uid,
|
|
366
|
-
start=start,
|
|
367
|
-
end=end,
|
|
368
|
-
metrics=metrics,
|
|
369
|
-
)
|
|
370
|
-
if endpoint_metrics:
|
|
371
|
-
endpoint_obj.status.metrics = endpoint_metrics
|
|
372
|
-
|
|
373
|
-
return endpoint_obj
|
|
374
|
-
|
|
375
|
-
def _get_path_and_container(self):
|
|
376
|
-
"""Getting path and container based on the model monitoring configurations"""
|
|
377
|
-
path = mlrun.mlconf.model_endpoint_monitoring.store_prefixes.default.format(
|
|
378
|
-
project=self.project,
|
|
379
|
-
kind=mlrun.api.schemas.ModelMonitoringStoreKinds.ENDPOINTS,
|
|
380
|
-
)
|
|
381
|
-
(
|
|
382
|
-
_,
|
|
383
|
-
container,
|
|
384
|
-
path,
|
|
385
|
-
) = mlrun.utils.model_monitoring.parse_model_endpoint_store_prefix(path)
|
|
386
|
-
return path, container
|
|
387
|
-
|
|
388
|
-
def list_model_endpoints(
|
|
389
|
-
self, model: str, function: str, labels: typing.List, top_level: bool
|
|
390
|
-
):
|
|
391
|
-
"""
|
|
392
|
-
Returns a list of endpoint unique ids, supports filtering by model, function,
|
|
393
|
-
labels or top level. By default, when no filters are applied, all available endpoint ids for the given project
|
|
394
|
-
will be listed.
|
|
395
|
-
|
|
396
|
-
:param model: The name of the model to filter by.
|
|
397
|
-
:param function: The name of the function to filter by.
|
|
398
|
-
:param labels: A list of labels to filter by. Label filters work by either filtering a specific value
|
|
399
|
-
of a label (i.e. list("key==value")) or by looking for the existence of a given
|
|
400
|
-
key (i.e. "key").
|
|
401
|
-
:param top_level: If True will return only routers and endpoint that are NOT children of any router.
|
|
402
|
-
|
|
403
|
-
:return: List of model endpoints unique ids.
|
|
404
|
-
"""
|
|
405
|
-
|
|
406
|
-
# Retrieve the raw data from the KV table and get the endpoint ids
|
|
407
|
-
cursor = self.client.kv.new_cursor(
|
|
408
|
-
container=self.container,
|
|
409
|
-
table_path=self.path,
|
|
410
|
-
filter_expression=self.build_kv_cursor_filter_expression(
|
|
411
|
-
self.project,
|
|
412
|
-
function,
|
|
413
|
-
model,
|
|
414
|
-
labels,
|
|
415
|
-
top_level,
|
|
416
|
-
),
|
|
417
|
-
attribute_names=["endpoint_id"],
|
|
418
|
-
raise_for_status=v3io.dataplane.RaiseForStatus.never,
|
|
419
|
-
)
|
|
420
|
-
try:
|
|
421
|
-
items = cursor.all()
|
|
422
|
-
except Exception:
|
|
423
|
-
return []
|
|
424
|
-
|
|
425
|
-
# Create a list of model endpoints unique ids
|
|
426
|
-
uids = [item["endpoint_id"] for item in items]
|
|
427
|
-
|
|
428
|
-
return uids
|
|
429
|
-
|
|
430
|
-
def delete_model_endpoints_resources(
|
|
431
|
-
self, endpoints: mlrun.api.schemas.model_endpoints.ModelEndpointList
|
|
432
|
-
):
|
|
433
|
-
"""
|
|
434
|
-
Delete all model endpoints resources in both KV and the time series DB.
|
|
435
|
-
|
|
436
|
-
:param endpoints: An object of ModelEndpointList which is literally a list of model endpoints along with some
|
|
437
|
-
metadata. To get a standard list of model endpoints use ModelEndpointList.endpoints.
|
|
438
|
-
"""
|
|
439
|
-
|
|
440
|
-
# Delete model endpoint record from KV table
|
|
441
|
-
for endpoint in endpoints.endpoints:
|
|
442
|
-
self.delete_model_endpoint(
|
|
443
|
-
endpoint.metadata.uid,
|
|
444
|
-
)
|
|
445
|
-
|
|
446
|
-
# Delete remain records in the KV
|
|
447
|
-
all_records = self.client.kv.new_cursor(
|
|
448
|
-
container=self.container,
|
|
449
|
-
table_path=self.path,
|
|
450
|
-
raise_for_status=v3io.dataplane.RaiseForStatus.never,
|
|
451
|
-
).all()
|
|
452
|
-
|
|
453
|
-
all_records = [r["__name"] for r in all_records]
|
|
454
|
-
|
|
455
|
-
# Cleanup KV
|
|
456
|
-
for record in all_records:
|
|
457
|
-
self.client.kv.delete(
|
|
458
|
-
container=self.container,
|
|
459
|
-
table_path=self.path,
|
|
460
|
-
key=record,
|
|
461
|
-
raise_for_status=v3io.dataplane.RaiseForStatus.never,
|
|
462
|
-
)
|
|
463
|
-
|
|
464
|
-
# Cleanup TSDB
|
|
465
|
-
frames = mlrun.utils.v3io_clients.get_frames_client(
|
|
466
|
-
token=self.access_key,
|
|
467
|
-
address=mlrun.mlconf.v3io_framesd,
|
|
468
|
-
container=self.container,
|
|
469
|
-
)
|
|
470
|
-
|
|
471
|
-
# Generate the required tsdb paths
|
|
472
|
-
tsdb_path, filtered_path = self._generate_tsdb_paths()
|
|
473
|
-
|
|
474
|
-
# Delete time series DB resources
|
|
475
|
-
try:
|
|
476
|
-
frames.delete(
|
|
477
|
-
backend=model_monitoring_constants.StoreTarget.TSDB,
|
|
478
|
-
table=filtered_path,
|
|
479
|
-
if_missing=v3io_frames.frames_pb2.IGNORE,
|
|
480
|
-
)
|
|
481
|
-
except v3io_frames.errors.CreateError:
|
|
482
|
-
# Frames might raise an exception if schema file does not exist.
|
|
483
|
-
pass
|
|
484
|
-
|
|
485
|
-
# Final cleanup of tsdb path
|
|
486
|
-
tsdb_path.replace("://u", ":///u")
|
|
487
|
-
store, _ = mlrun.store_manager.get_or_create_store(tsdb_path)
|
|
488
|
-
store.rm(tsdb_path, recursive=True)
|
|
489
|
-
|
|
490
|
-
def _generate_tsdb_paths(self) -> typing.Tuple[str, str]:
|
|
491
|
-
"""Generate a short path to the TSDB resources and a filtered path for the frames object
|
|
492
|
-
|
|
493
|
-
:return: A tuple of:
|
|
494
|
-
[0] = Short path to the TSDB resources
|
|
495
|
-
[1] = Filtered path to TSDB events without schema and container
|
|
496
|
-
"""
|
|
497
|
-
# Full path for the time series DB events
|
|
498
|
-
full_path = (
|
|
499
|
-
mlrun.mlconf.model_endpoint_monitoring.store_prefixes.default.format(
|
|
500
|
-
project=self.project,
|
|
501
|
-
kind=mlrun.api.schemas.ModelMonitoringStoreKinds.EVENTS,
|
|
502
|
-
)
|
|
503
|
-
)
|
|
504
|
-
|
|
505
|
-
# Generate the main directory with the TSDB resources
|
|
506
|
-
tsdb_path = mlrun.utils.model_monitoring.parse_model_endpoint_project_prefix(
|
|
507
|
-
full_path, self.project
|
|
508
|
-
)
|
|
509
|
-
|
|
510
|
-
# Generate filtered path without schema and container as required by the frames object
|
|
511
|
-
(
|
|
512
|
-
_,
|
|
513
|
-
_,
|
|
514
|
-
filtered_path,
|
|
515
|
-
) = mlrun.utils.model_monitoring.parse_model_endpoint_store_prefix(full_path)
|
|
516
|
-
return tsdb_path, filtered_path
|
|
517
|
-
|
|
518
|
-
@staticmethod
|
|
519
|
-
def build_kv_cursor_filter_expression(
|
|
520
|
-
project: str,
|
|
521
|
-
function: str = None,
|
|
522
|
-
model: str = None,
|
|
523
|
-
labels: typing.List[str] = None,
|
|
524
|
-
top_level: bool = False,
|
|
525
|
-
) -> str:
|
|
526
|
-
"""
|
|
527
|
-
Convert the provided filters into a valid filter expression. The expected filter expression includes different
|
|
528
|
-
conditions, divided by ' AND '.
|
|
529
|
-
|
|
530
|
-
:param project: The name of the project.
|
|
531
|
-
:param model: The name of the model to filter by.
|
|
532
|
-
:param function: The name of the function to filter by.
|
|
533
|
-
:param labels: A list of labels to filter by. Label filters work by either filtering a specific value of
|
|
534
|
-
a label (i.e. list("key==value")) or by looking for the existence of a given
|
|
535
|
-
key (i.e. "key").
|
|
536
|
-
:param top_level: If True will return only routers and endpoint that are NOT children of any router.
|
|
537
|
-
|
|
538
|
-
:return: A valid filter expression as a string.
|
|
539
|
-
"""
|
|
540
|
-
|
|
541
|
-
if not project:
|
|
542
|
-
raise mlrun.errors.MLRunInvalidArgumentError("project can't be empty")
|
|
543
|
-
|
|
544
|
-
# Add project filter
|
|
545
|
-
filter_expression = [f"project=='{project}'"]
|
|
546
|
-
|
|
547
|
-
# Add function and model filters
|
|
548
|
-
if function:
|
|
549
|
-
filter_expression.append(f"function=='{function}'")
|
|
550
|
-
if model:
|
|
551
|
-
filter_expression.append(f"model=='{model}'")
|
|
552
|
-
|
|
553
|
-
# Add labels filters
|
|
554
|
-
if labels:
|
|
555
|
-
for label in labels:
|
|
556
|
-
|
|
557
|
-
if not label.startswith("_"):
|
|
558
|
-
label = f"_{label}"
|
|
559
|
-
|
|
560
|
-
if "=" in label:
|
|
561
|
-
lbl, value = list(map(lambda x: x.strip(), label.split("=")))
|
|
562
|
-
filter_expression.append(f"{lbl}=='{value}'")
|
|
563
|
-
else:
|
|
564
|
-
filter_expression.append(f"exists({label})")
|
|
565
|
-
|
|
566
|
-
# Apply top_level filter (remove endpoints that considered a child of a router)
|
|
567
|
-
if top_level:
|
|
568
|
-
filter_expression.append(
|
|
569
|
-
f"(endpoint_type=='{str(mlrun.utils.model_monitoring.EndpointType.NODE_EP.value)}' "
|
|
570
|
-
f"OR endpoint_type=='{str(mlrun.utils.model_monitoring.EndpointType.ROUTER.value)}')"
|
|
571
|
-
)
|
|
572
|
-
|
|
573
|
-
return " AND ".join(filter_expression)
|
|
574
|
-
|
|
575
|
-
@staticmethod
|
|
576
|
-
def flatten_model_endpoint_attributes(
|
|
577
|
-
endpoint: mlrun.api.schemas.ModelEndpoint,
|
|
578
|
-
) -> typing.Dict:
|
|
579
|
-
"""
|
|
580
|
-
Retrieving flatten structure of the model endpoint object.
|
|
581
|
-
|
|
582
|
-
:param endpoint: ModelEndpoint object that will be used for getting the attributes.
|
|
583
|
-
|
|
584
|
-
:return: A flat dictionary of attributes.
|
|
585
|
-
"""
|
|
586
|
-
|
|
587
|
-
# Prepare the data for the attributes dictionary
|
|
588
|
-
labels = endpoint.metadata.labels or {}
|
|
589
|
-
searchable_labels = {f"_{k}": v for k, v in labels.items()}
|
|
590
|
-
feature_names = endpoint.spec.feature_names or []
|
|
591
|
-
label_names = endpoint.spec.label_names or []
|
|
592
|
-
feature_stats = endpoint.status.feature_stats or {}
|
|
593
|
-
current_stats = endpoint.status.current_stats or {}
|
|
594
|
-
children = endpoint.status.children or []
|
|
595
|
-
endpoint_type = endpoint.status.endpoint_type or None
|
|
596
|
-
children_uids = endpoint.status.children_uids or []
|
|
597
|
-
|
|
598
|
-
# Fill the data. Note that because it is a flat dictionary, we use json.dumps() for encoding hierarchies
|
|
599
|
-
# such as current_stats or label_names
|
|
600
|
-
attributes = {
|
|
601
|
-
"endpoint_id": endpoint.metadata.uid,
|
|
602
|
-
"project": endpoint.metadata.project,
|
|
603
|
-
"function_uri": endpoint.spec.function_uri,
|
|
604
|
-
"model": endpoint.spec.model,
|
|
605
|
-
"model_class": endpoint.spec.model_class or "",
|
|
606
|
-
"labels": json.dumps(labels),
|
|
607
|
-
"model_uri": endpoint.spec.model_uri or "",
|
|
608
|
-
"stream_path": endpoint.spec.stream_path or "",
|
|
609
|
-
"active": endpoint.spec.active or "",
|
|
610
|
-
"monitoring_feature_set_uri": endpoint.status.monitoring_feature_set_uri
|
|
611
|
-
or "",
|
|
612
|
-
"monitoring_mode": endpoint.spec.monitoring_mode or "",
|
|
613
|
-
"state": endpoint.status.state or "",
|
|
614
|
-
"feature_stats": json.dumps(feature_stats),
|
|
615
|
-
"current_stats": json.dumps(current_stats),
|
|
616
|
-
"feature_names": json.dumps(feature_names),
|
|
617
|
-
"children": json.dumps(children),
|
|
618
|
-
"label_names": json.dumps(label_names),
|
|
619
|
-
"endpoint_type": json.dumps(endpoint_type),
|
|
620
|
-
"children_uids": json.dumps(children_uids),
|
|
621
|
-
**searchable_labels,
|
|
622
|
-
}
|
|
623
|
-
return attributes
|
|
624
|
-
|
|
625
|
-
@staticmethod
|
|
626
|
-
def _json_loads_if_not_none(field: typing.Any) -> typing.Any:
|
|
627
|
-
return json.loads(field) if field is not None else None
|
|
628
|
-
|
|
629
|
-
@staticmethod
|
|
630
|
-
def get_endpoint_features(
|
|
631
|
-
feature_names: typing.List[str],
|
|
632
|
-
feature_stats: dict = None,
|
|
633
|
-
current_stats: dict = None,
|
|
634
|
-
) -> typing.List[mlrun.api.schemas.Features]:
|
|
635
|
-
"""
|
|
636
|
-
Getting a new list of features that exist in feature_names along with their expected (feature_stats) and
|
|
637
|
-
actual (current_stats) stats. The expected stats were calculated during the creation of the model endpoint,
|
|
638
|
-
usually based on the data from the Model Artifact. The actual stats are based on the results from the latest
|
|
639
|
-
model monitoring batch job.
|
|
640
|
-
|
|
641
|
-
param feature_names: List of feature names.
|
|
642
|
-
param feature_stats: Dictionary of feature stats that were stored during the creation of the model endpoint
|
|
643
|
-
object.
|
|
644
|
-
param current_stats: Dictionary of the latest stats that were stored during the last run of the model monitoring
|
|
645
|
-
batch job.
|
|
646
|
-
|
|
647
|
-
return: List of feature objects. Each feature has a name, weight, expected values, and actual values. More info
|
|
648
|
-
can be found under mlrun.api.schemas.Features.
|
|
649
|
-
"""
|
|
650
|
-
|
|
651
|
-
# Initialize feature and current stats dictionaries
|
|
652
|
-
safe_feature_stats = feature_stats or {}
|
|
653
|
-
safe_current_stats = current_stats or {}
|
|
654
|
-
|
|
655
|
-
# Create feature object and add it to a general features list
|
|
656
|
-
features = []
|
|
657
|
-
for name in feature_names:
|
|
658
|
-
if feature_stats is not None and name not in feature_stats:
|
|
659
|
-
logger.warn("Feature missing from 'feature_stats'", name=name)
|
|
660
|
-
if current_stats is not None and name not in current_stats:
|
|
661
|
-
logger.warn("Feature missing from 'current_stats'", name=name)
|
|
662
|
-
f = mlrun.api.schemas.Features.new(
|
|
663
|
-
name, safe_feature_stats.get(name), safe_current_stats.get(name)
|
|
664
|
-
)
|
|
665
|
-
features.append(f)
|
|
666
|
-
return features
|
|
667
|
-
|
|
668
|
-
def get_endpoint_metrics(
|
|
669
|
-
self,
|
|
670
|
-
endpoint_id: str,
|
|
671
|
-
metrics: typing.List[str],
|
|
672
|
-
start: str = "now-1h",
|
|
673
|
-
end: str = "now",
|
|
674
|
-
) -> typing.Dict[str, mlrun.api.schemas.Metric]:
|
|
675
|
-
"""
|
|
676
|
-
Getting metrics from the time series DB. There are pre-defined metrics for model endpoints such as
|
|
677
|
-
predictions_per_second and latency_avg_5m but also custom metrics defined by the user.
|
|
678
|
-
|
|
679
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
680
|
-
:param metrics: A list of metrics to return for the model endpoint.
|
|
681
|
-
:param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
|
|
682
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
683
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
684
|
-
earliest time.
|
|
685
|
-
:param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
|
|
686
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
687
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
688
|
-
earliest time.
|
|
689
|
-
|
|
690
|
-
:return: A dictionary of metrics in which the key is a metric name and the value is a Metric object that also
|
|
691
|
-
includes the relevant timestamp. More details about the Metric object can be found under
|
|
692
|
-
mlrun.api.schemas.Metric.
|
|
693
|
-
"""
|
|
694
|
-
|
|
695
|
-
if not metrics:
|
|
696
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
697
|
-
"Metric names must be provided"
|
|
698
|
-
)
|
|
699
|
-
|
|
700
|
-
# Initialize metrics mapping dictionary
|
|
701
|
-
metrics_mapping = {}
|
|
702
|
-
|
|
703
|
-
# Getting the path for the time series DB
|
|
704
|
-
events_path = (
|
|
705
|
-
mlrun.mlconf.model_endpoint_monitoring.store_prefixes.default.format(
|
|
706
|
-
project=self.project,
|
|
707
|
-
kind=mlrun.api.schemas.ModelMonitoringStoreKinds.EVENTS,
|
|
708
|
-
)
|
|
709
|
-
)
|
|
710
|
-
(
|
|
711
|
-
_,
|
|
712
|
-
_,
|
|
713
|
-
events_path,
|
|
714
|
-
) = mlrun.utils.model_monitoring.parse_model_endpoint_store_prefix(events_path)
|
|
715
|
-
|
|
716
|
-
# Retrieve the raw data from the time series DB based on the provided metrics and time ranges
|
|
717
|
-
frames_client = mlrun.utils.v3io_clients.get_frames_client(
|
|
718
|
-
token=self.access_key,
|
|
719
|
-
address=mlrun.mlconf.v3io_framesd,
|
|
720
|
-
container=self.container,
|
|
721
|
-
)
|
|
722
|
-
|
|
723
|
-
try:
|
|
724
|
-
data = frames_client.read(
|
|
725
|
-
backend=model_monitoring_constants.StoreTarget.TSDB,
|
|
726
|
-
table=events_path,
|
|
727
|
-
columns=["endpoint_id", *metrics],
|
|
728
|
-
filter=f"endpoint_id=='{endpoint_id}'",
|
|
729
|
-
start=start,
|
|
730
|
-
end=end,
|
|
731
|
-
)
|
|
732
|
-
|
|
733
|
-
# Fill the metrics mapping dictionary with the metric name and values
|
|
734
|
-
data_dict = data.to_dict()
|
|
735
|
-
for metric in metrics:
|
|
736
|
-
metric_data = data_dict.get(metric)
|
|
737
|
-
if metric_data is None:
|
|
738
|
-
continue
|
|
739
|
-
|
|
740
|
-
values = [
|
|
741
|
-
(str(timestamp), value) for timestamp, value in metric_data.items()
|
|
742
|
-
]
|
|
743
|
-
metrics_mapping[metric] = mlrun.api.schemas.Metric(
|
|
744
|
-
name=metric, values=values
|
|
745
|
-
)
|
|
746
|
-
except v3io_frames.errors.ReadError:
|
|
747
|
-
logger.warn("Failed to read tsdb", endpoint=endpoint_id)
|
|
748
|
-
return metrics_mapping
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
class _ModelEndpointSQLStore(_ModelEndpointStore):
|
|
752
|
-
def write_model_endpoint(self, endpoint, update=True):
|
|
753
|
-
raise NotImplementedError
|
|
754
|
-
|
|
755
|
-
def update_model_endpoint(self, endpoint_id, attributes):
|
|
756
|
-
raise NotImplementedError
|
|
757
|
-
|
|
758
|
-
def delete_model_endpoint(self, endpoint_id):
|
|
759
|
-
raise NotImplementedError
|
|
760
|
-
|
|
761
|
-
def delete_model_endpoints_resources(
|
|
762
|
-
self, endpoints: mlrun.api.schemas.model_endpoints.ModelEndpointList
|
|
763
|
-
):
|
|
764
|
-
raise NotImplementedError
|
|
765
|
-
|
|
766
|
-
def get_model_endpoint(
|
|
767
|
-
self,
|
|
768
|
-
metrics: typing.List[str] = None,
|
|
769
|
-
start: str = "now-1h",
|
|
770
|
-
end: str = "now",
|
|
771
|
-
feature_analysis: bool = False,
|
|
772
|
-
endpoint_id: str = None,
|
|
773
|
-
):
|
|
774
|
-
raise NotImplementedError
|
|
775
|
-
|
|
776
|
-
def list_model_endpoints(
|
|
777
|
-
self, model: str, function: str, labels: typing.List, top_level: bool
|
|
778
|
-
):
|
|
779
|
-
raise NotImplementedError
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
class ModelEndpointStoreType(enum.Enum):
|
|
783
|
-
"""Enum class to handle the different store type values for saving a model endpoint record."""
|
|
784
|
-
|
|
785
|
-
kv = "kv"
|
|
786
|
-
sql = "sql"
|
|
787
|
-
|
|
788
|
-
def to_endpoint_target(
|
|
789
|
-
self, project: str, access_key: str = None
|
|
790
|
-
) -> _ModelEndpointStore:
|
|
791
|
-
"""
|
|
792
|
-
Return a ModelEndpointStore object based on the provided enum value.
|
|
793
|
-
|
|
794
|
-
:param project: The name of the project.
|
|
795
|
-
:param access_key: Access key with permission to the DB table. Note that if access key is None and the
|
|
796
|
-
endpoint target is from type KV then the access key will be retrieved from the environment
|
|
797
|
-
variable.
|
|
798
|
-
|
|
799
|
-
:return: ModelEndpointStore object.
|
|
800
|
-
|
|
801
|
-
"""
|
|
802
|
-
|
|
803
|
-
if self.value == ModelEndpointStoreType.kv.value:
|
|
804
|
-
|
|
805
|
-
# Get V3IO access key from env
|
|
806
|
-
access_key = (
|
|
807
|
-
mlrun.mlconf.get_v3io_access_key() if access_key is None else access_key
|
|
808
|
-
)
|
|
809
|
-
|
|
810
|
-
return _ModelEndpointKVStore(project=project, access_key=access_key)
|
|
811
|
-
|
|
812
|
-
# Assuming SQL store target if store type is not KV.
|
|
813
|
-
# Update these lines once there are more than two store target types.
|
|
814
|
-
return _ModelEndpointSQLStore(project=project)
|
|
815
|
-
|
|
816
|
-
@classmethod
|
|
817
|
-
def _missing_(cls, value: typing.Any):
|
|
818
|
-
"""A lookup function to handle an invalid value.
|
|
819
|
-
:param value: Provided enum (invalid) value.
|
|
820
|
-
"""
|
|
821
|
-
valid_values = list(cls.__members__.keys())
|
|
822
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
823
|
-
"%r is not a valid %s, please choose a valid value: %s."
|
|
824
|
-
% (value, cls.__name__, valid_values)
|
|
825
|
-
)
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
def get_model_endpoint_target(
|
|
829
|
-
project: str, access_key: str = None
|
|
830
|
-
) -> _ModelEndpointStore:
|
|
831
|
-
"""
|
|
832
|
-
Getting the DB target type based on mlrun.config.model_endpoint_monitoring.store_type.
|
|
833
|
-
|
|
834
|
-
:param project: The name of the project.
|
|
835
|
-
:param access_key: Access key with permission to the DB table.
|
|
836
|
-
|
|
837
|
-
:return: ModelEndpointStore object. Using this object, the user can apply different operations on the
|
|
838
|
-
model endpoint record such as write, update, get and delete.
|
|
839
|
-
"""
|
|
840
|
-
|
|
841
|
-
# Get store type value from ModelEndpointStoreType enum class
|
|
842
|
-
model_endpoint_store_type = ModelEndpointStoreType(
|
|
843
|
-
mlrun.mlconf.model_endpoint_monitoring.store_type
|
|
844
|
-
)
|
|
845
|
-
|
|
846
|
-
# Convert into model endpoint store target object
|
|
847
|
-
return model_endpoint_store_type.to_endpoint_target(project, access_key)
|