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
mlrun/runtimes/generators.py
CHANGED
mlrun/runtimes/kubejob.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.
|
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
|
|
15
15
|
import os
|
|
16
16
|
import time
|
|
17
|
+
import warnings
|
|
17
18
|
|
|
18
19
|
from kubernetes import client
|
|
19
20
|
from kubernetes.client.rest import ApiException
|
|
20
21
|
|
|
21
|
-
import mlrun.
|
|
22
|
+
import mlrun.common.schemas
|
|
22
23
|
import mlrun.errors
|
|
23
24
|
from mlrun.runtimes.base import BaseRuntimeHandler
|
|
24
25
|
|
|
25
|
-
from ..builder import build_runtime
|
|
26
26
|
from ..db import RunDBError
|
|
27
27
|
from ..errors import err_to_str
|
|
28
28
|
from ..kfpops import build_op
|
|
@@ -30,7 +30,7 @@ from ..model import RunObject
|
|
|
30
30
|
from ..utils import get_in, logger
|
|
31
31
|
from .base import RunError, RuntimeClassMode
|
|
32
32
|
from .pod import KubeResource, kube_resource_spec_to_pod_spec
|
|
33
|
-
from .utils import
|
|
33
|
+
from .utils import get_k8s
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
class KubejobRuntime(KubeResource):
|
|
@@ -44,12 +44,13 @@ class KubejobRuntime(KubeResource):
|
|
|
44
44
|
if self.spec.image:
|
|
45
45
|
return True
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
db = self._get_db()
|
|
48
|
+
try:
|
|
49
|
+
# getting builder status enriches the runtime when it needs to be fetched from the API,
|
|
50
|
+
# otherwise it's a no-op
|
|
51
|
+
db.get_builder_status(self, logs=False)
|
|
52
|
+
except Exception:
|
|
53
|
+
pass
|
|
53
54
|
|
|
54
55
|
if self.spec.image:
|
|
55
56
|
return True
|
|
@@ -58,27 +59,30 @@ class KubejobRuntime(KubeResource):
|
|
|
58
59
|
return False
|
|
59
60
|
|
|
60
61
|
def with_source_archive(
|
|
61
|
-
self, source, workdir=None, handler=None, pull_at_runtime=True
|
|
62
|
+
self, source, workdir=None, handler=None, pull_at_runtime=True, target_dir=None
|
|
62
63
|
):
|
|
63
64
|
"""load the code from git/tar/zip archive at runtime or build
|
|
64
65
|
|
|
65
|
-
:param source:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
:param source: valid absolute path or URL to git, zip, or tar file, e.g.
|
|
67
|
+
git://github.com/mlrun/something.git
|
|
68
|
+
http://some/url/file.zip
|
|
69
|
+
note path source must exist on the image or exist locally when run is local
|
|
70
|
+
(it is recommended to use 'workdir' when source is a filepath instead)
|
|
71
|
+
:param handler: default function handler
|
|
72
|
+
:param workdir: working dir relative to the archive root (e.g. './subdir') or absolute to the image root
|
|
70
73
|
:param pull_at_runtime: load the archive into the container at job runtime vs on build/deploy
|
|
74
|
+
:param target_dir: target dir on runtime pod or repo clone / archive extraction
|
|
71
75
|
"""
|
|
72
|
-
|
|
73
|
-
logger.warn(
|
|
74
|
-
"zip files are not natively extracted by docker, use tar.gz for faster loading during build"
|
|
75
|
-
)
|
|
76
|
+
mlrun.utils.helpers.validate_builder_source(source, pull_at_runtime, workdir)
|
|
76
77
|
|
|
77
78
|
self.spec.build.source = source
|
|
78
79
|
if handler:
|
|
79
80
|
self.spec.default_handler = handler
|
|
80
81
|
if workdir:
|
|
81
82
|
self.spec.workdir = workdir
|
|
83
|
+
if target_dir:
|
|
84
|
+
self.spec.clone_target_dir = target_dir
|
|
85
|
+
|
|
82
86
|
self.spec.build.load_source_on_run = pull_at_runtime
|
|
83
87
|
if (
|
|
84
88
|
self.spec.build.base_image
|
|
@@ -86,7 +90,7 @@ class KubejobRuntime(KubeResource):
|
|
|
86
90
|
and pull_at_runtime
|
|
87
91
|
and not self.spec.image
|
|
88
92
|
):
|
|
89
|
-
# if we load source from repo and
|
|
93
|
+
# if we load source from repo and don't need a full build use the base_image as the image
|
|
90
94
|
self.spec.image = self.spec.build.base_image
|
|
91
95
|
elif not pull_at_runtime:
|
|
92
96
|
# clear the image so build will not be skipped
|
|
@@ -106,7 +110,9 @@ class KubejobRuntime(KubeResource):
|
|
|
106
110
|
auto_build=None,
|
|
107
111
|
requirements=None,
|
|
108
112
|
overwrite=False,
|
|
109
|
-
verify_base_image=
|
|
113
|
+
verify_base_image=False,
|
|
114
|
+
prepare_image_for_deploy=True,
|
|
115
|
+
requirements_file=None,
|
|
110
116
|
):
|
|
111
117
|
"""specify builder configuration for the deploy operation
|
|
112
118
|
|
|
@@ -121,43 +127,43 @@ class KubejobRuntime(KubeResource):
|
|
|
121
127
|
:param with_mlrun: add the current mlrun package to the container build
|
|
122
128
|
:param auto_build: when set to True and the function require build it will be built on the first
|
|
123
129
|
function run, use only if you dont plan on changing the build config between runs
|
|
124
|
-
:param requirements:
|
|
130
|
+
:param requirements: a list of packages to install
|
|
131
|
+
:param requirements_file: requirements file to install
|
|
125
132
|
:param overwrite: overwrite existing build configuration
|
|
126
133
|
|
|
127
134
|
* False: the new params are merged with the existing (currently merge is applied to requirements and
|
|
128
135
|
commands)
|
|
129
136
|
* True: the existing params are replaced by the new ones
|
|
130
|
-
:param verify_base_image:
|
|
137
|
+
:param verify_base_image: verify that the base image is configured
|
|
138
|
+
(deprecated, use prepare_image_for_deploy)
|
|
139
|
+
:param prepare_image_for_deploy: prepare the image/base_image spec for deployment
|
|
131
140
|
"""
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
self.
|
|
158
|
-
|
|
159
|
-
if verify_base_image:
|
|
160
|
-
self.verify_base_image()
|
|
141
|
+
|
|
142
|
+
image = mlrun.utils.helpers.remove_image_protocol_prefix(image)
|
|
143
|
+
self.spec.build.build_config(
|
|
144
|
+
image,
|
|
145
|
+
base_image,
|
|
146
|
+
commands,
|
|
147
|
+
secret,
|
|
148
|
+
source,
|
|
149
|
+
extra,
|
|
150
|
+
load_source_on_run,
|
|
151
|
+
with_mlrun,
|
|
152
|
+
auto_build,
|
|
153
|
+
requirements,
|
|
154
|
+
requirements_file,
|
|
155
|
+
overwrite,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
if verify_base_image or prepare_image_for_deploy:
|
|
159
|
+
if verify_base_image:
|
|
160
|
+
# TODO: remove verify_base_image in 1.6.0
|
|
161
|
+
warnings.warn(
|
|
162
|
+
"verify_base_image is deprecated in 1.4.0 and will be removed in 1.6.0, "
|
|
163
|
+
"use prepare_image_for_deploy",
|
|
164
|
+
category=FutureWarning,
|
|
165
|
+
)
|
|
166
|
+
self.prepare_image_for_deploy()
|
|
161
167
|
|
|
162
168
|
def deploy(
|
|
163
169
|
self,
|
|
@@ -194,7 +200,13 @@ class KubejobRuntime(KubeResource):
|
|
|
194
200
|
or "/mlrun/" in build.base_image
|
|
195
201
|
)
|
|
196
202
|
|
|
197
|
-
if
|
|
203
|
+
if (
|
|
204
|
+
not build.source
|
|
205
|
+
and not build.commands
|
|
206
|
+
and not build.requirements
|
|
207
|
+
and not build.extra
|
|
208
|
+
and with_mlrun
|
|
209
|
+
):
|
|
198
210
|
logger.info(
|
|
199
211
|
"running build to add mlrun package, set "
|
|
200
212
|
"with_mlrun=False to skip if its already in the image"
|
|
@@ -209,6 +221,7 @@ class KubejobRuntime(KubeResource):
|
|
|
209
221
|
if is_kfp:
|
|
210
222
|
watch = True
|
|
211
223
|
|
|
224
|
+
ready = False
|
|
212
225
|
if self._is_remote_api():
|
|
213
226
|
db = self._get_db()
|
|
214
227
|
data = db.remote_builder(
|
|
@@ -223,6 +236,8 @@ class KubejobRuntime(KubeResource):
|
|
|
223
236
|
self.spec.build.base_image = self.spec.build.base_image or get_in(
|
|
224
237
|
data, "data.spec.build.base_image"
|
|
225
238
|
)
|
|
239
|
+
# get the clone target dir in case it was enriched due to loading source
|
|
240
|
+
self.spec.clone_target_dir = get_in(data, "data.spec.clone_target_dir")
|
|
226
241
|
ready = data.get("ready", False)
|
|
227
242
|
if not ready:
|
|
228
243
|
logger.info(
|
|
@@ -232,17 +247,6 @@ class KubejobRuntime(KubeResource):
|
|
|
232
247
|
state = self._build_watch(watch, show_on_failure=show_on_failure)
|
|
233
248
|
ready = state == "ready"
|
|
234
249
|
self.status.state = state
|
|
235
|
-
else:
|
|
236
|
-
self.save(versioned=False)
|
|
237
|
-
ready = build_runtime(
|
|
238
|
-
mlrun.api.schemas.AuthInfo(),
|
|
239
|
-
self,
|
|
240
|
-
with_mlrun,
|
|
241
|
-
mlrun_version_specifier,
|
|
242
|
-
skip_deployed,
|
|
243
|
-
watch,
|
|
244
|
-
)
|
|
245
|
-
self.save(versioned=False)
|
|
246
250
|
|
|
247
251
|
if watch and not ready:
|
|
248
252
|
raise mlrun.errors.MLRunRuntimeError("Deploy failed")
|
|
@@ -279,36 +283,6 @@ class KubejobRuntime(KubeResource):
|
|
|
279
283
|
print()
|
|
280
284
|
return self.status.state
|
|
281
285
|
|
|
282
|
-
def builder_status(self, watch=True, logs=True):
|
|
283
|
-
if self._is_remote_api():
|
|
284
|
-
return self._build_watch(watch, logs)
|
|
285
|
-
|
|
286
|
-
else:
|
|
287
|
-
pod = self.status.build_pod
|
|
288
|
-
if not self.status.state == "ready" and pod:
|
|
289
|
-
k8s = self._get_k8s()
|
|
290
|
-
status = k8s.get_pod_status(pod)
|
|
291
|
-
if logs:
|
|
292
|
-
if watch:
|
|
293
|
-
status = k8s.watch(pod)
|
|
294
|
-
else:
|
|
295
|
-
resp = k8s.logs(pod)
|
|
296
|
-
if resp:
|
|
297
|
-
print(resp.encode())
|
|
298
|
-
|
|
299
|
-
if status == "succeeded":
|
|
300
|
-
self.status.build_pod = None
|
|
301
|
-
self.status.state = "ready"
|
|
302
|
-
logger.info("build completed successfully")
|
|
303
|
-
return "ready"
|
|
304
|
-
if status in ["failed", "error"]:
|
|
305
|
-
self.status.state = status
|
|
306
|
-
logger.error(f" build {status}, watch the build pod logs: {pod}")
|
|
307
|
-
return status
|
|
308
|
-
|
|
309
|
-
logger.info(f"builder status is: {status}, wait for it to complete")
|
|
310
|
-
return None
|
|
311
|
-
|
|
312
286
|
def deploy_step(
|
|
313
287
|
self,
|
|
314
288
|
image=None,
|
|
@@ -335,23 +309,14 @@ class KubejobRuntime(KubeResource):
|
|
|
335
309
|
)
|
|
336
310
|
|
|
337
311
|
def _run(self, runobj: RunObject, execution):
|
|
338
|
-
|
|
339
312
|
command, args, extra_env = self._get_cmd_args(runobj)
|
|
340
313
|
|
|
341
314
|
if runobj.metadata.iteration:
|
|
342
315
|
self.store_run(runobj)
|
|
343
|
-
k8s = self._get_k8s()
|
|
344
316
|
new_meta = self._get_meta(runobj)
|
|
345
317
|
|
|
346
318
|
self._add_secrets_to_spec_before_running(runobj)
|
|
347
|
-
workdir = self.
|
|
348
|
-
if workdir:
|
|
349
|
-
if self.spec.build.source and self.spec.build.load_source_on_run:
|
|
350
|
-
# workdir will be set AFTER the clone
|
|
351
|
-
workdir = None
|
|
352
|
-
elif not workdir.startswith("/"):
|
|
353
|
-
# relative path mapped to real path in the job pod
|
|
354
|
-
workdir = os.path.join("/mlrun", workdir)
|
|
319
|
+
workdir = self._resolve_workdir()
|
|
355
320
|
|
|
356
321
|
pod_spec = func_to_pod(
|
|
357
322
|
self.full_image_path(
|
|
@@ -368,23 +333,41 @@ class KubejobRuntime(KubeResource):
|
|
|
368
333
|
)
|
|
369
334
|
pod = client.V1Pod(metadata=new_meta, spec=pod_spec)
|
|
370
335
|
try:
|
|
371
|
-
pod_name, namespace =
|
|
336
|
+
pod_name, namespace = get_k8s().create_pod(pod)
|
|
372
337
|
except ApiException as exc:
|
|
373
338
|
raise RunError(err_to_str(exc))
|
|
374
339
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if status in ["failed", "error"]:
|
|
380
|
-
raise RunError(f"pod exited with {status}, check logs")
|
|
381
|
-
else:
|
|
382
|
-
txt = f"Job is running in the background, pod: {pod_name}"
|
|
383
|
-
logger.info(txt)
|
|
384
|
-
runobj.status.status_text = txt
|
|
340
|
+
txt = f"Job is running in the background, pod: {pod_name}"
|
|
341
|
+
logger.info(txt)
|
|
342
|
+
runobj.status.status_text = txt
|
|
385
343
|
|
|
386
344
|
return None
|
|
387
345
|
|
|
346
|
+
def _resolve_workdir(self):
|
|
347
|
+
"""
|
|
348
|
+
The workdir is relative to the source root, if the source is not loaded on run then the workdir
|
|
349
|
+
is relative to the clone target dir (where the source was copied to).
|
|
350
|
+
Otherwise, if the source is loaded on run, the workdir is resolved on the run as well.
|
|
351
|
+
If the workdir is absolute, keep it as is.
|
|
352
|
+
"""
|
|
353
|
+
workdir = self.spec.workdir
|
|
354
|
+
if self.spec.build.source and self.spec.build.load_source_on_run:
|
|
355
|
+
# workdir will be set AFTER the clone which is done in the pre-run of local runtime
|
|
356
|
+
return None
|
|
357
|
+
|
|
358
|
+
if workdir and os.path.isabs(workdir):
|
|
359
|
+
return workdir
|
|
360
|
+
|
|
361
|
+
if self.spec.clone_target_dir:
|
|
362
|
+
workdir = workdir or ""
|
|
363
|
+
if workdir.startswith("./"):
|
|
364
|
+
# TODO: use 'removeprefix' when we drop python 3.7 support
|
|
365
|
+
# workdir.removeprefix("./")
|
|
366
|
+
workdir = workdir[2:]
|
|
367
|
+
return os.path.join(self.spec.clone_target_dir, workdir)
|
|
368
|
+
|
|
369
|
+
return workdir
|
|
370
|
+
|
|
388
371
|
|
|
389
372
|
def func_to_pod(image, runtime, extra_env, command, args, workdir):
|
|
390
373
|
container = client.V1Container(
|
mlrun/runtimes/local.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.
|
|
@@ -41,7 +41,7 @@ from ..execution import MLClientCtx
|
|
|
41
41
|
from ..model import RunObject
|
|
42
42
|
from ..utils import get_handler_extended, get_in, logger, set_paths
|
|
43
43
|
from ..utils.clones import extract_source
|
|
44
|
-
from .base import BaseRuntime
|
|
44
|
+
from .base import BaseRuntime
|
|
45
45
|
from .kubejob import KubejobRuntime
|
|
46
46
|
from .remotesparkjob import RemoteSparkRuntime
|
|
47
47
|
from .utils import RunError, global_context, log_std
|
|
@@ -172,48 +172,10 @@ class HandlerRuntime(BaseRuntime, ParallelRunner):
|
|
|
172
172
|
return context.to_dict()
|
|
173
173
|
|
|
174
174
|
|
|
175
|
-
class LocalFunctionSpec(FunctionSpec):
|
|
176
|
-
_dict_fields = spec_fields + ["clone_target_dir"]
|
|
177
|
-
|
|
178
|
-
def __init__(
|
|
179
|
-
self,
|
|
180
|
-
command=None,
|
|
181
|
-
args=None,
|
|
182
|
-
mode=None,
|
|
183
|
-
default_handler=None,
|
|
184
|
-
pythonpath=None,
|
|
185
|
-
entry_points=None,
|
|
186
|
-
description=None,
|
|
187
|
-
workdir=None,
|
|
188
|
-
build=None,
|
|
189
|
-
clone_target_dir=None,
|
|
190
|
-
):
|
|
191
|
-
super().__init__(
|
|
192
|
-
command=command,
|
|
193
|
-
args=args,
|
|
194
|
-
mode=mode,
|
|
195
|
-
build=build,
|
|
196
|
-
entry_points=entry_points,
|
|
197
|
-
description=description,
|
|
198
|
-
workdir=workdir,
|
|
199
|
-
default_handler=default_handler,
|
|
200
|
-
pythonpath=pythonpath,
|
|
201
|
-
)
|
|
202
|
-
self.clone_target_dir = clone_target_dir
|
|
203
|
-
|
|
204
|
-
|
|
205
175
|
class LocalRuntime(BaseRuntime, ParallelRunner):
|
|
206
176
|
kind = "local"
|
|
207
177
|
_is_remote = False
|
|
208
178
|
|
|
209
|
-
@property
|
|
210
|
-
def spec(self) -> LocalFunctionSpec:
|
|
211
|
-
return self._spec
|
|
212
|
-
|
|
213
|
-
@spec.setter
|
|
214
|
-
def spec(self, spec):
|
|
215
|
-
self._spec = self._verify_dict(spec, "spec", LocalFunctionSpec)
|
|
216
|
-
|
|
217
179
|
def to_job(self, image=""):
|
|
218
180
|
struct = self.to_dict()
|
|
219
181
|
obj = KubejobRuntime.from_dict(struct)
|
|
@@ -224,12 +186,12 @@ class LocalRuntime(BaseRuntime, ParallelRunner):
|
|
|
224
186
|
def with_source_archive(self, source, workdir=None, handler=None, target_dir=None):
|
|
225
187
|
"""load the code from git/tar/zip archive at runtime or build
|
|
226
188
|
|
|
227
|
-
:param source:
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
:param handler:
|
|
231
|
-
:param workdir:
|
|
232
|
-
:param target_dir:
|
|
189
|
+
:param source: valid path to git, zip, or tar file, e.g.
|
|
190
|
+
git://github.com/mlrun/something.git
|
|
191
|
+
http://some/url/file.zip
|
|
192
|
+
:param handler: default function handler
|
|
193
|
+
:param workdir: working dir relative to the archive root (e.g. './subdir') or absolute
|
|
194
|
+
:param target_dir: local target dir for repo clone (by default its <current-dir>/code)
|
|
233
195
|
"""
|
|
234
196
|
self.spec.build.source = source
|
|
235
197
|
self.spec.build.load_source_on_run = True
|
|
@@ -255,6 +217,8 @@ class LocalRuntime(BaseRuntime, ParallelRunner):
|
|
|
255
217
|
execution._current_workdir = workdir
|
|
256
218
|
execution._old_workdir = None
|
|
257
219
|
|
|
220
|
+
# _is_run_local is set when the user specifies local=True in run()
|
|
221
|
+
# in this case we don't want to extract the source code and contaminate the user's local dir
|
|
258
222
|
if self.spec.build.source and not hasattr(self, "_is_run_local"):
|
|
259
223
|
target_dir = extract_source(
|
|
260
224
|
self.spec.build.source,
|
|
@@ -456,7 +420,7 @@ def exec_from_params(handler, runobj: RunObject, context: MLClientCtx, cwd=None)
|
|
|
456
420
|
if runobj.spec.verbose:
|
|
457
421
|
logger.set_logger_level("DEBUG")
|
|
458
422
|
|
|
459
|
-
# Prepare the inputs type hints (user may pass type hints as part of the
|
|
423
|
+
# Prepare the inputs type hints (user may pass type hints as part of the input keys):
|
|
460
424
|
runobj.spec.extract_type_hints_from_inputs()
|
|
461
425
|
# Read the keyword arguments to pass to the function (combining params and inputs from the run spec):
|
|
462
426
|
kwargs = get_func_arg(handler, runobj, context)
|
|
@@ -471,20 +435,23 @@ def exec_from_params(handler, runobj: RunObject, context: MLClientCtx, cwd=None)
|
|
|
471
435
|
if cwd:
|
|
472
436
|
os.chdir(cwd)
|
|
473
437
|
# Apply the MLRun handler decorator for parsing inputs using type hints and logging outputs using log hints
|
|
474
|
-
# (Expected behavior: inputs are being parsed when they have type hints in code or given by user.
|
|
475
|
-
#
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
438
|
+
# (Expected behavior: inputs are being parsed when they have type hints in code or given by user. Outputs
|
|
439
|
+
# are logged only if log hints are provided by the user):
|
|
440
|
+
if mlrun.mlconf.packagers.enabled:
|
|
441
|
+
val = mlrun.handler(
|
|
442
|
+
inputs=(
|
|
443
|
+
runobj.spec.inputs_type_hints
|
|
444
|
+
if runobj.spec.inputs_type_hints
|
|
445
|
+
else True # True will use type hints if provided in user's code.
|
|
446
|
+
),
|
|
447
|
+
outputs=(
|
|
448
|
+
runobj.spec.returns
|
|
449
|
+
if runobj.spec.returns
|
|
450
|
+
else None # None will turn off outputs logging.
|
|
451
|
+
),
|
|
452
|
+
)(handler)(**kwargs)
|
|
453
|
+
else:
|
|
454
|
+
val = handler(**kwargs)
|
|
488
455
|
context.set_state("completed", commit=False)
|
|
489
456
|
except Exception as exc:
|
|
490
457
|
err = err_to_str(exc)
|
|
@@ -511,6 +478,18 @@ def get_func_arg(handler, runobj: RunObject, context: MLClientCtx, is_nuclio=Fal
|
|
|
511
478
|
kwargs = {}
|
|
512
479
|
args = inspect.signature(handler).parameters
|
|
513
480
|
|
|
481
|
+
def _get_input_value(input_key: str):
|
|
482
|
+
input_obj = context.get_input(input_key, inputs[input_key])
|
|
483
|
+
# If there is no type hint annotation but there is a default value and its type is string, point the data
|
|
484
|
+
# item to local downloaded file path (`local()` returns the downloaded temp path string):
|
|
485
|
+
if (
|
|
486
|
+
args[input_key].annotation is inspect.Parameter.empty
|
|
487
|
+
and type(args[input_key].default) is str
|
|
488
|
+
):
|
|
489
|
+
return input_obj.local()
|
|
490
|
+
else:
|
|
491
|
+
return input_obj
|
|
492
|
+
|
|
514
493
|
for key in args.keys():
|
|
515
494
|
if key == "context":
|
|
516
495
|
kwargs[key] = context
|
|
@@ -519,9 +498,23 @@ def get_func_arg(handler, runobj: RunObject, context: MLClientCtx, is_nuclio=Fal
|
|
|
519
498
|
elif key in params:
|
|
520
499
|
kwargs[key] = copy(params[key])
|
|
521
500
|
elif key in inputs:
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
501
|
+
kwargs[key] = _get_input_value(key)
|
|
502
|
+
|
|
503
|
+
list_of_params = list(args.values())
|
|
504
|
+
if len(list_of_params) == 0:
|
|
505
|
+
return kwargs
|
|
506
|
+
|
|
507
|
+
# get the last parameter, as **kwargs can only be last in the function's parameters list
|
|
508
|
+
last_param = list_of_params[-1]
|
|
509
|
+
# VAR_KEYWORD meaning : A dict of keyword arguments that aren’t bound to any other parameter.
|
|
510
|
+
# This corresponds to a **kwargs parameter in a Python function definition.
|
|
511
|
+
if last_param.kind == last_param.VAR_KEYWORD:
|
|
512
|
+
# if handler has **kwargs, pass all parameters provided by the user to the handler which were not already set
|
|
513
|
+
# as part of the previous loop which handled all parameters which were explicitly defined in the handler
|
|
514
|
+
for key in params:
|
|
515
|
+
if key not in kwargs:
|
|
516
|
+
kwargs[key] = copy(params[key])
|
|
517
|
+
for key in inputs:
|
|
518
|
+
if key not in kwargs:
|
|
519
|
+
kwargs[key] = _get_input_value(key)
|
|
527
520
|
return kwargs
|
|
@@ -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,7 +24,7 @@ from mlrun.execution import MLClientCtx
|
|
|
24
24
|
from mlrun.model import RunObject
|
|
25
25
|
from mlrun.runtimes.kubejob import KubejobRuntime
|
|
26
26
|
from mlrun.runtimes.pod import KubeResourceSpec
|
|
27
|
-
from mlrun.runtimes.utils import RunError
|
|
27
|
+
from mlrun.runtimes.utils import RunError, get_k8s
|
|
28
28
|
from mlrun.utils import get_in, logger
|
|
29
29
|
|
|
30
30
|
|
|
@@ -60,6 +60,7 @@ class MPIResourceSpec(KubeResourceSpec):
|
|
|
60
60
|
tolerations=None,
|
|
61
61
|
preemption_mode=None,
|
|
62
62
|
security_context=None,
|
|
63
|
+
clone_target_dir=None,
|
|
63
64
|
):
|
|
64
65
|
super().__init__(
|
|
65
66
|
command=command,
|
|
@@ -88,6 +89,7 @@ class MPIResourceSpec(KubeResourceSpec):
|
|
|
88
89
|
tolerations=tolerations,
|
|
89
90
|
preemption_mode=preemption_mode,
|
|
90
91
|
security_context=security_context,
|
|
92
|
+
clone_target_dir=clone_target_dir,
|
|
91
93
|
)
|
|
92
94
|
self.mpi_args = mpi_args or [
|
|
93
95
|
"-x",
|
|
@@ -189,10 +191,9 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
|
|
|
189
191
|
def _submit_mpijob(self, job, namespace=None):
|
|
190
192
|
mpi_group, mpi_version, mpi_plural = self._get_crd_info()
|
|
191
193
|
|
|
192
|
-
|
|
193
|
-
namespace = k8s.resolve_namespace(namespace)
|
|
194
|
+
namespace = get_k8s().resolve_namespace(namespace)
|
|
194
195
|
try:
|
|
195
|
-
resp =
|
|
196
|
+
resp = get_k8s().crdapi.create_namespaced_custom_object(
|
|
196
197
|
mpi_group,
|
|
197
198
|
mpi_version,
|
|
198
199
|
namespace=namespace,
|
|
@@ -208,7 +209,7 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
|
|
|
208
209
|
|
|
209
210
|
def delete_job(self, name, namespace=None):
|
|
210
211
|
mpi_group, mpi_version, mpi_plural = self._get_crd_info()
|
|
211
|
-
k8s =
|
|
212
|
+
k8s = get_k8s()
|
|
212
213
|
namespace = k8s.resolve_namespace(namespace)
|
|
213
214
|
try:
|
|
214
215
|
# delete the mpi job
|
|
@@ -223,11 +224,10 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
|
|
|
223
224
|
|
|
224
225
|
def list_jobs(self, namespace=None, selector="", show=True):
|
|
225
226
|
mpi_group, mpi_version, mpi_plural = self._get_crd_info()
|
|
226
|
-
|
|
227
|
-
namespace = k8s.resolve_namespace(namespace)
|
|
227
|
+
namespace = get_k8s().resolve_namespace(namespace)
|
|
228
228
|
items = []
|
|
229
229
|
try:
|
|
230
|
-
resp =
|
|
230
|
+
resp = get_k8s().crdapi.list_namespaced_custom_object(
|
|
231
231
|
mpi_group,
|
|
232
232
|
mpi_version,
|
|
233
233
|
namespace,
|
|
@@ -247,10 +247,9 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
|
|
|
247
247
|
|
|
248
248
|
def get_job(self, name, namespace=None):
|
|
249
249
|
mpi_group, mpi_version, mpi_plural = self._get_crd_info()
|
|
250
|
-
|
|
251
|
-
namespace = k8s.resolve_namespace(namespace)
|
|
250
|
+
namespace = get_k8s().resolve_namespace(namespace)
|
|
252
251
|
try:
|
|
253
|
-
resp =
|
|
252
|
+
resp = get_k8s().crdapi.get_namespaced_custom_object(
|
|
254
253
|
mpi_group, mpi_version, namespace, mpi_plural, name
|
|
255
254
|
)
|
|
256
255
|
except client.exceptions.ApiException as exc:
|
|
@@ -259,12 +258,11 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
|
|
|
259
258
|
return resp
|
|
260
259
|
|
|
261
260
|
def get_pods(self, name=None, namespace=None, launcher=False):
|
|
262
|
-
|
|
263
|
-
namespace = k8s.resolve_namespace(namespace)
|
|
261
|
+
namespace = get_k8s().resolve_namespace(namespace)
|
|
264
262
|
|
|
265
263
|
selector = self._generate_pods_selector(name, launcher)
|
|
266
264
|
|
|
267
|
-
pods =
|
|
265
|
+
pods = get_k8s().list_pods(selector=selector, namespace=namespace)
|
|
268
266
|
if pods:
|
|
269
267
|
return {p.metadata.name: p.status.phase for p in pods}
|
|
270
268
|
|
mlrun/runtimes/mpijob/v1.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.
|
|
@@ -62,6 +62,7 @@ class MPIV1ResourceSpec(MPIResourceSpec):
|
|
|
62
62
|
tolerations=None,
|
|
63
63
|
preemption_mode=None,
|
|
64
64
|
security_context=None,
|
|
65
|
+
clone_target_dir=None,
|
|
65
66
|
):
|
|
66
67
|
super().__init__(
|
|
67
68
|
command=command,
|
|
@@ -91,6 +92,7 @@ class MPIV1ResourceSpec(MPIResourceSpec):
|
|
|
91
92
|
tolerations=tolerations,
|
|
92
93
|
preemption_mode=preemption_mode,
|
|
93
94
|
security_context=security_context,
|
|
95
|
+
clone_target_dir=clone_target_dir,
|
|
94
96
|
)
|
|
95
97
|
self.clean_pod_policy = clean_pod_policy or MPIJobV1CleanPodPolicies.default()
|
|
96
98
|
|