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/launcher.py
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Copyright 2023 MLRun Authors
|
|
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
|
+
from typing import Dict, List, Optional, Union
|
|
15
|
+
|
|
16
|
+
import mlrun.api.crud
|
|
17
|
+
import mlrun.api.db.sqldb.session
|
|
18
|
+
import mlrun.common.schemas.schedule
|
|
19
|
+
import mlrun.config
|
|
20
|
+
import mlrun.execution
|
|
21
|
+
import mlrun.launcher.base
|
|
22
|
+
import mlrun.runtimes
|
|
23
|
+
import mlrun.runtimes.generators
|
|
24
|
+
import mlrun.runtimes.utils
|
|
25
|
+
import mlrun.utils
|
|
26
|
+
import mlrun.utils.regex
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ServerSideLauncher(mlrun.launcher.base.BaseLauncher):
|
|
30
|
+
def launch(
|
|
31
|
+
self,
|
|
32
|
+
runtime: mlrun.runtimes.BaseRuntime,
|
|
33
|
+
task: Optional[
|
|
34
|
+
Union["mlrun.run.RunTemplate", "mlrun.run.RunObject", dict]
|
|
35
|
+
] = None,
|
|
36
|
+
handler: Optional[str] = None,
|
|
37
|
+
name: Optional[str] = "",
|
|
38
|
+
project: Optional[str] = "",
|
|
39
|
+
params: Optional[dict] = None,
|
|
40
|
+
inputs: Optional[Dict[str, str]] = None,
|
|
41
|
+
out_path: Optional[str] = "",
|
|
42
|
+
workdir: Optional[str] = "",
|
|
43
|
+
artifact_path: Optional[str] = "",
|
|
44
|
+
watch: Optional[bool] = True,
|
|
45
|
+
schedule: Optional[
|
|
46
|
+
Union[str, mlrun.common.schemas.schedule.ScheduleCronTrigger]
|
|
47
|
+
] = None,
|
|
48
|
+
hyperparams: Dict[str, list] = None,
|
|
49
|
+
hyper_param_options: Optional[mlrun.model.HyperParamOptions] = None,
|
|
50
|
+
verbose: Optional[bool] = None,
|
|
51
|
+
scrape_metrics: Optional[bool] = None,
|
|
52
|
+
local_code_path: Optional[str] = None,
|
|
53
|
+
auto_build: Optional[bool] = None,
|
|
54
|
+
param_file_secrets: Optional[Dict[str, str]] = None,
|
|
55
|
+
notifications: Optional[List[mlrun.model.Notification]] = None,
|
|
56
|
+
returns: Optional[List[Union[str, Dict[str, str]]]] = None,
|
|
57
|
+
) -> mlrun.run.RunObject:
|
|
58
|
+
self.enrich_runtime(runtime, project)
|
|
59
|
+
|
|
60
|
+
run = self._create_run_object(task)
|
|
61
|
+
|
|
62
|
+
run = self._enrich_run(
|
|
63
|
+
runtime,
|
|
64
|
+
run=run,
|
|
65
|
+
handler=handler,
|
|
66
|
+
project_name=project,
|
|
67
|
+
name=name,
|
|
68
|
+
params=params,
|
|
69
|
+
inputs=inputs,
|
|
70
|
+
returns=returns,
|
|
71
|
+
hyperparams=hyperparams,
|
|
72
|
+
hyper_param_options=hyper_param_options,
|
|
73
|
+
verbose=verbose,
|
|
74
|
+
scrape_metrics=scrape_metrics,
|
|
75
|
+
out_path=out_path,
|
|
76
|
+
artifact_path=artifact_path,
|
|
77
|
+
workdir=workdir,
|
|
78
|
+
notifications=notifications,
|
|
79
|
+
)
|
|
80
|
+
self._validate_runtime(runtime, run)
|
|
81
|
+
|
|
82
|
+
if runtime.verbose:
|
|
83
|
+
mlrun.utils.logger.info(f"Run:\n{run.to_yaml()}")
|
|
84
|
+
|
|
85
|
+
if not runtime.is_child:
|
|
86
|
+
mlrun.utils.logger.info(
|
|
87
|
+
"Storing function",
|
|
88
|
+
name=run.metadata.name,
|
|
89
|
+
uid=run.metadata.uid,
|
|
90
|
+
)
|
|
91
|
+
self._store_function(runtime, run)
|
|
92
|
+
|
|
93
|
+
execution = mlrun.execution.MLClientCtx.from_dict(
|
|
94
|
+
run.to_dict(),
|
|
95
|
+
runtime._get_db(),
|
|
96
|
+
autocommit=False,
|
|
97
|
+
is_api=True,
|
|
98
|
+
store_run=False,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# create task generator (for child runs) from spec
|
|
102
|
+
task_generator = mlrun.runtimes.generators.get_generator(
|
|
103
|
+
run.spec, execution, param_file_secrets=param_file_secrets
|
|
104
|
+
)
|
|
105
|
+
if task_generator:
|
|
106
|
+
# verify valid task parameters
|
|
107
|
+
tasks = task_generator.generate(run)
|
|
108
|
+
for task in tasks:
|
|
109
|
+
self._validate_run_params(task.spec.parameters)
|
|
110
|
+
|
|
111
|
+
# post verifications, store execution in db and run pre run hooks
|
|
112
|
+
execution.store_run()
|
|
113
|
+
runtime._pre_run(run, execution) # hook for runtime specific prep
|
|
114
|
+
|
|
115
|
+
resp = None
|
|
116
|
+
last_err = None
|
|
117
|
+
# If the runtime is nested, it means the hyper-run will run within a single instance of the run.
|
|
118
|
+
# So while in the API, we consider the hyper-run as a single run, and then in the runtime itself when the
|
|
119
|
+
# runtime is now a local runtime and therefore `self._is_nested == False`, we run each task as a separate run by
|
|
120
|
+
# using the task generator
|
|
121
|
+
if task_generator and not runtime._is_nested:
|
|
122
|
+
# multiple runs (based on hyper params or params file)
|
|
123
|
+
runner = runtime._run_many
|
|
124
|
+
if hasattr(runtime, "_parallel_run_many") and task_generator.use_parallel():
|
|
125
|
+
runner = runtime._parallel_run_many
|
|
126
|
+
results = runner(task_generator, execution, run)
|
|
127
|
+
mlrun.runtimes.utils.results_to_iter(results, run, execution)
|
|
128
|
+
result = execution.to_dict()
|
|
129
|
+
result = runtime._update_run_state(result, task=run)
|
|
130
|
+
|
|
131
|
+
else:
|
|
132
|
+
# single run
|
|
133
|
+
try:
|
|
134
|
+
resp = runtime._run(run, execution)
|
|
135
|
+
|
|
136
|
+
except mlrun.runtimes.utils.RunError as err:
|
|
137
|
+
last_err = err
|
|
138
|
+
|
|
139
|
+
finally:
|
|
140
|
+
result = runtime._update_run_state(resp=resp, task=run, err=last_err)
|
|
141
|
+
|
|
142
|
+
self._save_notifications(run)
|
|
143
|
+
|
|
144
|
+
runtime._post_run(result, execution) # hook for runtime specific cleanup
|
|
145
|
+
|
|
146
|
+
return self._wrap_run_result(runtime, result, run, err=last_err)
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
def enrich_runtime(
|
|
150
|
+
runtime: "mlrun.runtimes.base.BaseRuntime", project_name: Optional[str] = ""
|
|
151
|
+
):
|
|
152
|
+
"""
|
|
153
|
+
Enrich the runtime object with the project spec and metadata.
|
|
154
|
+
This is done only on the server side, since it's the source of truth for the project, and we want to keep the
|
|
155
|
+
client side enrichment as minimal as possible.
|
|
156
|
+
"""
|
|
157
|
+
# ensure the runtime has a project before we enrich it with the project's spec
|
|
158
|
+
runtime.metadata.project = (
|
|
159
|
+
project_name
|
|
160
|
+
or runtime.metadata.project
|
|
161
|
+
or mlrun.config.config.default_project
|
|
162
|
+
)
|
|
163
|
+
project = runtime._get_db().get_project(runtime.metadata.project)
|
|
164
|
+
# this is mainly for tests with nop db
|
|
165
|
+
# in normal use cases if no project is found we will get an error
|
|
166
|
+
if project:
|
|
167
|
+
project = mlrun.projects.project.MlrunProject.from_dict(project.dict())
|
|
168
|
+
mlrun.projects.pipelines.enrich_function_object(
|
|
169
|
+
project, runtime, copy_function=False
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
def _save_notifications(self, runobj):
|
|
173
|
+
if not self._run_has_valid_notifications(runobj):
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
# If in the api server, we can assume that watch=False, so we save notification
|
|
177
|
+
# configs to the DB, for the run monitor to later pick up and push.
|
|
178
|
+
session = mlrun.api.db.sqldb.session.create_session()
|
|
179
|
+
mlrun.api.crud.Notifications().store_run_notifications(
|
|
180
|
+
session,
|
|
181
|
+
runobj.spec.notifications,
|
|
182
|
+
runobj.metadata.uid,
|
|
183
|
+
runobj.metadata.project,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
def _store_function(
|
|
187
|
+
self, runtime: mlrun.runtimes.base.BaseRuntime, run: mlrun.run.RunObject
|
|
188
|
+
):
|
|
189
|
+
run.metadata.labels["kind"] = runtime.kind
|
|
190
|
+
db = runtime._get_db()
|
|
191
|
+
if db and runtime.kind != "handler":
|
|
192
|
+
struct = runtime.to_dict()
|
|
193
|
+
hash_key = db.store_function(
|
|
194
|
+
struct, runtime.metadata.name, runtime.metadata.project, versioned=True
|
|
195
|
+
)
|
|
196
|
+
run.spec.function = runtime._function_uri(hash_key=hash_key)
|
mlrun/api/main.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.
|
|
@@ -24,12 +24,14 @@ import sqlalchemy.orm
|
|
|
24
24
|
import uvicorn
|
|
25
25
|
from fastapi.exception_handlers import http_exception_handler
|
|
26
26
|
|
|
27
|
-
import mlrun.api.
|
|
27
|
+
import mlrun.api.db.base
|
|
28
28
|
import mlrun.api.utils.clients.chief
|
|
29
29
|
import mlrun.api.utils.clients.log_collector
|
|
30
|
+
import mlrun.common.schemas
|
|
30
31
|
import mlrun.errors
|
|
31
32
|
import mlrun.lists
|
|
32
33
|
import mlrun.utils
|
|
34
|
+
import mlrun.utils.notifications
|
|
33
35
|
import mlrun.utils.version
|
|
34
36
|
from mlrun.api.api.api import api_router
|
|
35
37
|
from mlrun.api.db.session import close_session, create_session
|
|
@@ -41,6 +43,7 @@ from mlrun.api.utils.periodic import (
|
|
|
41
43
|
run_function_periodically,
|
|
42
44
|
)
|
|
43
45
|
from mlrun.api.utils.singletons.db import get_db, initialize_db
|
|
46
|
+
from mlrun.api.utils.singletons.k8s import get_k8s_helper
|
|
44
47
|
from mlrun.api.utils.singletons.logs_dir import initialize_logs_dir
|
|
45
48
|
from mlrun.api.utils.singletons.project_member import (
|
|
46
49
|
get_project_member,
|
|
@@ -49,13 +52,20 @@ from mlrun.api.utils.singletons.project_member import (
|
|
|
49
52
|
from mlrun.api.utils.singletons.scheduler import get_scheduler, initialize_scheduler
|
|
50
53
|
from mlrun.config import config
|
|
51
54
|
from mlrun.errors import err_to_str
|
|
52
|
-
from mlrun.k8s_utils import get_k8s_helper
|
|
53
55
|
from mlrun.runtimes import RuntimeClassMode, RuntimeKinds, get_runtime_handler
|
|
54
56
|
from mlrun.utils import logger
|
|
55
57
|
|
|
56
58
|
API_PREFIX = "/api"
|
|
57
59
|
BASE_VERSIONED_API_PREFIX = f"{API_PREFIX}/v1"
|
|
58
60
|
|
|
61
|
+
# When pushing notifications, push notifications only for runs that entered a terminal state
|
|
62
|
+
# since the last time we pushed notifications.
|
|
63
|
+
# On the first time we push notifications, we'll push notifications for all runs that are in a terminal state
|
|
64
|
+
# and their notifications haven't been sent yet.
|
|
65
|
+
# TODO: find better solution than a global variable for chunking the list of runs
|
|
66
|
+
# for which to push notifications
|
|
67
|
+
_last_notification_push_time: datetime.datetime = None
|
|
68
|
+
|
|
59
69
|
|
|
60
70
|
app = fastapi.FastAPI(
|
|
61
71
|
title="MLRun",
|
|
@@ -70,8 +80,9 @@ app = fastapi.FastAPI(
|
|
|
70
80
|
)
|
|
71
81
|
app.include_router(api_router, prefix=BASE_VERSIONED_API_PREFIX)
|
|
72
82
|
# This is for backward compatibility, that is why we still leave it here but not include it in the schema
|
|
73
|
-
# so new users won't use the old un-versioned api
|
|
74
|
-
#
|
|
83
|
+
# so new users won't use the old un-versioned api.
|
|
84
|
+
# /api points to /api/v1 since it is used externally, and we don't want to break it.
|
|
85
|
+
# TODO: make sure UI and all relevant Iguazio versions uses /api/v1 and deprecate this
|
|
75
86
|
app.include_router(api_router, prefix=API_PREFIX, include_in_schema=False)
|
|
76
87
|
|
|
77
88
|
init_middlewares(app)
|
|
@@ -93,6 +104,11 @@ async def generic_error_handler(request: fastapi.Request, exc: Exception):
|
|
|
93
104
|
async def http_status_error_handler(
|
|
94
105
|
request: fastapi.Request, exc: mlrun.errors.MLRunHTTPStatusError
|
|
95
106
|
):
|
|
107
|
+
request_id = None
|
|
108
|
+
|
|
109
|
+
# request might not have request id when the error is raised before the request id is set on middleware
|
|
110
|
+
if hasattr(request.state, "request_id"):
|
|
111
|
+
request_id = request.state.request_id
|
|
96
112
|
status_code = exc.response.status_code
|
|
97
113
|
error_message = repr(exc)
|
|
98
114
|
logger.warning(
|
|
@@ -100,6 +116,7 @@ async def http_status_error_handler(
|
|
|
100
116
|
error_message=error_message,
|
|
101
117
|
status_code=status_code,
|
|
102
118
|
traceback=traceback.format_exc(),
|
|
119
|
+
request_id=request_id,
|
|
103
120
|
)
|
|
104
121
|
return await http_exception_handler(
|
|
105
122
|
request,
|
|
@@ -110,8 +127,8 @@ async def http_status_error_handler(
|
|
|
110
127
|
@app.on_event("startup")
|
|
111
128
|
async def startup_event():
|
|
112
129
|
logger.info(
|
|
113
|
-
"
|
|
114
|
-
|
|
130
|
+
"On startup event handler called",
|
|
131
|
+
config=config.dump_yaml(),
|
|
115
132
|
version=mlrun.utils.version.Version().get(),
|
|
116
133
|
)
|
|
117
134
|
loop = asyncio.get_running_loop()
|
|
@@ -126,13 +143,13 @@ async def startup_event():
|
|
|
126
143
|
|
|
127
144
|
if (
|
|
128
145
|
config.httpdb.clusterization.worker.sync_with_chief.mode
|
|
129
|
-
== mlrun.
|
|
146
|
+
== mlrun.common.schemas.WaitForChiefToReachOnlineStateFeatureFlag.enabled
|
|
130
147
|
and config.httpdb.clusterization.role
|
|
131
|
-
== mlrun.
|
|
148
|
+
== mlrun.common.schemas.ClusterizationRole.worker
|
|
132
149
|
):
|
|
133
150
|
_start_chief_clusterization_spec_sync_loop()
|
|
134
151
|
|
|
135
|
-
if config.httpdb.state == mlrun.
|
|
152
|
+
if config.httpdb.state == mlrun.common.schemas.APIStates.online:
|
|
136
153
|
await move_api_to_online()
|
|
137
154
|
|
|
138
155
|
|
|
@@ -155,7 +172,10 @@ async def move_api_to_online():
|
|
|
155
172
|
initialize_project_member()
|
|
156
173
|
|
|
157
174
|
# maintenance periodic functions should only run on the chief instance
|
|
158
|
-
if
|
|
175
|
+
if (
|
|
176
|
+
config.httpdb.clusterization.role
|
|
177
|
+
== mlrun.common.schemas.ClusterizationRole.chief
|
|
178
|
+
):
|
|
159
179
|
# runs cleanup/monitoring is not needed if we're not inside kubernetes cluster
|
|
160
180
|
if get_k8s_helper(silent=True).is_running_inside_kubernetes_cluster():
|
|
161
181
|
_start_periodic_cleanup()
|
|
@@ -165,7 +185,7 @@ async def move_api_to_online():
|
|
|
165
185
|
|
|
166
186
|
|
|
167
187
|
async def _start_logs_collection():
|
|
168
|
-
if config.log_collector.mode == mlrun.
|
|
188
|
+
if config.log_collector.mode == mlrun.common.schemas.LogsCollectorMode.legacy:
|
|
169
189
|
logger.info(
|
|
170
190
|
"Using legacy logs collection method, skipping logs collection periodic function",
|
|
171
191
|
mode=config.log_collector.mode,
|
|
@@ -405,7 +425,7 @@ def _start_periodic_runs_monitoring():
|
|
|
405
425
|
|
|
406
426
|
|
|
407
427
|
async def _start_periodic_stop_logs():
|
|
408
|
-
if config.log_collector.mode == mlrun.
|
|
428
|
+
if config.log_collector.mode == mlrun.common.schemas.LogsCollectorMode.legacy:
|
|
409
429
|
logger.info(
|
|
410
430
|
"Using legacy logs collection method, skipping stop logs periodic function",
|
|
411
431
|
mode=config.log_collector.mode,
|
|
@@ -469,7 +489,7 @@ def _start_chief_clusterization_spec_sync_loop():
|
|
|
469
489
|
async def _synchronize_with_chief_clusterization_spec():
|
|
470
490
|
# sanity
|
|
471
491
|
# if we are still in the periodic function and the worker has reached the terminal state, then cancel it
|
|
472
|
-
if config.httpdb.state in mlrun.
|
|
492
|
+
if config.httpdb.state in mlrun.common.schemas.APIStates.terminal_states():
|
|
473
493
|
cancel_periodic_function(_synchronize_with_chief_clusterization_spec.__name__)
|
|
474
494
|
|
|
475
495
|
try:
|
|
@@ -488,14 +508,14 @@ async def _synchronize_with_chief_clusterization_spec():
|
|
|
488
508
|
|
|
489
509
|
|
|
490
510
|
async def _align_worker_state_with_chief_state(
|
|
491
|
-
clusterization_spec: mlrun.
|
|
511
|
+
clusterization_spec: mlrun.common.schemas.ClusterizationSpec,
|
|
492
512
|
):
|
|
493
513
|
chief_state = clusterization_spec.chief_api_state
|
|
494
514
|
if not chief_state:
|
|
495
515
|
logger.warning("Chief did not return any state")
|
|
496
516
|
return
|
|
497
517
|
|
|
498
|
-
if chief_state not in mlrun.
|
|
518
|
+
if chief_state not in mlrun.common.schemas.APIStates.terminal_states():
|
|
499
519
|
logger.debug(
|
|
500
520
|
"Chief did not reach online state yet, will retry after sync interval",
|
|
501
521
|
interval=config.httpdb.clusterization.worker.sync_with_chief.interval,
|
|
@@ -505,7 +525,7 @@ async def _align_worker_state_with_chief_state(
|
|
|
505
525
|
config.httpdb.state = chief_state
|
|
506
526
|
return
|
|
507
527
|
|
|
508
|
-
if chief_state == mlrun.
|
|
528
|
+
if chief_state == mlrun.common.schemas.APIStates.online:
|
|
509
529
|
logger.info("Chief reached online state! Switching worker state to online")
|
|
510
530
|
await move_api_to_online()
|
|
511
531
|
logger.info("Worker state reached online")
|
|
@@ -522,18 +542,20 @@ async def _align_worker_state_with_chief_state(
|
|
|
522
542
|
|
|
523
543
|
|
|
524
544
|
def _monitor_runs():
|
|
545
|
+
db = get_db()
|
|
525
546
|
db_session = create_session()
|
|
526
547
|
try:
|
|
527
548
|
for kind in RuntimeKinds.runtime_with_handlers():
|
|
528
549
|
try:
|
|
529
550
|
runtime_handler = get_runtime_handler(kind)
|
|
530
|
-
runtime_handler.monitor_runs(
|
|
551
|
+
runtime_handler.monitor_runs(db, db_session)
|
|
531
552
|
except Exception as exc:
|
|
532
553
|
logger.warning(
|
|
533
554
|
"Failed monitoring runs. Ignoring",
|
|
534
555
|
exc=err_to_str(exc),
|
|
535
556
|
kind=kind,
|
|
536
557
|
)
|
|
558
|
+
_push_terminal_run_notifications(db, db_session)
|
|
537
559
|
finally:
|
|
538
560
|
close_session(db_session)
|
|
539
561
|
|
|
@@ -555,6 +577,50 @@ def _cleanup_runtimes():
|
|
|
555
577
|
close_session(db_session)
|
|
556
578
|
|
|
557
579
|
|
|
580
|
+
def _push_terminal_run_notifications(db: mlrun.api.db.base.DBInterface, db_session):
|
|
581
|
+
"""
|
|
582
|
+
Get all runs with notification configs which became terminal since the last call to the function
|
|
583
|
+
and push their notifications if they haven't been pushed yet.
|
|
584
|
+
"""
|
|
585
|
+
# Import here to avoid circular import
|
|
586
|
+
import mlrun.api.api.utils
|
|
587
|
+
|
|
588
|
+
# When pushing notifications, push notifications only for runs that entered a terminal state
|
|
589
|
+
# since the last time we pushed notifications.
|
|
590
|
+
# On the first time we push notifications, we'll push notifications for all runs that are in a terminal state
|
|
591
|
+
# and their notifications haven't been sent yet.
|
|
592
|
+
global _last_notification_push_time
|
|
593
|
+
|
|
594
|
+
now = datetime.datetime.now(datetime.timezone.utc)
|
|
595
|
+
|
|
596
|
+
runs = db.list_runs(
|
|
597
|
+
db_session,
|
|
598
|
+
project="*",
|
|
599
|
+
states=mlrun.runtimes.constants.RunStates.terminal_states(),
|
|
600
|
+
last_update_time_from=_last_notification_push_time,
|
|
601
|
+
with_notifications=True,
|
|
602
|
+
)
|
|
603
|
+
|
|
604
|
+
if not len(runs):
|
|
605
|
+
return
|
|
606
|
+
|
|
607
|
+
# Unmasking the run parameters from secrets before handing them over to the notification handler
|
|
608
|
+
# as importing the `Secrets` crud in the notification handler will cause a circular import
|
|
609
|
+
unmasked_runs = [
|
|
610
|
+
mlrun.api.api.utils.unmask_notification_params_secret_on_task(
|
|
611
|
+
db, db_session, run
|
|
612
|
+
)
|
|
613
|
+
for run in runs
|
|
614
|
+
]
|
|
615
|
+
|
|
616
|
+
logger.debug(
|
|
617
|
+
"Got terminal runs with configured notifications", runs_amount=len(runs)
|
|
618
|
+
)
|
|
619
|
+
mlrun.utils.notifications.NotificationPusher(unmasked_runs).push(db)
|
|
620
|
+
|
|
621
|
+
_last_notification_push_time = now
|
|
622
|
+
|
|
623
|
+
|
|
558
624
|
async def _stop_logs():
|
|
559
625
|
"""
|
|
560
626
|
Stop logs for runs that are in terminal state and last updated in the previous interval
|
|
@@ -607,16 +673,19 @@ async def _stop_logs_for_runs(runs: list):
|
|
|
607
673
|
|
|
608
674
|
|
|
609
675
|
def main():
|
|
610
|
-
if
|
|
676
|
+
if (
|
|
677
|
+
config.httpdb.clusterization.role
|
|
678
|
+
== mlrun.common.schemas.ClusterizationRole.chief
|
|
679
|
+
):
|
|
611
680
|
init_data()
|
|
612
681
|
elif (
|
|
613
682
|
config.httpdb.clusterization.worker.sync_with_chief.mode
|
|
614
|
-
== mlrun.
|
|
683
|
+
== mlrun.common.schemas.WaitForChiefToReachOnlineStateFeatureFlag.enabled
|
|
615
684
|
and config.httpdb.clusterization.role
|
|
616
|
-
== mlrun.
|
|
685
|
+
== mlrun.common.schemas.ClusterizationRole.worker
|
|
617
686
|
):
|
|
618
687
|
# we set this state to mark the phase between the startup of the instance until we able to pull the chief state
|
|
619
|
-
config.httpdb.state = mlrun.
|
|
688
|
+
config.httpdb.state = mlrun.common.schemas.APIStates.waiting_for_chief
|
|
620
689
|
|
|
621
690
|
logger.info(
|
|
622
691
|
"Starting API server",
|
mlrun/api/middlewares.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,7 +21,7 @@ import fastapi
|
|
|
21
21
|
import uvicorn.protocols.utils
|
|
22
22
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
23
23
|
|
|
24
|
-
import mlrun.
|
|
24
|
+
import mlrun.common.schemas.constants
|
|
25
25
|
from mlrun.config import config
|
|
26
26
|
from mlrun.utils import logger
|
|
27
27
|
|
|
@@ -46,6 +46,7 @@ async def log_request_response(request: fastapi.Request, call_next):
|
|
|
46
46
|
path_with_query_string = uvicorn.protocols.utils.get_path_with_query_string(
|
|
47
47
|
request.scope
|
|
48
48
|
)
|
|
49
|
+
request.state.request_id = request_id
|
|
49
50
|
start_time = time.perf_counter_ns()
|
|
50
51
|
if not any(
|
|
51
52
|
silent_logging_path in path_with_query_string
|
|
@@ -100,7 +101,7 @@ async def ui_clear_cache(request: fastapi.Request, call_next):
|
|
|
100
101
|
This middleware tells ui when to clear its cache based on backend version changes.
|
|
101
102
|
"""
|
|
102
103
|
ui_version = request.headers.get(
|
|
103
|
-
mlrun.
|
|
104
|
+
mlrun.common.schemas.constants.HeaderNames.ui_version, ""
|
|
104
105
|
)
|
|
105
106
|
response: fastapi.Response = await call_next(request)
|
|
106
107
|
development_version = config.version.startswith("0.0.0")
|
|
@@ -117,7 +118,7 @@ async def ui_clear_cache(request: fastapi.Request, call_next):
|
|
|
117
118
|
|
|
118
119
|
# tell ui to reload
|
|
119
120
|
response.headers[
|
|
120
|
-
mlrun.
|
|
121
|
+
mlrun.common.schemas.constants.HeaderNames.ui_clear_cache
|
|
121
122
|
] = "true"
|
|
122
123
|
return response
|
|
123
124
|
|
|
@@ -128,7 +129,7 @@ async def ensure_be_version(request: fastapi.Request, call_next):
|
|
|
128
129
|
"""
|
|
129
130
|
response: fastapi.Response = await call_next(request)
|
|
130
131
|
response.headers[
|
|
131
|
-
mlrun.
|
|
132
|
+
mlrun.common.schemas.constants.HeaderNames.backend_version
|
|
132
133
|
] = config.version
|
|
133
134
|
return response
|
|
134
135
|
|
|
@@ -0,0 +1,40 @@
|
|
|
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
|
+
"""market_place_to_hub
|
|
16
|
+
|
|
17
|
+
Revision ID: 28383af526f3
|
|
18
|
+
Revises: c905d15bd91d
|
|
19
|
+
Create Date: 2023-04-24 11:06:36.177314
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
from alembic import op
|
|
23
|
+
|
|
24
|
+
# revision identifiers, used by Alembic.
|
|
25
|
+
revision = "28383af526f3"
|
|
26
|
+
down_revision = "c905d15bd91d"
|
|
27
|
+
branch_labels = None
|
|
28
|
+
depends_on = None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def upgrade():
|
|
32
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
33
|
+
op.rename_table("marketplace_sources", "hub_sources")
|
|
34
|
+
# ### end Alembic commands ###
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def downgrade():
|
|
38
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
39
|
+
op.rename_table("hub_sources", "marketplace_sources")
|
|
40
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,72 @@
|
|
|
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
|
+
"""notifications
|
|
16
|
+
|
|
17
|
+
Revision ID: c905d15bd91d
|
|
18
|
+
Revises: 88e656800d6a
|
|
19
|
+
Create Date: 2022-09-20 10:44:41.727488
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
import sqlalchemy as sa
|
|
23
|
+
from alembic import op
|
|
24
|
+
from sqlalchemy.dialects import mysql
|
|
25
|
+
|
|
26
|
+
# revision identifiers, used by Alembic.
|
|
27
|
+
revision = "c905d15bd91d"
|
|
28
|
+
down_revision = "88e656800d6a"
|
|
29
|
+
branch_labels = None
|
|
30
|
+
depends_on = None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def upgrade():
|
|
34
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
35
|
+
op.create_table(
|
|
36
|
+
"runs_notifications",
|
|
37
|
+
sa.Column("id", sa.Integer(), nullable=False),
|
|
38
|
+
sa.Column("project", sa.String(length=255, collation="utf8_bin")),
|
|
39
|
+
sa.Column("name", sa.String(length=255, collation="utf8_bin"), nullable=False),
|
|
40
|
+
sa.Column("kind", sa.String(length=255, collation="utf8_bin"), nullable=False),
|
|
41
|
+
sa.Column(
|
|
42
|
+
"message", sa.String(length=255, collation="utf8_bin"), nullable=False
|
|
43
|
+
),
|
|
44
|
+
sa.Column(
|
|
45
|
+
"severity", sa.String(length=255, collation="utf8_bin"), nullable=False
|
|
46
|
+
),
|
|
47
|
+
sa.Column("when", sa.String(length=255, collation="utf8_bin"), nullable=False),
|
|
48
|
+
sa.Column(
|
|
49
|
+
"condition", sa.String(length=255, collation="utf8_bin"), nullable=False
|
|
50
|
+
),
|
|
51
|
+
sa.Column("params", sa.JSON(), nullable=True),
|
|
52
|
+
# A generic parent_id rather than run_id since notification table is standard across objects, see the
|
|
53
|
+
# make_notification function for its definition and usage.
|
|
54
|
+
sa.Column("parent_id", sa.Integer(), nullable=True),
|
|
55
|
+
sa.Column("sent_time", mysql.TIMESTAMP(fsp=3), nullable=True),
|
|
56
|
+
sa.Column(
|
|
57
|
+
"status", sa.String(length=255, collation="utf8_bin"), nullable=False
|
|
58
|
+
),
|
|
59
|
+
sa.ForeignKeyConstraint(
|
|
60
|
+
["parent_id"],
|
|
61
|
+
["runs.id"],
|
|
62
|
+
),
|
|
63
|
+
sa.PrimaryKeyConstraint("id"),
|
|
64
|
+
sa.UniqueConstraint("name", "parent_id", name="_runs_notifications_uc"),
|
|
65
|
+
)
|
|
66
|
+
# ### end Alembic commands ###
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def downgrade():
|
|
70
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
71
|
+
op.drop_table("notifications")
|
|
72
|
+
# ### end Alembic commands ###
|