mlrun 1.3.3__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.3.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.3.dist-info/RECORD +0 -381
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
mlrun/api/crud/logs.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2023 Iguazio
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -21,13 +21,13 @@ from http import HTTPStatus
|
|
|
21
21
|
from fastapi.concurrency import run_in_threadpool
|
|
22
22
|
from sqlalchemy.orm import Session
|
|
23
23
|
|
|
24
|
-
import mlrun.api.schemas
|
|
25
24
|
import mlrun.api.utils.clients.log_collector as log_collector
|
|
25
|
+
import mlrun.api.utils.singletons.k8s
|
|
26
|
+
import mlrun.common.schemas
|
|
26
27
|
import mlrun.utils.singleton
|
|
27
28
|
from mlrun.api.api.utils import log_and_raise, log_path, project_logs_path
|
|
28
29
|
from mlrun.api.constants import LogSources
|
|
29
30
|
from mlrun.api.utils.singletons.db import get_db
|
|
30
|
-
from mlrun.api.utils.singletons.k8s import get_k8s
|
|
31
31
|
from mlrun.runtimes.constants import PodPhases
|
|
32
32
|
from mlrun.utils import logger
|
|
33
33
|
|
|
@@ -85,7 +85,7 @@ class Logs(
|
|
|
85
85
|
log_stream = None
|
|
86
86
|
if (
|
|
87
87
|
mlrun.mlconf.log_collector.mode
|
|
88
|
-
== mlrun.
|
|
88
|
+
== mlrun.common.schemas.LogsCollectorMode.best_effort
|
|
89
89
|
and source == LogSources.AUTO
|
|
90
90
|
):
|
|
91
91
|
try:
|
|
@@ -112,7 +112,7 @@ class Logs(
|
|
|
112
112
|
)
|
|
113
113
|
elif (
|
|
114
114
|
mlrun.mlconf.log_collector.mode
|
|
115
|
-
== mlrun.
|
|
115
|
+
== mlrun.common.schemas.LogsCollectorMode.sidecar
|
|
116
116
|
and source == LogSources.AUTO
|
|
117
117
|
):
|
|
118
118
|
log_stream = self._get_logs_from_logs_collector(
|
|
@@ -123,7 +123,7 @@ class Logs(
|
|
|
123
123
|
)
|
|
124
124
|
elif (
|
|
125
125
|
mlrun.mlconf.log_collector.mode
|
|
126
|
-
== mlrun.
|
|
126
|
+
== mlrun.common.schemas.LogsCollectorMode.legacy
|
|
127
127
|
or source != LogSources.AUTO
|
|
128
128
|
):
|
|
129
129
|
log_stream = self._get_logs_legacy_method_generator_wrapper(
|
|
@@ -178,10 +178,12 @@ class Logs(
|
|
|
178
178
|
fp.seek(offset)
|
|
179
179
|
log_contents = fp.read(size)
|
|
180
180
|
elif source in [LogSources.AUTO, LogSources.K8S]:
|
|
181
|
-
k8s =
|
|
181
|
+
k8s = mlrun.api.utils.singletons.k8s.get_k8s_helper()
|
|
182
182
|
if k8s and k8s.is_running_inside_kubernetes_cluster():
|
|
183
183
|
run_kind = run.get("metadata", {}).get("labels", {}).get("kind")
|
|
184
|
-
pods =
|
|
184
|
+
pods = mlrun.api.utils.singletons.k8s.get_k8s_helper().get_logger_pods(
|
|
185
|
+
project, uid, run_kind
|
|
186
|
+
)
|
|
185
187
|
if pods:
|
|
186
188
|
if len(pods) > 1:
|
|
187
189
|
|
|
@@ -195,7 +197,7 @@ class Logs(
|
|
|
195
197
|
)
|
|
196
198
|
pod, pod_phase = list(pods.items())[0]
|
|
197
199
|
if pod_phase != PodPhases.pending:
|
|
198
|
-
resp =
|
|
200
|
+
resp = mlrun.api.utils.singletons.k8s.get_k8s_helper().logs(pod)
|
|
199
201
|
if resp:
|
|
200
202
|
if size == -1:
|
|
201
203
|
log_contents = resp.encode()[offset:]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2023 Iguazio
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
#
|
|
15
|
+
# flake8: noqa: F401 - this is until we take care of the F401 violations with respect to __all__ & sphinx
|
|
15
16
|
|
|
16
|
-
from .
|
|
17
|
-
from .model_endpoints import ModelEndpoints # noqa: F401
|
|
17
|
+
from .model_endpoints import ModelEndpoints
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
# Copyright 2023 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
|
+
from typing import Any, Dict, List, Optional, Set
|
|
17
|
+
|
|
18
|
+
import numpy as np
|
|
19
|
+
import pandas as pd
|
|
20
|
+
from fastapi.concurrency import run_in_threadpool
|
|
21
|
+
from sqlalchemy.orm import Session
|
|
22
|
+
|
|
23
|
+
import mlrun.api.crud
|
|
24
|
+
import mlrun.api.utils.auth.verifier
|
|
25
|
+
import mlrun.common.model_monitoring
|
|
26
|
+
import mlrun.common.schemas
|
|
27
|
+
from mlrun.api.utils.singletons.project_member import get_project_member
|
|
28
|
+
from mlrun.errors import MLRunBadRequestError
|
|
29
|
+
from mlrun.utils import config, logger
|
|
30
|
+
from mlrun.utils.model_monitoring import parse_model_endpoint_store_prefix
|
|
31
|
+
from mlrun.utils.v3io_clients import get_frames_client
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def grafana_list_projects(
|
|
35
|
+
db_session: Session,
|
|
36
|
+
auth_info: mlrun.common.schemas.AuthInfo,
|
|
37
|
+
query_parameters: Dict[str, str],
|
|
38
|
+
) -> List[str]:
|
|
39
|
+
"""
|
|
40
|
+
List available project names. Will be used as a filter in each grafana dashboard.
|
|
41
|
+
|
|
42
|
+
:param db_session: A session that manages the current dialog with the database.
|
|
43
|
+
:param auth_info: The auth info of the request.
|
|
44
|
+
:param query_parameters: Dictionary of query parameters attached to the request. Note that this parameter is
|
|
45
|
+
required by the API even though it is not being used in this function.
|
|
46
|
+
|
|
47
|
+
:return: List of available project names.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
projects_output = get_project_member().list_projects(
|
|
51
|
+
db_session,
|
|
52
|
+
format_=mlrun.common.schemas.ProjectsFormat.name_only,
|
|
53
|
+
leader_session=auth_info.session,
|
|
54
|
+
)
|
|
55
|
+
return projects_output.projects
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# The following functions were not removed due to backward compatibility that is related to iguazio version <= 3.5.2
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
async def grafana_list_endpoints(
|
|
62
|
+
body: Dict[str, Any],
|
|
63
|
+
query_parameters: Dict[str, str],
|
|
64
|
+
auth_info: mlrun.common.schemas.AuthInfo,
|
|
65
|
+
) -> List[mlrun.common.schemas.GrafanaTable]:
|
|
66
|
+
project = query_parameters.get("project")
|
|
67
|
+
|
|
68
|
+
# Filters
|
|
69
|
+
model = query_parameters.get("model", None)
|
|
70
|
+
function = query_parameters.get("function", None)
|
|
71
|
+
labels = query_parameters.get("labels", "")
|
|
72
|
+
labels = labels.split(",") if labels else []
|
|
73
|
+
|
|
74
|
+
# Metrics to include
|
|
75
|
+
metrics = query_parameters.get("metrics", "")
|
|
76
|
+
metrics = metrics.split(",") if metrics else []
|
|
77
|
+
|
|
78
|
+
# Time range for metrics
|
|
79
|
+
start = body.get("rangeRaw", {}).get("start", "now-1h")
|
|
80
|
+
end = body.get("rangeRaw", {}).get("end", "now")
|
|
81
|
+
|
|
82
|
+
# Endpoint type filter - will be used to filter the router models
|
|
83
|
+
filter_router = query_parameters.get("filter_router", None)
|
|
84
|
+
|
|
85
|
+
if project:
|
|
86
|
+
await mlrun.api.utils.auth.verifier.AuthVerifier().query_project_permissions(
|
|
87
|
+
project,
|
|
88
|
+
mlrun.common.schemas.AuthorizationAction.read,
|
|
89
|
+
auth_info,
|
|
90
|
+
)
|
|
91
|
+
endpoint_list = await run_in_threadpool(
|
|
92
|
+
mlrun.api.crud.ModelEndpoints().list_model_endpoints,
|
|
93
|
+
auth_info=auth_info,
|
|
94
|
+
project=project,
|
|
95
|
+
model=model,
|
|
96
|
+
function=function,
|
|
97
|
+
labels=labels,
|
|
98
|
+
metrics=metrics,
|
|
99
|
+
start=start,
|
|
100
|
+
end=end,
|
|
101
|
+
)
|
|
102
|
+
allowed_endpoints = await mlrun.api.utils.auth.verifier.AuthVerifier().filter_project_resources_by_permissions(
|
|
103
|
+
mlrun.common.schemas.AuthorizationResourceTypes.model_endpoint,
|
|
104
|
+
endpoint_list.endpoints,
|
|
105
|
+
lambda _endpoint: (
|
|
106
|
+
_endpoint.metadata.project,
|
|
107
|
+
_endpoint.metadata.uid,
|
|
108
|
+
),
|
|
109
|
+
auth_info,
|
|
110
|
+
)
|
|
111
|
+
endpoint_list.endpoints = allowed_endpoints
|
|
112
|
+
|
|
113
|
+
columns = [
|
|
114
|
+
mlrun.common.schemas.GrafanaColumn(text="endpoint_id", type="string"),
|
|
115
|
+
mlrun.common.schemas.GrafanaColumn(text="endpoint_function", type="string"),
|
|
116
|
+
mlrun.common.schemas.GrafanaColumn(text="endpoint_model", type="string"),
|
|
117
|
+
mlrun.common.schemas.GrafanaColumn(text="endpoint_model_class", type="string"),
|
|
118
|
+
mlrun.common.schemas.GrafanaColumn(text="first_request", type="time"),
|
|
119
|
+
mlrun.common.schemas.GrafanaColumn(text="last_request", type="time"),
|
|
120
|
+
mlrun.common.schemas.GrafanaColumn(text="accuracy", type="number"),
|
|
121
|
+
mlrun.common.schemas.GrafanaColumn(text="error_count", type="number"),
|
|
122
|
+
mlrun.common.schemas.GrafanaColumn(text="drift_status", type="number"),
|
|
123
|
+
mlrun.common.schemas.GrafanaColumn(
|
|
124
|
+
text="predictions_per_second", type="number"
|
|
125
|
+
),
|
|
126
|
+
mlrun.common.schemas.GrafanaColumn(text="latency_avg_1h", type="number"),
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
table = mlrun.common.schemas.GrafanaTable(columns=columns)
|
|
130
|
+
for endpoint in endpoint_list.endpoints:
|
|
131
|
+
if (
|
|
132
|
+
filter_router
|
|
133
|
+
and endpoint.status.endpoint_type
|
|
134
|
+
== mlrun.common.model_monitoring.EndpointType.ROUTER
|
|
135
|
+
):
|
|
136
|
+
continue
|
|
137
|
+
row = [
|
|
138
|
+
endpoint.metadata.uid,
|
|
139
|
+
endpoint.spec.function_uri,
|
|
140
|
+
endpoint.spec.model,
|
|
141
|
+
endpoint.spec.model_class,
|
|
142
|
+
endpoint.status.first_request,
|
|
143
|
+
endpoint.status.last_request,
|
|
144
|
+
"N/A", # Leaving here for backwards compatibility
|
|
145
|
+
endpoint.status.error_count,
|
|
146
|
+
endpoint.status.drift_status,
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
if (
|
|
150
|
+
endpoint.status.metrics
|
|
151
|
+
and mlrun.common.model_monitoring.EventKeyMetrics.GENERIC
|
|
152
|
+
in endpoint.status.metrics
|
|
153
|
+
):
|
|
154
|
+
row.extend(
|
|
155
|
+
[
|
|
156
|
+
endpoint.status.metrics[
|
|
157
|
+
mlrun.common.model_monitoring.EventKeyMetrics.GENERIC
|
|
158
|
+
][
|
|
159
|
+
mlrun.common.model_monitoring.EventLiveStats.PREDICTIONS_PER_SECOND
|
|
160
|
+
],
|
|
161
|
+
endpoint.status.metrics[
|
|
162
|
+
mlrun.common.model_monitoring.EventKeyMetrics.GENERIC
|
|
163
|
+
][mlrun.common.model_monitoring.EventLiveStats.LATENCY_AVG_1H],
|
|
164
|
+
]
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
table.add_row(*row)
|
|
168
|
+
|
|
169
|
+
return [table]
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
async def grafana_individual_feature_analysis(
|
|
173
|
+
body: Dict[str, Any],
|
|
174
|
+
query_parameters: Dict[str, str],
|
|
175
|
+
auth_info: mlrun.common.schemas.AuthInfo,
|
|
176
|
+
):
|
|
177
|
+
endpoint_id = query_parameters.get("endpoint_id")
|
|
178
|
+
project = query_parameters.get("project")
|
|
179
|
+
await mlrun.api.utils.auth.verifier.AuthVerifier().query_project_resource_permissions(
|
|
180
|
+
mlrun.common.schemas.AuthorizationResourceTypes.model_endpoint,
|
|
181
|
+
project,
|
|
182
|
+
endpoint_id,
|
|
183
|
+
mlrun.common.schemas.AuthorizationAction.read,
|
|
184
|
+
auth_info,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
endpoint = await run_in_threadpool(
|
|
188
|
+
mlrun.api.crud.ModelEndpoints().get_model_endpoint,
|
|
189
|
+
auth_info=auth_info,
|
|
190
|
+
project=project,
|
|
191
|
+
endpoint_id=endpoint_id,
|
|
192
|
+
feature_analysis=True,
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
# Load JSON data from KV, make sure not to fail if a field is missing
|
|
196
|
+
feature_stats = endpoint.status.feature_stats or {}
|
|
197
|
+
current_stats = endpoint.status.current_stats or {}
|
|
198
|
+
drift_measures = endpoint.status.drift_measures or {}
|
|
199
|
+
|
|
200
|
+
table = mlrun.common.schemas.GrafanaTable(
|
|
201
|
+
columns=[
|
|
202
|
+
mlrun.common.schemas.GrafanaColumn(text="feature_name", type="string"),
|
|
203
|
+
mlrun.common.schemas.GrafanaColumn(text="actual_min", type="number"),
|
|
204
|
+
mlrun.common.schemas.GrafanaColumn(text="actual_mean", type="number"),
|
|
205
|
+
mlrun.common.schemas.GrafanaColumn(text="actual_max", type="number"),
|
|
206
|
+
mlrun.common.schemas.GrafanaColumn(text="expected_min", type="number"),
|
|
207
|
+
mlrun.common.schemas.GrafanaColumn(text="expected_mean", type="number"),
|
|
208
|
+
mlrun.common.schemas.GrafanaColumn(text="expected_max", type="number"),
|
|
209
|
+
mlrun.common.schemas.GrafanaColumn(text="tvd", type="number"),
|
|
210
|
+
mlrun.common.schemas.GrafanaColumn(text="hellinger", type="number"),
|
|
211
|
+
mlrun.common.schemas.GrafanaColumn(text="kld", type="number"),
|
|
212
|
+
]
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
for feature, base_stat in feature_stats.items():
|
|
216
|
+
current_stat = current_stats.get(feature, {})
|
|
217
|
+
drift_measure = drift_measures.get(feature, {})
|
|
218
|
+
|
|
219
|
+
table.add_row(
|
|
220
|
+
feature,
|
|
221
|
+
current_stat.get("min"),
|
|
222
|
+
current_stat.get("mean"),
|
|
223
|
+
current_stat.get("max"),
|
|
224
|
+
base_stat.get("min"),
|
|
225
|
+
base_stat.get("mean"),
|
|
226
|
+
base_stat.get("max"),
|
|
227
|
+
drift_measure.get("tvd"),
|
|
228
|
+
drift_measure.get("hellinger"),
|
|
229
|
+
drift_measure.get("kld"),
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
return [table]
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
async def grafana_overall_feature_analysis(
|
|
236
|
+
body: Dict[str, Any],
|
|
237
|
+
query_parameters: Dict[str, str],
|
|
238
|
+
auth_info: mlrun.common.schemas.AuthInfo,
|
|
239
|
+
):
|
|
240
|
+
endpoint_id = query_parameters.get("endpoint_id")
|
|
241
|
+
project = query_parameters.get("project")
|
|
242
|
+
await mlrun.api.utils.auth.verifier.AuthVerifier().query_project_resource_permissions(
|
|
243
|
+
mlrun.common.schemas.AuthorizationResourceTypes.model_endpoint,
|
|
244
|
+
project,
|
|
245
|
+
endpoint_id,
|
|
246
|
+
mlrun.common.schemas.AuthorizationAction.read,
|
|
247
|
+
auth_info,
|
|
248
|
+
)
|
|
249
|
+
endpoint = await run_in_threadpool(
|
|
250
|
+
mlrun.api.crud.ModelEndpoints().get_model_endpoint,
|
|
251
|
+
auth_info=auth_info,
|
|
252
|
+
project=project,
|
|
253
|
+
endpoint_id=endpoint_id,
|
|
254
|
+
feature_analysis=True,
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
table = mlrun.common.schemas.GrafanaTable(
|
|
258
|
+
columns=[
|
|
259
|
+
mlrun.common.schemas.GrafanaNumberColumn(text="tvd_sum"),
|
|
260
|
+
mlrun.common.schemas.GrafanaNumberColumn(text="tvd_mean"),
|
|
261
|
+
mlrun.common.schemas.GrafanaNumberColumn(text="hellinger_sum"),
|
|
262
|
+
mlrun.common.schemas.GrafanaNumberColumn(text="hellinger_mean"),
|
|
263
|
+
mlrun.common.schemas.GrafanaNumberColumn(text="kld_sum"),
|
|
264
|
+
mlrun.common.schemas.GrafanaNumberColumn(text="kld_mean"),
|
|
265
|
+
]
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
if endpoint.status.drift_measures:
|
|
269
|
+
table.add_row(
|
|
270
|
+
endpoint.status.drift_measures.get("tvd_sum"),
|
|
271
|
+
endpoint.status.drift_measures.get("tvd_mean"),
|
|
272
|
+
endpoint.status.drift_measures.get("hellinger_sum"),
|
|
273
|
+
endpoint.status.drift_measures.get("hellinger_mean"),
|
|
274
|
+
endpoint.status.drift_measures.get("kld_sum"),
|
|
275
|
+
endpoint.status.drift_measures.get("kld_mean"),
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
return [table]
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
async def grafana_incoming_features(
|
|
282
|
+
body: Dict[str, Any],
|
|
283
|
+
query_parameters: Dict[str, str],
|
|
284
|
+
auth_info: mlrun.common.schemas.AuthInfo,
|
|
285
|
+
):
|
|
286
|
+
endpoint_id = query_parameters.get("endpoint_id")
|
|
287
|
+
project = query_parameters.get("project")
|
|
288
|
+
start = body.get("rangeRaw", {}).get("from", "now-1h")
|
|
289
|
+
end = body.get("rangeRaw", {}).get("to", "now")
|
|
290
|
+
|
|
291
|
+
await mlrun.api.utils.auth.verifier.AuthVerifier().query_project_resource_permissions(
|
|
292
|
+
mlrun.common.schemas.AuthorizationResourceTypes.model_endpoint,
|
|
293
|
+
project,
|
|
294
|
+
endpoint_id,
|
|
295
|
+
mlrun.common.schemas.AuthorizationAction.read,
|
|
296
|
+
auth_info,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
endpoint = await run_in_threadpool(
|
|
300
|
+
mlrun.api.crud.ModelEndpoints().get_model_endpoint,
|
|
301
|
+
auth_info=auth_info,
|
|
302
|
+
project=project,
|
|
303
|
+
endpoint_id=endpoint_id,
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
time_series = []
|
|
307
|
+
|
|
308
|
+
feature_names = endpoint.spec.feature_names
|
|
309
|
+
|
|
310
|
+
if not feature_names:
|
|
311
|
+
logger.warn(
|
|
312
|
+
"'feature_names' is either missing or not initialized in endpoint record",
|
|
313
|
+
endpoint_id=endpoint.metadata.uid,
|
|
314
|
+
)
|
|
315
|
+
return time_series
|
|
316
|
+
|
|
317
|
+
path = config.model_endpoint_monitoring.store_prefixes.default.format(
|
|
318
|
+
project=project, kind=mlrun.common.schemas.ModelMonitoringStoreKinds.EVENTS
|
|
319
|
+
)
|
|
320
|
+
_, container, path = parse_model_endpoint_store_prefix(path)
|
|
321
|
+
|
|
322
|
+
client = get_frames_client(
|
|
323
|
+
token=auth_info.data_session,
|
|
324
|
+
address=config.v3io_framesd,
|
|
325
|
+
container=container,
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
data: pd.DataFrame = await run_in_threadpool(
|
|
329
|
+
client.read,
|
|
330
|
+
backend="tsdb",
|
|
331
|
+
table=path,
|
|
332
|
+
columns=feature_names,
|
|
333
|
+
filter=f"endpoint_id=='{endpoint_id}'",
|
|
334
|
+
start=start,
|
|
335
|
+
end=end,
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
data.drop(["endpoint_id"], axis=1, inplace=True, errors="ignore")
|
|
339
|
+
data.index = data.index.astype(np.int64) // 10**6
|
|
340
|
+
|
|
341
|
+
for feature, indexed_values in data.to_dict().items():
|
|
342
|
+
target = mlrun.common.schemas.GrafanaTimeSeriesTarget(target=feature)
|
|
343
|
+
for index, value in indexed_values.items():
|
|
344
|
+
data_point = mlrun.common.schemas.GrafanaDataPoint(
|
|
345
|
+
value=float(value), timestamp=index
|
|
346
|
+
)
|
|
347
|
+
target.add_data_point(data_point)
|
|
348
|
+
time_series.append(target)
|
|
349
|
+
|
|
350
|
+
return time_series
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def parse_query_parameters(request_body: Dict[str, Any]) -> Dict[str, str]:
|
|
354
|
+
"""
|
|
355
|
+
This function searches for the target field in Grafana's SimpleJson json. Once located, the target string is
|
|
356
|
+
parsed by splitting on semi-colons (;). Each part in the resulting list is then split by an equal sign (=) to be
|
|
357
|
+
read as key-value pairs.
|
|
358
|
+
"""
|
|
359
|
+
|
|
360
|
+
# Try to get the target
|
|
361
|
+
targets = request_body.get("targets", [])
|
|
362
|
+
|
|
363
|
+
if len(targets) > 1:
|
|
364
|
+
logger.warn(
|
|
365
|
+
f"The 'targets' list contains more than one element ({len(targets)}), all targets except the first one are "
|
|
366
|
+
f"ignored."
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
target_obj = targets[0] if targets else {}
|
|
370
|
+
target_query = target_obj.get("target") if target_obj else ""
|
|
371
|
+
|
|
372
|
+
if not target_query:
|
|
373
|
+
raise MLRunBadRequestError(f"Target missing in request body:\n {request_body}")
|
|
374
|
+
|
|
375
|
+
parameters = _parse_parameters(target_query)
|
|
376
|
+
|
|
377
|
+
return parameters
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def parse_search_parameters(request_body: Dict[str, Any]) -> Dict[str, str]:
|
|
381
|
+
"""
|
|
382
|
+
This function searches for the target field in Grafana's SimpleJson json. Once located, the target string is
|
|
383
|
+
parsed by splitting on semi-colons (;). Each part in the resulting list is then split by an equal sign (=) to be
|
|
384
|
+
read as key-value pairs.
|
|
385
|
+
"""
|
|
386
|
+
|
|
387
|
+
# Try to get the target
|
|
388
|
+
target = request_body.get("target")
|
|
389
|
+
|
|
390
|
+
if not target:
|
|
391
|
+
raise MLRunBadRequestError(f"Target missing in request body:\n {request_body}")
|
|
392
|
+
|
|
393
|
+
parameters = _parse_parameters(target)
|
|
394
|
+
|
|
395
|
+
return parameters
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def _parse_parameters(target_query):
|
|
399
|
+
parameters = {}
|
|
400
|
+
for query in filter(lambda q: q, target_query.split(";")):
|
|
401
|
+
query_parts = query.split("=")
|
|
402
|
+
if len(query_parts) < 2:
|
|
403
|
+
raise MLRunBadRequestError(
|
|
404
|
+
f"Query must contain both query key and query value. Expected query_key=query_value, found {query} "
|
|
405
|
+
f"instead."
|
|
406
|
+
)
|
|
407
|
+
parameters[query_parts[0]] = query_parts[1]
|
|
408
|
+
return parameters
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def drop_grafana_escape_chars(query_parameters: Dict[str, str]):
|
|
412
|
+
query_parameters = dict(query_parameters)
|
|
413
|
+
endpoint_id = query_parameters.get("endpoint_id")
|
|
414
|
+
if endpoint_id is not None:
|
|
415
|
+
query_parameters["endpoint_id"] = endpoint_id.replace("\\", "")
|
|
416
|
+
return query_parameters
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def validate_query_parameters(
|
|
420
|
+
query_parameters: Dict[str, str], supported_endpoints: Optional[Set[str]] = None
|
|
421
|
+
):
|
|
422
|
+
"""Validates the parameters sent via Grafana's SimpleJson query"""
|
|
423
|
+
if "target_endpoint" not in query_parameters:
|
|
424
|
+
raise MLRunBadRequestError(
|
|
425
|
+
f"Expected 'target_endpoint' field in query, found {query_parameters} instead"
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
if (
|
|
429
|
+
supported_endpoints is not None
|
|
430
|
+
and query_parameters["target_endpoint"] not in supported_endpoints
|
|
431
|
+
):
|
|
432
|
+
raise MLRunBadRequestError(
|
|
433
|
+
f"{query_parameters['target_endpoint']} unsupported in query parameters: {query_parameters}. "
|
|
434
|
+
f"Currently supports: {','.join(supported_endpoints)}"
|
|
435
|
+
)
|