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
|
@@ -0,0 +1,149 @@
|
|
|
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
|
+
import typing
|
|
16
|
+
|
|
17
|
+
import sqlalchemy.orm
|
|
18
|
+
|
|
19
|
+
import mlrun.api.api.utils
|
|
20
|
+
import mlrun.api.db.sqldb.db
|
|
21
|
+
import mlrun.api.utils.scheduler
|
|
22
|
+
import mlrun.api.utils.singletons.db
|
|
23
|
+
import mlrun.api.utils.singletons.scheduler
|
|
24
|
+
import mlrun.common.schemas
|
|
25
|
+
import mlrun.utils.singleton
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Notifications(
|
|
29
|
+
metaclass=mlrun.utils.singleton.Singleton,
|
|
30
|
+
):
|
|
31
|
+
def store_run_notifications(
|
|
32
|
+
self,
|
|
33
|
+
session: sqlalchemy.orm.Session,
|
|
34
|
+
notification_objects: typing.List[mlrun.model.Notification],
|
|
35
|
+
run_uid: str,
|
|
36
|
+
project: str = None,
|
|
37
|
+
):
|
|
38
|
+
project = project or mlrun.mlconf.default_project
|
|
39
|
+
notification_objects_to_store = (
|
|
40
|
+
mlrun.api.api.utils.validate_and_mask_notification_list(
|
|
41
|
+
notification_objects, run_uid, project
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
mlrun.api.utils.singletons.db.get_db().store_run_notifications(
|
|
46
|
+
session, notification_objects_to_store, run_uid, project
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
def list_run_notifications(
|
|
50
|
+
self,
|
|
51
|
+
session: sqlalchemy.orm.Session,
|
|
52
|
+
run_uid: str,
|
|
53
|
+
project: str = "",
|
|
54
|
+
) -> typing.List[mlrun.model.Notification]:
|
|
55
|
+
project = project or mlrun.mlconf.default_project
|
|
56
|
+
return mlrun.api.utils.singletons.db.get_db().list_run_notifications(
|
|
57
|
+
session, run_uid, project
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
def delete_run_notifications(
|
|
61
|
+
self,
|
|
62
|
+
session: sqlalchemy.orm.Session,
|
|
63
|
+
name: str = None,
|
|
64
|
+
run_uid: str = None,
|
|
65
|
+
project: str = None,
|
|
66
|
+
):
|
|
67
|
+
project = project or mlrun.mlconf.default_project
|
|
68
|
+
|
|
69
|
+
# Delete notification param project secret
|
|
70
|
+
notifications = [
|
|
71
|
+
notification
|
|
72
|
+
for notification in self.list_run_notifications(session, run_uid, project)
|
|
73
|
+
if notification.name == name
|
|
74
|
+
]
|
|
75
|
+
if notifications:
|
|
76
|
+
# unique constraint on name, run_uid, project, so the list will contain one item at most
|
|
77
|
+
notification = notifications[0]
|
|
78
|
+
mlrun.api.api.utils.delete_notification_params_secret(project, notification)
|
|
79
|
+
|
|
80
|
+
mlrun.api.utils.singletons.db.get_db().delete_run_notifications(
|
|
81
|
+
session, name, run_uid, project
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def set_object_notifications(
|
|
86
|
+
db_session: sqlalchemy.orm.Session,
|
|
87
|
+
auth_info: mlrun.common.schemas.AuthInfo,
|
|
88
|
+
project: str,
|
|
89
|
+
notifications: typing.List[mlrun.common.schemas.Notification],
|
|
90
|
+
notification_parent: typing.Union[
|
|
91
|
+
mlrun.common.schemas.RunIdentifier, mlrun.common.schemas.ScheduleIdentifier
|
|
92
|
+
],
|
|
93
|
+
):
|
|
94
|
+
"""
|
|
95
|
+
Sets notifications on given object (run or schedule, might be extended in the future).
|
|
96
|
+
This will replace any existing notifications.
|
|
97
|
+
:param db_session: DB session
|
|
98
|
+
:param auth_info: Authorization info
|
|
99
|
+
:param project: Project name
|
|
100
|
+
:param notifications: List of notifications to set
|
|
101
|
+
:param notification_parent: Identifier of the object on which to set the notifications
|
|
102
|
+
"""
|
|
103
|
+
set_notification_methods = {
|
|
104
|
+
"run": {
|
|
105
|
+
"factory": mlrun.api.utils.singletons.db.get_db,
|
|
106
|
+
"method_name": mlrun.api.db.sqldb.db.SQLDB.set_run_notifications.__name__,
|
|
107
|
+
"identifier_key": "uid",
|
|
108
|
+
},
|
|
109
|
+
"schedule": {
|
|
110
|
+
"factory": mlrun.api.utils.singletons.scheduler.get_scheduler,
|
|
111
|
+
"method_name": mlrun.api.utils.scheduler.Scheduler.set_schedule_notifications.__name__,
|
|
112
|
+
"identifier_key": "name",
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
set_notification_method = set_notification_methods.get(
|
|
117
|
+
notification_parent.kind, {}
|
|
118
|
+
)
|
|
119
|
+
factory = set_notification_method.get("factory")
|
|
120
|
+
if not factory:
|
|
121
|
+
raise mlrun.errors.MLRunNotFoundError(
|
|
122
|
+
f"couldn't find factory for object kind: {notification_parent.kind}"
|
|
123
|
+
)
|
|
124
|
+
set_func = set_notification_method.get("method_name")
|
|
125
|
+
if not set_func:
|
|
126
|
+
raise mlrun.errors.MLRunNotFoundError(
|
|
127
|
+
f"couldn't find set notification function for object kind: {notification_parent.kind}"
|
|
128
|
+
)
|
|
129
|
+
identifier_key = set_notification_method.get("identifier_key")
|
|
130
|
+
if not identifier_key:
|
|
131
|
+
raise mlrun.errors.MLRunNotFoundError(
|
|
132
|
+
f"couldn't find identifier key for object kind: {notification_parent.kind}"
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
notification_objects_to_set = (
|
|
136
|
+
mlrun.api.api.utils.validate_and_mask_notification_list(
|
|
137
|
+
notifications,
|
|
138
|
+
getattr(notification_parent, identifier_key),
|
|
139
|
+
project,
|
|
140
|
+
)
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
getattr(factory(), set_func)(
|
|
144
|
+
session=db_session,
|
|
145
|
+
project=project,
|
|
146
|
+
notifications=notification_objects_to_set,
|
|
147
|
+
identifier=notification_parent,
|
|
148
|
+
auth_info=auth_info,
|
|
149
|
+
)
|
mlrun/api/crud/pipelines.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.
|
|
@@ -20,11 +20,12 @@ import traceback
|
|
|
20
20
|
import typing
|
|
21
21
|
|
|
22
22
|
import kfp
|
|
23
|
+
import kfp_server_api
|
|
23
24
|
import sqlalchemy.orm
|
|
24
25
|
|
|
25
26
|
import mlrun
|
|
26
27
|
import mlrun.api.api.utils
|
|
27
|
-
import mlrun.
|
|
28
|
+
import mlrun.common.schemas
|
|
28
29
|
import mlrun.errors
|
|
29
30
|
import mlrun.kfpops
|
|
30
31
|
import mlrun.utils.helpers
|
|
@@ -44,26 +45,22 @@ class Pipelines(
|
|
|
44
45
|
sort_by: str = "",
|
|
45
46
|
page_token: str = "",
|
|
46
47
|
filter_: str = "",
|
|
47
|
-
format_: mlrun.
|
|
48
|
+
format_: mlrun.common.schemas.PipelinesFormat = mlrun.common.schemas.PipelinesFormat.metadata_only,
|
|
48
49
|
page_size: typing.Optional[int] = None,
|
|
49
50
|
) -> typing.Tuple[int, typing.Optional[int], typing.List[dict]]:
|
|
50
|
-
if project != "*" and (page_token or page_size
|
|
51
|
+
if project != "*" and (page_token or page_size):
|
|
51
52
|
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
52
|
-
"Filtering by project can not be used together with pagination
|
|
53
|
+
"Filtering by project can not be used together with pagination"
|
|
53
54
|
)
|
|
54
|
-
if format_ == mlrun.
|
|
55
|
+
if format_ == mlrun.common.schemas.PipelinesFormat.summary:
|
|
55
56
|
# we don't support summary format in list pipelines since the returned runs doesn't include the workflow
|
|
56
57
|
# manifest status that includes the nodes section we use to generate the DAG.
|
|
57
58
|
# (There is a workflow manifest under the run's pipeline_spec field, but it doesn't include the status)
|
|
58
59
|
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
59
60
|
"Summary format is not supported for list pipelines, use get instead"
|
|
60
61
|
)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
raise mlrun.errors.MLRunNotFoundError(
|
|
64
|
-
"KubeFlow Pipelines is not configured"
|
|
65
|
-
)
|
|
66
|
-
kfp_client = kfp.Client(host=kfp_url)
|
|
62
|
+
|
|
63
|
+
kfp_client = self.initialize_kfp_client(namespace)
|
|
67
64
|
if project != "*":
|
|
68
65
|
run_dicts = []
|
|
69
66
|
while page_token is not None:
|
|
@@ -72,7 +69,8 @@ class Pipelines(
|
|
|
72
69
|
# the filter that was used to create it)
|
|
73
70
|
response = kfp_client._run_api.list_runs(
|
|
74
71
|
page_token=page_token,
|
|
75
|
-
page_size=mlrun.
|
|
72
|
+
page_size=mlrun.common.schemas.PipelinesPagination.max_page_size,
|
|
73
|
+
sort_by=sort_by,
|
|
76
74
|
filter=filter_ if page_token == "" else "",
|
|
77
75
|
)
|
|
78
76
|
run_dicts.extend([run.to_dict() for run in response.runs or []])
|
|
@@ -89,7 +87,7 @@ class Pipelines(
|
|
|
89
87
|
response = kfp_client._run_api.list_runs(
|
|
90
88
|
page_token=page_token,
|
|
91
89
|
page_size=page_size
|
|
92
|
-
or mlrun.
|
|
90
|
+
or mlrun.common.schemas.PipelinesPagination.default_page_size,
|
|
93
91
|
sort_by=sort_by,
|
|
94
92
|
filter=filter_,
|
|
95
93
|
)
|
|
@@ -100,20 +98,45 @@ class Pipelines(
|
|
|
100
98
|
|
|
101
99
|
return total_size, next_page_token, runs
|
|
102
100
|
|
|
101
|
+
def delete_pipelines_runs(self, db_session: sqlalchemy.orm.Session, project: str):
|
|
102
|
+
_, _, project_pipeline_runs = self.list_pipelines(
|
|
103
|
+
db_session=db_session,
|
|
104
|
+
project=project,
|
|
105
|
+
format_=mlrun.common.schemas.PipelinesFormat.metadata_only,
|
|
106
|
+
)
|
|
107
|
+
kfp_client = self.initialize_kfp_client()
|
|
108
|
+
|
|
109
|
+
if project_pipeline_runs:
|
|
110
|
+
logger.debug(
|
|
111
|
+
"Detected pipeline runs for project, deleting them",
|
|
112
|
+
project=project,
|
|
113
|
+
pipeline_run_ids=[run["id"] for run in project_pipeline_runs],
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
for pipeline_run in project_pipeline_runs:
|
|
117
|
+
try:
|
|
118
|
+
# delete pipeline run also terminates it if it is in progress
|
|
119
|
+
kfp_client._run_api.delete_run(pipeline_run["id"])
|
|
120
|
+
except Exception as exc:
|
|
121
|
+
# we don't want to fail the entire delete operation if we failed to delete a single pipeline run
|
|
122
|
+
# so it won't fail the delete project operation. we will log the error and continue
|
|
123
|
+
logger.warning(
|
|
124
|
+
"Failed to delete pipeline run",
|
|
125
|
+
project=project,
|
|
126
|
+
pipeline_run_id=pipeline_run["id"],
|
|
127
|
+
exc_info=exc,
|
|
128
|
+
)
|
|
129
|
+
logger.debug("Finished deleting pipeline runs", project=project)
|
|
130
|
+
|
|
103
131
|
def get_pipeline(
|
|
104
132
|
self,
|
|
105
133
|
db_session: sqlalchemy.orm.Session,
|
|
106
134
|
run_id: str,
|
|
107
135
|
project: typing.Optional[str] = None,
|
|
108
136
|
namespace: typing.Optional[str] = None,
|
|
109
|
-
format_: mlrun.
|
|
137
|
+
format_: mlrun.common.schemas.PipelinesFormat = mlrun.common.schemas.PipelinesFormat.summary,
|
|
110
138
|
):
|
|
111
|
-
|
|
112
|
-
if not kfp_url:
|
|
113
|
-
raise mlrun.errors.MLRunBadRequestError(
|
|
114
|
-
"KubeFlow Pipelines is not configured"
|
|
115
|
-
)
|
|
116
|
-
kfp_client = kfp.Client(host=kfp_url)
|
|
139
|
+
kfp_client = self.initialize_kfp_client(namespace)
|
|
117
140
|
run = None
|
|
118
141
|
try:
|
|
119
142
|
api_run_detail = kfp_client.get_run(run_id)
|
|
@@ -122,13 +145,16 @@ class Pipelines(
|
|
|
122
145
|
if project and project != "*":
|
|
123
146
|
run_project = self.resolve_project_from_pipeline(run)
|
|
124
147
|
if run_project != project:
|
|
125
|
-
raise mlrun.errors.
|
|
148
|
+
raise mlrun.errors.MLRunNotFoundError(
|
|
126
149
|
f"Pipeline run with id {run_id} is not of project {project}"
|
|
127
150
|
)
|
|
128
151
|
run = self._format_run(
|
|
129
152
|
db_session, run, format_, api_run_detail.to_dict()
|
|
130
153
|
)
|
|
131
|
-
|
|
154
|
+
except kfp_server_api.ApiException as exc:
|
|
155
|
+
mlrun.errors.raise_for_status_code(int(exc.status), err_to_str(exc))
|
|
156
|
+
except mlrun.errors.MLRunHTTPStatusError:
|
|
157
|
+
raise
|
|
132
158
|
except Exception as exc:
|
|
133
159
|
raise mlrun.errors.MLRunRuntimeError(
|
|
134
160
|
f"Failed getting kfp run: {err_to_str(exc)}"
|
|
@@ -158,7 +184,6 @@ class Pipelines(
|
|
|
158
184
|
)
|
|
159
185
|
|
|
160
186
|
logger.debug("Writing pipeline to temp file", content_type=content_type)
|
|
161
|
-
print(str(data))
|
|
162
187
|
|
|
163
188
|
pipeline_file = tempfile.NamedTemporaryFile(suffix=content_type)
|
|
164
189
|
with open(pipeline_file.name, "wb") as fp:
|
|
@@ -172,12 +197,7 @@ class Pipelines(
|
|
|
172
197
|
)
|
|
173
198
|
|
|
174
199
|
try:
|
|
175
|
-
|
|
176
|
-
if not kfp_url:
|
|
177
|
-
raise mlrun.errors.MLRunBadRequestError(
|
|
178
|
-
"KubeFlow Pipelines is not configured"
|
|
179
|
-
)
|
|
180
|
-
kfp_client = kfp.Client(host=kfp_url)
|
|
200
|
+
kfp_client = self.initialize_kfp_client(namespace)
|
|
181
201
|
experiment = kfp_client.create_experiment(name=experiment_name)
|
|
182
202
|
run = kfp_client.run_pipeline(
|
|
183
203
|
experiment.id, run_name, pipeline_file.name, params=arguments
|
|
@@ -196,11 +216,20 @@ class Pipelines(
|
|
|
196
216
|
|
|
197
217
|
return run
|
|
198
218
|
|
|
219
|
+
@staticmethod
|
|
220
|
+
def initialize_kfp_client(namespace: typing.Optional[str] = None) -> kfp.Client:
|
|
221
|
+
kfp_url = mlrun.mlconf.resolve_kfp_url(namespace)
|
|
222
|
+
if not kfp_url:
|
|
223
|
+
raise mlrun.errors.MLRunNotFoundError(
|
|
224
|
+
"KubeFlow Pipelines is not configured"
|
|
225
|
+
)
|
|
226
|
+
return kfp.Client(host=kfp_url)
|
|
227
|
+
|
|
199
228
|
def _format_runs(
|
|
200
229
|
self,
|
|
201
230
|
db_session: sqlalchemy.orm.Session,
|
|
202
231
|
runs: typing.List[dict],
|
|
203
|
-
format_: mlrun.
|
|
232
|
+
format_: mlrun.common.schemas.PipelinesFormat = mlrun.common.schemas.PipelinesFormat.metadata_only,
|
|
204
233
|
) -> typing.List[dict]:
|
|
205
234
|
formatted_runs = []
|
|
206
235
|
for run in runs:
|
|
@@ -211,32 +240,18 @@ class Pipelines(
|
|
|
211
240
|
self,
|
|
212
241
|
db_session: sqlalchemy.orm.Session,
|
|
213
242
|
run: dict,
|
|
214
|
-
format_: mlrun.
|
|
243
|
+
format_: mlrun.common.schemas.PipelinesFormat = mlrun.common.schemas.PipelinesFormat.metadata_only,
|
|
215
244
|
api_run_detail: typing.Optional[dict] = None,
|
|
216
245
|
) -> dict:
|
|
217
246
|
run["project"] = self.resolve_project_from_pipeline(run)
|
|
218
|
-
if format_ == mlrun.
|
|
247
|
+
if format_ == mlrun.common.schemas.PipelinesFormat.full:
|
|
219
248
|
return run
|
|
220
|
-
elif format_ == mlrun.
|
|
221
|
-
return
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if k
|
|
225
|
-
in [
|
|
226
|
-
"id",
|
|
227
|
-
"name",
|
|
228
|
-
"project",
|
|
229
|
-
"status",
|
|
230
|
-
"error",
|
|
231
|
-
"created_at",
|
|
232
|
-
"scheduled_at",
|
|
233
|
-
"finished_at",
|
|
234
|
-
"description",
|
|
235
|
-
]
|
|
236
|
-
}
|
|
237
|
-
elif format_ == mlrun.api.schemas.PipelinesFormat.name_only:
|
|
249
|
+
elif format_ == mlrun.common.schemas.PipelinesFormat.metadata_only:
|
|
250
|
+
return mlrun.utils.helpers.format_run(run, with_project=True)
|
|
251
|
+
|
|
252
|
+
elif format_ == mlrun.common.schemas.PipelinesFormat.name_only:
|
|
238
253
|
return run.get("name")
|
|
239
|
-
elif format_ == mlrun.
|
|
254
|
+
elif format_ == mlrun.common.schemas.PipelinesFormat.summary:
|
|
240
255
|
if not api_run_detail:
|
|
241
256
|
raise mlrun.errors.MLRunRuntimeError(
|
|
242
257
|
"The full kfp api_run_detail object is needed to generate the summary format"
|
mlrun/api/crud/projects.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.
|
|
@@ -23,11 +23,12 @@ import sqlalchemy.orm
|
|
|
23
23
|
|
|
24
24
|
import mlrun.api.crud
|
|
25
25
|
import mlrun.api.db.session
|
|
26
|
-
import mlrun.api.
|
|
26
|
+
import mlrun.api.utils.events.events_factory as events_factory
|
|
27
27
|
import mlrun.api.utils.projects.remotes.follower
|
|
28
28
|
import mlrun.api.utils.singletons.db
|
|
29
29
|
import mlrun.api.utils.singletons.k8s
|
|
30
30
|
import mlrun.api.utils.singletons.scheduler
|
|
31
|
+
import mlrun.common.schemas
|
|
31
32
|
import mlrun.errors
|
|
32
33
|
import mlrun.utils.singleton
|
|
33
34
|
from mlrun.utils import logger
|
|
@@ -44,7 +45,7 @@ class Projects(
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
def create_project(
|
|
47
|
-
self, session: sqlalchemy.orm.Session, project: mlrun.
|
|
48
|
+
self, session: sqlalchemy.orm.Session, project: mlrun.common.schemas.Project
|
|
48
49
|
):
|
|
49
50
|
logger.debug(
|
|
50
51
|
"Creating project",
|
|
@@ -63,7 +64,7 @@ class Projects(
|
|
|
63
64
|
self,
|
|
64
65
|
session: sqlalchemy.orm.Session,
|
|
65
66
|
name: str,
|
|
66
|
-
project: mlrun.
|
|
67
|
+
project: mlrun.common.schemas.Project,
|
|
67
68
|
):
|
|
68
69
|
logger.debug(
|
|
69
70
|
"Storing project",
|
|
@@ -83,7 +84,7 @@ class Projects(
|
|
|
83
84
|
session: sqlalchemy.orm.Session,
|
|
84
85
|
name: str,
|
|
85
86
|
project: dict,
|
|
86
|
-
patch_mode: mlrun.
|
|
87
|
+
patch_mode: mlrun.common.schemas.PatchMode = mlrun.common.schemas.PatchMode.replace,
|
|
87
88
|
):
|
|
88
89
|
logger.debug(
|
|
89
90
|
"Patching project", name=name, project=project, patch_mode=patch_mode
|
|
@@ -96,12 +97,12 @@ class Projects(
|
|
|
96
97
|
self,
|
|
97
98
|
session: sqlalchemy.orm.Session,
|
|
98
99
|
name: str,
|
|
99
|
-
deletion_strategy: mlrun.
|
|
100
|
+
deletion_strategy: mlrun.common.schemas.DeletionStrategy = mlrun.common.schemas.DeletionStrategy.default(),
|
|
100
101
|
):
|
|
101
102
|
logger.debug("Deleting project", name=name, deletion_strategy=deletion_strategy)
|
|
102
103
|
if (
|
|
103
104
|
deletion_strategy.is_restricted()
|
|
104
|
-
or deletion_strategy == mlrun.
|
|
105
|
+
or deletion_strategy == mlrun.common.schemas.DeletionStrategy.check
|
|
105
106
|
):
|
|
106
107
|
if not mlrun.api.utils.singletons.db.get_db().is_project_exists(
|
|
107
108
|
session, name
|
|
@@ -111,7 +112,7 @@ class Projects(
|
|
|
111
112
|
session, name
|
|
112
113
|
)
|
|
113
114
|
self._verify_project_has_no_external_resources(name)
|
|
114
|
-
if deletion_strategy == mlrun.
|
|
115
|
+
if deletion_strategy == mlrun.common.schemas.DeletionStrategy.check:
|
|
115
116
|
return
|
|
116
117
|
elif deletion_strategy.is_cascading():
|
|
117
118
|
self.delete_project_resources(session, name)
|
|
@@ -134,7 +135,7 @@ class Projects(
|
|
|
134
135
|
# Therefore, this check should remain at the end of the verification flow.
|
|
135
136
|
if (
|
|
136
137
|
mlrun.mlconf.is_api_running_on_k8s()
|
|
137
|
-
and mlrun.api.utils.singletons.k8s.
|
|
138
|
+
and mlrun.api.utils.singletons.k8s.get_k8s_helper().get_project_secret_keys(
|
|
138
139
|
project
|
|
139
140
|
)
|
|
140
141
|
):
|
|
@@ -158,11 +159,16 @@ class Projects(
|
|
|
158
159
|
label_selector=f"mlrun/project={name}",
|
|
159
160
|
force=True,
|
|
160
161
|
)
|
|
162
|
+
if mlrun.mlconf.resolve_kfp_url():
|
|
163
|
+
logger.debug("Removing KFP pipelines runs for project", project=name)
|
|
164
|
+
mlrun.api.crud.pipelines.Pipelines().delete_pipelines_runs(
|
|
165
|
+
db_session=session, project=name
|
|
166
|
+
)
|
|
161
167
|
|
|
162
168
|
# log collector service will delete the logs, so we don't need to do it here
|
|
163
169
|
if (
|
|
164
170
|
mlrun.mlconf.log_collector.mode
|
|
165
|
-
== mlrun.
|
|
171
|
+
== mlrun.common.schemas.LogsCollectorMode.legacy
|
|
166
172
|
):
|
|
167
173
|
mlrun.api.crud.Logs().delete_logs(name)
|
|
168
174
|
|
|
@@ -176,22 +182,44 @@ class Projects(
|
|
|
176
182
|
|
|
177
183
|
# delete project secrets - passing None will delete all secrets
|
|
178
184
|
if mlrun.mlconf.is_api_running_on_k8s():
|
|
179
|
-
|
|
185
|
+
secrets = None
|
|
186
|
+
(
|
|
187
|
+
secret_name,
|
|
188
|
+
action,
|
|
189
|
+
) = mlrun.api.utils.singletons.k8s.get_k8s_helper().delete_project_secrets(
|
|
190
|
+
name, secrets
|
|
191
|
+
)
|
|
192
|
+
if action:
|
|
193
|
+
events_client = events_factory.EventsFactory().get_events_client()
|
|
194
|
+
events_client.emit(
|
|
195
|
+
events_client.generate_project_secret_event(
|
|
196
|
+
name,
|
|
197
|
+
secret_name,
|
|
198
|
+
action=action,
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
else:
|
|
203
|
+
logger.debug(
|
|
204
|
+
"No project secrets to delete",
|
|
205
|
+
action=action,
|
|
206
|
+
secret_name=secret_name,
|
|
207
|
+
)
|
|
180
208
|
|
|
181
209
|
def get_project(
|
|
182
210
|
self, session: sqlalchemy.orm.Session, name: str
|
|
183
|
-
) -> mlrun.
|
|
211
|
+
) -> mlrun.common.schemas.Project:
|
|
184
212
|
return mlrun.api.utils.singletons.db.get_db().get_project(session, name)
|
|
185
213
|
|
|
186
214
|
def list_projects(
|
|
187
215
|
self,
|
|
188
216
|
session: sqlalchemy.orm.Session,
|
|
189
217
|
owner: str = None,
|
|
190
|
-
format_: mlrun.
|
|
218
|
+
format_: mlrun.common.schemas.ProjectsFormat = mlrun.common.schemas.ProjectsFormat.full,
|
|
191
219
|
labels: typing.List[str] = None,
|
|
192
|
-
state: mlrun.
|
|
220
|
+
state: mlrun.common.schemas.ProjectState = None,
|
|
193
221
|
names: typing.Optional[typing.List[str]] = None,
|
|
194
|
-
) -> mlrun.
|
|
222
|
+
) -> mlrun.common.schemas.ProjectsOutput:
|
|
195
223
|
return mlrun.api.utils.singletons.db.get_db().list_projects(
|
|
196
224
|
session, owner, format_, labels, state, names
|
|
197
225
|
)
|
|
@@ -201,14 +229,14 @@ class Projects(
|
|
|
201
229
|
session: sqlalchemy.orm.Session,
|
|
202
230
|
owner: str = None,
|
|
203
231
|
labels: typing.List[str] = None,
|
|
204
|
-
state: mlrun.
|
|
232
|
+
state: mlrun.common.schemas.ProjectState = None,
|
|
205
233
|
names: typing.Optional[typing.List[str]] = None,
|
|
206
|
-
) -> mlrun.
|
|
234
|
+
) -> mlrun.common.schemas.ProjectSummariesOutput:
|
|
207
235
|
projects_output = await fastapi.concurrency.run_in_threadpool(
|
|
208
236
|
self.list_projects,
|
|
209
237
|
session,
|
|
210
238
|
owner,
|
|
211
|
-
mlrun.
|
|
239
|
+
mlrun.common.schemas.ProjectsFormat.name_only,
|
|
212
240
|
labels,
|
|
213
241
|
state,
|
|
214
242
|
names,
|
|
@@ -216,13 +244,13 @@ class Projects(
|
|
|
216
244
|
project_summaries = await self.generate_projects_summaries(
|
|
217
245
|
projects_output.projects
|
|
218
246
|
)
|
|
219
|
-
return mlrun.
|
|
247
|
+
return mlrun.common.schemas.ProjectSummariesOutput(
|
|
220
248
|
project_summaries=project_summaries
|
|
221
249
|
)
|
|
222
250
|
|
|
223
251
|
async def get_project_summary(
|
|
224
252
|
self, session: sqlalchemy.orm.Session, name: str
|
|
225
|
-
) -> mlrun.
|
|
253
|
+
) -> mlrun.common.schemas.ProjectSummary:
|
|
226
254
|
# Call get project so we'll explode if project doesn't exists
|
|
227
255
|
await fastapi.concurrency.run_in_threadpool(self.get_project, session, name)
|
|
228
256
|
project_summaries = await self.generate_projects_summaries([name])
|
|
@@ -230,7 +258,7 @@ class Projects(
|
|
|
230
258
|
|
|
231
259
|
async def generate_projects_summaries(
|
|
232
260
|
self, projects: typing.List[str]
|
|
233
|
-
) -> typing.List[mlrun.
|
|
261
|
+
) -> typing.List[mlrun.common.schemas.ProjectSummary]:
|
|
234
262
|
(
|
|
235
263
|
project_to_files_count,
|
|
236
264
|
project_to_schedule_count,
|
|
@@ -243,7 +271,7 @@ class Projects(
|
|
|
243
271
|
project_summaries = []
|
|
244
272
|
for project in projects:
|
|
245
273
|
project_summaries.append(
|
|
246
|
-
mlrun.
|
|
274
|
+
mlrun.common.schemas.ProjectSummary(
|
|
247
275
|
name=project,
|
|
248
276
|
files_count=project_to_files_count.get(project, 0),
|
|
249
277
|
schedules_count=project_to_schedule_count.get(project, 0),
|
|
@@ -314,7 +342,7 @@ class Projects(
|
|
|
314
342
|
@staticmethod
|
|
315
343
|
def _list_pipelines(
|
|
316
344
|
session,
|
|
317
|
-
format_: mlrun.
|
|
345
|
+
format_: mlrun.common.schemas.PipelinesFormat = mlrun.common.schemas.PipelinesFormat.metadata_only,
|
|
318
346
|
):
|
|
319
347
|
return mlrun.api.crud.Pipelines().list_pipelines(session, "*", format_=format_)
|
|
320
348
|
|
mlrun/api/crud/runs.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.
|
|
@@ -16,10 +16,10 @@ import typing
|
|
|
16
16
|
|
|
17
17
|
import sqlalchemy.orm
|
|
18
18
|
|
|
19
|
-
import mlrun.api.schemas
|
|
20
19
|
import mlrun.api.utils.projects.remotes.follower
|
|
21
20
|
import mlrun.api.utils.singletons.db
|
|
22
21
|
import mlrun.api.utils.singletons.project_member
|
|
22
|
+
import mlrun.common.schemas
|
|
23
23
|
import mlrun.config
|
|
24
24
|
import mlrun.errors
|
|
25
25
|
import mlrun.lists
|
|
@@ -119,13 +119,14 @@ class Runs(
|
|
|
119
119
|
start_time_to=None,
|
|
120
120
|
last_update_time_from=None,
|
|
121
121
|
last_update_time_to=None,
|
|
122
|
-
partition_by: mlrun.
|
|
122
|
+
partition_by: mlrun.common.schemas.RunPartitionByField = None,
|
|
123
123
|
rows_per_partition: int = 1,
|
|
124
|
-
partition_sort_by: mlrun.
|
|
125
|
-
partition_order: mlrun.
|
|
124
|
+
partition_sort_by: mlrun.common.schemas.SortField = None,
|
|
125
|
+
partition_order: mlrun.common.schemas.OrderType = mlrun.common.schemas.OrderType.desc,
|
|
126
126
|
max_partitions: int = 0,
|
|
127
127
|
requested_logs: bool = None,
|
|
128
128
|
return_as_run_structs: bool = True,
|
|
129
|
+
with_notifications: bool = False,
|
|
129
130
|
):
|
|
130
131
|
project = project or mlrun.mlconf.default_project
|
|
131
132
|
return mlrun.api.utils.singletons.db.get_db().list_runs(
|
|
@@ -149,6 +150,7 @@ class Runs(
|
|
|
149
150
|
max_partitions,
|
|
150
151
|
requested_logs,
|
|
151
152
|
return_as_run_structs,
|
|
153
|
+
with_notifications,
|
|
152
154
|
)
|
|
153
155
|
|
|
154
156
|
def delete_run(
|