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/run.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.
|
|
@@ -11,32 +11,27 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
import functools
|
|
15
|
-
import importlib
|
|
16
14
|
import importlib.util as imputil
|
|
17
|
-
import inspect
|
|
18
15
|
import json
|
|
19
16
|
import os
|
|
20
17
|
import pathlib
|
|
21
|
-
import re
|
|
22
18
|
import socket
|
|
23
19
|
import tempfile
|
|
24
20
|
import time
|
|
25
21
|
import uuid
|
|
26
22
|
import warnings
|
|
27
23
|
from base64 import b64decode
|
|
28
|
-
from collections import OrderedDict
|
|
29
24
|
from copy import deepcopy
|
|
30
25
|
from os import environ, makedirs, path
|
|
31
26
|
from pathlib import Path
|
|
32
|
-
from typing import
|
|
27
|
+
from typing import Dict, List, Optional, Tuple, Union
|
|
33
28
|
|
|
34
29
|
import nuclio
|
|
35
30
|
import yaml
|
|
36
31
|
from deprecated import deprecated
|
|
37
32
|
from kfp import Client
|
|
38
33
|
|
|
39
|
-
import mlrun.
|
|
34
|
+
import mlrun.common.schemas
|
|
40
35
|
import mlrun.errors
|
|
41
36
|
import mlrun.utils.helpers
|
|
42
37
|
from mlrun.kfpops import format_summary_from_kfp_run, show_kfp_run
|
|
@@ -44,6 +39,7 @@ from mlrun.kfpops import format_summary_from_kfp_run, show_kfp_run
|
|
|
44
39
|
from .config import config as mlconf
|
|
45
40
|
from .datastore import store_manager
|
|
46
41
|
from .db import get_or_set_dburl, get_run_db
|
|
42
|
+
from .errors import MLRunInvalidArgumentError, MLRunTimeoutError
|
|
47
43
|
from .execution import MLClientCtx
|
|
48
44
|
from .model import BaseMetadata, RunObject, RunTemplate
|
|
49
45
|
from .runtimes import (
|
|
@@ -57,12 +53,10 @@ from .runtimes import (
|
|
|
57
53
|
RemoteSparkRuntime,
|
|
58
54
|
RuntimeKinds,
|
|
59
55
|
ServingRuntime,
|
|
60
|
-
Spark2Runtime,
|
|
61
56
|
Spark3Runtime,
|
|
62
57
|
get_runtime_class,
|
|
63
58
|
)
|
|
64
59
|
from .runtimes.funcdoc import update_function_entry_points
|
|
65
|
-
from .runtimes.package.context_handler import ArtifactType, ContextHandler
|
|
66
60
|
from .runtimes.serving import serving_subkind
|
|
67
61
|
from .runtimes.utils import add_code_metadata, global_context
|
|
68
62
|
from .utils import (
|
|
@@ -112,6 +106,12 @@ class RunStatuses(object):
|
|
|
112
106
|
]
|
|
113
107
|
|
|
114
108
|
|
|
109
|
+
# TODO: remove in 1.6.0
|
|
110
|
+
@deprecated(
|
|
111
|
+
version="1.4.0",
|
|
112
|
+
reason="'run_local' will be removed in 1.6.0, use 'function.run(local=True)' instead",
|
|
113
|
+
category=FutureWarning,
|
|
114
|
+
)
|
|
115
115
|
def run_local(
|
|
116
116
|
task=None,
|
|
117
117
|
command="",
|
|
@@ -127,6 +127,7 @@ def run_local(
|
|
|
127
127
|
artifact_path: str = "",
|
|
128
128
|
mode: str = None,
|
|
129
129
|
allow_empty_resources=None,
|
|
130
|
+
notifications: List[mlrun.model.Notification] = None,
|
|
130
131
|
returns: list = None,
|
|
131
132
|
):
|
|
132
133
|
"""Run a task on function/code (.py, .ipynb or .yaml) locally,
|
|
@@ -162,6 +163,7 @@ def run_local(
|
|
|
162
163
|
(allows to have function which don't depend on having targets,
|
|
163
164
|
e.g a function which accepts a feature vector uri and generate
|
|
164
165
|
the offline vector e.g. parquet_ for it if it doesn't exist)
|
|
166
|
+
:param notifications: list of notifications to push when the run is completed
|
|
165
167
|
:param returns: List of configurations for how to log the returning values from the handler's run (as artifacts or
|
|
166
168
|
results). The list's length must be equal to the amount of returning objects. A configuration may
|
|
167
169
|
be given as:
|
|
@@ -216,6 +218,7 @@ def run_local(
|
|
|
216
218
|
inputs=inputs,
|
|
217
219
|
returns=returns,
|
|
218
220
|
artifact_path=artifact_path,
|
|
221
|
+
notifications=notifications,
|
|
219
222
|
)
|
|
220
223
|
|
|
221
224
|
|
|
@@ -235,7 +238,7 @@ def function_to_module(code="", workdir=None, secrets=None, silent=False):
|
|
|
235
238
|
mod.my_job(context, p1=1, p2='x')
|
|
236
239
|
print(context.to_yaml())
|
|
237
240
|
|
|
238
|
-
fn = mlrun.import_function('hub://
|
|
241
|
+
fn = mlrun.import_function('hub://open-archive')
|
|
239
242
|
mod = mlrun.function_to_module(fn)
|
|
240
243
|
data = mlrun.run.get_dataitem("https://fpsignals-public.s3.amazonaws.com/catsndogs.tar.gz")
|
|
241
244
|
context = mlrun.get_or_create_ctx('myfunc')
|
|
@@ -457,7 +460,7 @@ def import_function(url="", secrets=None, db="", project=None, new_name=None):
|
|
|
457
460
|
|
|
458
461
|
examples::
|
|
459
462
|
|
|
460
|
-
function = mlrun.import_function("hub://
|
|
463
|
+
function = mlrun.import_function("hub://auto-trainer")
|
|
461
464
|
function = mlrun.import_function("./func.yaml")
|
|
462
465
|
function = mlrun.import_function("https://raw.githubusercontent.com/org/repo/func.yaml")
|
|
463
466
|
|
|
@@ -549,6 +552,7 @@ def new_function(
|
|
|
549
552
|
source: str = None,
|
|
550
553
|
requirements: Union[str, List[str]] = None,
|
|
551
554
|
kfp=None,
|
|
555
|
+
requirements_file: str = "",
|
|
552
556
|
):
|
|
553
557
|
"""Create a new ML function from base properties
|
|
554
558
|
|
|
@@ -584,9 +588,13 @@ def new_function(
|
|
|
584
588
|
(job, mpijob, ..) the handler can also be specified in the `.run()` command, when not specified
|
|
585
589
|
the entire file will be executed (as main).
|
|
586
590
|
for nuclio functions the handler is in the form of module:function, defaults to "main:handler"
|
|
587
|
-
:param source: valid path to git, zip, or tar file, e.g.
|
|
591
|
+
:param source: valid absolute path or URL to git, zip, or tar file, e.g.
|
|
592
|
+
`git://github.com/mlrun/something.git`,
|
|
588
593
|
`http://some/url/file.zip`
|
|
589
|
-
|
|
594
|
+
note path source must exist on the image or exist locally when run is local
|
|
595
|
+
(it is recommended to use 'function.spec.workdir' when source is a filepath instead)
|
|
596
|
+
:param requirements: a list of python packages, defaults to None
|
|
597
|
+
:param requirements_file: path to a python requirements file
|
|
590
598
|
:param kfp: reserved, flag indicating running within kubeflow pipeline
|
|
591
599
|
|
|
592
600
|
:return: function object
|
|
@@ -642,7 +650,7 @@ def new_function(
|
|
|
642
650
|
runner.spec.build.source = source
|
|
643
651
|
if handler:
|
|
644
652
|
if kind == RuntimeKinds.serving:
|
|
645
|
-
raise
|
|
653
|
+
raise MLRunInvalidArgumentError(
|
|
646
654
|
"cannot set the handler for serving runtime"
|
|
647
655
|
)
|
|
648
656
|
elif kind in RuntimeKinds.nuclio_runtimes():
|
|
@@ -651,8 +659,13 @@ def new_function(
|
|
|
651
659
|
runner.spec.default_handler = handler
|
|
652
660
|
|
|
653
661
|
if requirements:
|
|
654
|
-
runner.with_requirements(
|
|
655
|
-
|
|
662
|
+
runner.with_requirements(
|
|
663
|
+
requirements,
|
|
664
|
+
requirements_file=requirements_file,
|
|
665
|
+
prepare_image_for_deploy=False,
|
|
666
|
+
)
|
|
667
|
+
|
|
668
|
+
runner.prepare_image_for_deploy()
|
|
656
669
|
return runner
|
|
657
670
|
|
|
658
671
|
|
|
@@ -692,6 +705,7 @@ def code_to_function(
|
|
|
692
705
|
labels: Dict[str, str] = None,
|
|
693
706
|
with_doc: bool = True,
|
|
694
707
|
ignored_tags=None,
|
|
708
|
+
requirements_file: str = "",
|
|
695
709
|
) -> Union[
|
|
696
710
|
MpiRuntimeV1Alpha1,
|
|
697
711
|
MpiRuntimeV1,
|
|
@@ -700,7 +714,6 @@ def code_to_function(
|
|
|
700
714
|
DaskCluster,
|
|
701
715
|
KubejobRuntime,
|
|
702
716
|
LocalRuntime,
|
|
703
|
-
Spark2Runtime,
|
|
704
717
|
Spark3Runtime,
|
|
705
718
|
RemoteSparkRuntime,
|
|
706
719
|
]:
|
|
@@ -729,8 +742,7 @@ def code_to_function(
|
|
|
729
742
|
- spark: run distributed Spark job using Spark Kubernetes Operator
|
|
730
743
|
- remote-spark: run distributed Spark job on remote Spark service
|
|
731
744
|
|
|
732
|
-
Learn more about function runtimes
|
|
733
|
-
https://docs.mlrun.org/en/latest/runtimes/functions.html#function-runtimes
|
|
745
|
+
Learn more about {Kinds of function (runtimes)](../concepts/functions-overview.html).
|
|
734
746
|
|
|
735
747
|
:param name: function name, typically best to use hyphen-case
|
|
736
748
|
:param project: project used to namespace the function, defaults to 'default'
|
|
@@ -747,6 +759,8 @@ def code_to_function(
|
|
|
747
759
|
defaults to True
|
|
748
760
|
:param description: short function description, defaults to ''
|
|
749
761
|
:param requirements: list of python packages or pip requirements file path, defaults to None
|
|
762
|
+
:param requirements: a list of python packages
|
|
763
|
+
:param requirements_file: path to a python requirements file
|
|
750
764
|
:param categories: list of categories for mlrun Function Hub, defaults to None
|
|
751
765
|
:param labels: immutable name/value pairs to tag the function with useful metadata, defaults to None
|
|
752
766
|
:param with_doc: indicates whether to document the function parameters, defaults to True
|
|
@@ -793,12 +807,13 @@ def code_to_function(
|
|
|
793
807
|
|
|
794
808
|
def update_common(fn, spec):
|
|
795
809
|
fn.spec.image = image or get_in(spec, "spec.image", "")
|
|
810
|
+
fn.spec.filename = filename or get_in(spec, "spec.filename", "")
|
|
796
811
|
fn.spec.build.base_image = get_in(spec, "spec.build.baseImage")
|
|
797
812
|
fn.spec.build.commands = get_in(spec, "spec.build.commands")
|
|
798
813
|
fn.spec.build.secret = get_in(spec, "spec.build.secret")
|
|
799
814
|
|
|
800
815
|
if requirements:
|
|
801
|
-
fn.with_requirements(requirements)
|
|
816
|
+
fn.with_requirements(requirements, requirements_file=requirements_file)
|
|
802
817
|
|
|
803
818
|
if embed_code:
|
|
804
819
|
fn.spec.build.functionSourceCode = get_in(
|
|
@@ -920,7 +935,7 @@ def code_to_function(
|
|
|
920
935
|
|
|
921
936
|
build.image = get_in(spec, "spec.build.image")
|
|
922
937
|
update_common(r, spec)
|
|
923
|
-
r.
|
|
938
|
+
r.prepare_image_for_deploy()
|
|
924
939
|
|
|
925
940
|
if with_doc:
|
|
926
941
|
update_function_entry_points(r, code)
|
|
@@ -1136,22 +1151,24 @@ def wait_for_pipeline_completion(
|
|
|
1136
1151
|
if remote:
|
|
1137
1152
|
mldb = mlrun.db.get_run_db()
|
|
1138
1153
|
|
|
1139
|
-
def
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
show_kfp_run(
|
|
1143
|
-
if
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1154
|
+
def _wait_for_pipeline_completion():
|
|
1155
|
+
pipeline = mldb.get_pipeline(run_id, namespace=namespace, project=project)
|
|
1156
|
+
pipeline_status = pipeline["run"]["status"]
|
|
1157
|
+
show_kfp_run(pipeline, clear_output=True)
|
|
1158
|
+
if pipeline_status not in RunStatuses.stable_statuses():
|
|
1159
|
+
logger.debug(
|
|
1160
|
+
"Waiting for pipeline completion",
|
|
1161
|
+
run_id=run_id,
|
|
1162
|
+
status=pipeline_status,
|
|
1163
|
+
)
|
|
1147
1164
|
raise RuntimeError("pipeline run has not completed yet")
|
|
1148
1165
|
|
|
1149
|
-
return
|
|
1166
|
+
return pipeline
|
|
1150
1167
|
|
|
1151
1168
|
if mldb.kind != "http":
|
|
1152
1169
|
raise ValueError(
|
|
1153
|
-
"get pipeline
|
|
1154
|
-
",
|
|
1170
|
+
"get pipeline requires access to remote api-service"
|
|
1171
|
+
", set the dbpath url"
|
|
1155
1172
|
)
|
|
1156
1173
|
|
|
1157
1174
|
resp = retry_until_successful(
|
|
@@ -1159,9 +1176,7 @@ def wait_for_pipeline_completion(
|
|
|
1159
1176
|
timeout,
|
|
1160
1177
|
logger,
|
|
1161
1178
|
False,
|
|
1162
|
-
|
|
1163
|
-
run_id,
|
|
1164
|
-
namespace=namespace,
|
|
1179
|
+
_wait_for_pipeline_completion,
|
|
1165
1180
|
)
|
|
1166
1181
|
else:
|
|
1167
1182
|
client = Client(namespace=namespace)
|
|
@@ -1194,8 +1209,8 @@ def get_pipeline(
|
|
|
1194
1209
|
run_id,
|
|
1195
1210
|
namespace=None,
|
|
1196
1211
|
format_: Union[
|
|
1197
|
-
str, mlrun.
|
|
1198
|
-
] = mlrun.
|
|
1212
|
+
str, mlrun.common.schemas.PipelinesFormat
|
|
1213
|
+
] = mlrun.common.schemas.PipelinesFormat.summary,
|
|
1199
1214
|
project: str = None,
|
|
1200
1215
|
remote: bool = True,
|
|
1201
1216
|
):
|
|
@@ -1231,7 +1246,7 @@ def get_pipeline(
|
|
|
1231
1246
|
resp = resp.to_dict()
|
|
1232
1247
|
if (
|
|
1233
1248
|
not format_
|
|
1234
|
-
or format_ == mlrun.
|
|
1249
|
+
or format_ == mlrun.common.schemas.PipelinesFormat.summary.value
|
|
1235
1250
|
):
|
|
1236
1251
|
resp = format_summary_from_kfp_run(resp)
|
|
1237
1252
|
|
|
@@ -1247,7 +1262,7 @@ def list_pipelines(
|
|
|
1247
1262
|
filter_="",
|
|
1248
1263
|
namespace=None,
|
|
1249
1264
|
project="*",
|
|
1250
|
-
format_: mlrun.
|
|
1265
|
+
format_: mlrun.common.schemas.PipelinesFormat = mlrun.common.schemas.PipelinesFormat.metadata_only,
|
|
1251
1266
|
) -> Tuple[int, Optional[int], List[dict]]:
|
|
1252
1267
|
"""List pipelines
|
|
1253
1268
|
|
|
@@ -1267,7 +1282,7 @@ def list_pipelines(
|
|
|
1267
1282
|
:param format_: Control what will be returned (full/metadata_only/name_only)
|
|
1268
1283
|
"""
|
|
1269
1284
|
if full:
|
|
1270
|
-
format_ = mlrun.
|
|
1285
|
+
format_ = mlrun.common.schemas.PipelinesFormat.full
|
|
1271
1286
|
run_db = mlrun.db.get_run_db()
|
|
1272
1287
|
pipelines = run_db.list_pipelines(
|
|
1273
1288
|
project, namespace, sort_by, page_token, filter_, format_, page_size
|
|
@@ -1333,291 +1348,7 @@ def wait_for_runs_completion(runs: list, sleep=3, timeout=0, silent=False):
|
|
|
1333
1348
|
if timeout and total_time > timeout:
|
|
1334
1349
|
if silent:
|
|
1335
1350
|
break
|
|
1336
|
-
raise
|
|
1337
|
-
"some runs did not reach terminal state on time"
|
|
1338
|
-
)
|
|
1351
|
+
raise MLRunTimeoutError("some runs did not reach terminal state on time")
|
|
1339
1352
|
runs = running
|
|
1340
1353
|
|
|
1341
1354
|
return completed
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
def _parse_type_hint(type_hint: Union[Type, str]) -> Type:
|
|
1345
|
-
"""
|
|
1346
|
-
Parse a given type hint from string to its actual hinted type class object. The string must be one of the following:
|
|
1347
|
-
|
|
1348
|
-
* Python builtin type - one of ``tuple``, ``list``, ``set``, ``dict`` and ``bytearray``.
|
|
1349
|
-
* Full module import path. An alias is not allowed (if ``import pandas as pd`` is used, the type hint cannot be
|
|
1350
|
-
``pd.DataFrame`` but ``pandas.DataFrame``).
|
|
1351
|
-
|
|
1352
|
-
The type class on its own (like `DataFrame`) cannot be used as the scope of the decorator is not the same as the
|
|
1353
|
-
handler itself, hence modules and objects that were imported in the handler's scope are not available. This is the
|
|
1354
|
-
same reason import aliases cannot be used as well.
|
|
1355
|
-
|
|
1356
|
-
If the provided type hint is not a string, it will simply be returned as is.
|
|
1357
|
-
|
|
1358
|
-
**Notice**: This method should only run on client side as it dependent on user requirements.
|
|
1359
|
-
|
|
1360
|
-
:param type_hint: The type hint to parse.
|
|
1361
|
-
|
|
1362
|
-
:return: The hinted type.
|
|
1363
|
-
|
|
1364
|
-
:raise MLRunInvalidArgumentError: In case the type hint is not following the 2 options mentioned above.
|
|
1365
|
-
"""
|
|
1366
|
-
if not isinstance(type_hint, str):
|
|
1367
|
-
return type_hint
|
|
1368
|
-
|
|
1369
|
-
# TODO: Remove once Packager is implemented (it will support typing hints)
|
|
1370
|
-
# If a typing hint is provided, we return a dummy Union type so the parser will skip the data item:
|
|
1371
|
-
if type_hint.startswith("typing."):
|
|
1372
|
-
return Union[int, str]
|
|
1373
|
-
|
|
1374
|
-
# Validate the type hint is a valid module path:
|
|
1375
|
-
if not bool(
|
|
1376
|
-
re.fullmatch(r"([a-zA-Z_][a-zA-Z0-9_]*\.)*[a-zA-Z_][a-zA-Z0-9_]*", type_hint)
|
|
1377
|
-
):
|
|
1378
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
1379
|
-
f"Invalid type hint. An input type hint must be a valid python class name or its module import path. For "
|
|
1380
|
-
f"example: 'list', 'pandas.DataFrame', 'numpy.ndarray', 'sklearn.linear_model.LinearRegression'. Type hint "
|
|
1381
|
-
f"given: '{type_hint}'."
|
|
1382
|
-
)
|
|
1383
|
-
|
|
1384
|
-
# Look for a builtin type (rest of the builtin types like `int`, `str`, `float` should be treated as results, hence
|
|
1385
|
-
# not given as an input to an MLRun function, but as a parameter):
|
|
1386
|
-
builtin_types = {
|
|
1387
|
-
tuple.__name__: tuple,
|
|
1388
|
-
list.__name__: list,
|
|
1389
|
-
set.__name__: set,
|
|
1390
|
-
dict.__name__: dict,
|
|
1391
|
-
bytearray.__name__: bytearray,
|
|
1392
|
-
}
|
|
1393
|
-
if type_hint in builtin_types:
|
|
1394
|
-
return builtin_types[type_hint]
|
|
1395
|
-
|
|
1396
|
-
# If it's not a builtin, its should have a full module path:
|
|
1397
|
-
if "." not in type_hint:
|
|
1398
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
1399
|
-
f"MLRun tried to get the type hint '{type_hint}' but it can't as it is not a valid builtin Python type "
|
|
1400
|
-
f"(one of {', '.join(list(builtin_types.keys()))}). Pay attention using only the type as string is not "
|
|
1401
|
-
f"allowed as the handler's scope is different then MLRun's. To properly give a type hint, please specify "
|
|
1402
|
-
f"the full module path. For example: do not use `DataFrame`, use `pandas.DataFrame`."
|
|
1403
|
-
)
|
|
1404
|
-
|
|
1405
|
-
# Import the module to receive the hinted type:
|
|
1406
|
-
try:
|
|
1407
|
-
# Get the module path and the type class (If we'll wish to support inner classes, the `rsplit` won't work):
|
|
1408
|
-
module_path, type_hint = type_hint.rsplit(".", 1)
|
|
1409
|
-
# Replace alias if needed (alias assumed to be imported already, hence we look in globals):
|
|
1410
|
-
# For example:
|
|
1411
|
-
# If in handler scope there was `import A.B.C as abc` and user gave a type hint "abc.Something" then:
|
|
1412
|
-
# `module_path[0]` will be equal to "abc". Then, because it is an alias, it will appear in the globals, so we'll
|
|
1413
|
-
# replace the alias with the full module name in order to import the module.
|
|
1414
|
-
module_path = module_path.split(".")
|
|
1415
|
-
if module_path[0] in globals():
|
|
1416
|
-
module_path[0] = globals()[module_path[0]].__name__
|
|
1417
|
-
module_path = ".".join(module_path)
|
|
1418
|
-
# Import the module:
|
|
1419
|
-
module = importlib.import_module(module_path)
|
|
1420
|
-
# Get the class type from the module:
|
|
1421
|
-
type_hint = getattr(module, type_hint)
|
|
1422
|
-
except ModuleNotFoundError as module_not_found_error:
|
|
1423
|
-
# May be raised from `importlib.import_module` in case the module does not exist.
|
|
1424
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
1425
|
-
f"MLRun tried to get the type hint '{type_hint}' but the module '{module_path}' cannot be imported. "
|
|
1426
|
-
f"Keep in mind that using alias in the module path (meaning: import module as alias) is not allowed. "
|
|
1427
|
-
f"If the module path is correct, please make sure the module package is installed in the python "
|
|
1428
|
-
f"interpreter."
|
|
1429
|
-
) from module_not_found_error
|
|
1430
|
-
except AttributeError as attribute_error:
|
|
1431
|
-
# May be raised from `getattr(module, type_hint)` in case the class type cannot be imported directly from the
|
|
1432
|
-
# imported module.
|
|
1433
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
1434
|
-
f"MLRun tried to get the type hint '{type_hint}' from the module '{module.__name__}' but it seems it "
|
|
1435
|
-
f"doesn't exist. Make sure the class can be imported from the module with the exact module path you "
|
|
1436
|
-
f"passed. Notice inner classes (a class inside of a class) are not supported."
|
|
1437
|
-
) from attribute_error
|
|
1438
|
-
|
|
1439
|
-
return type_hint
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
def _parse_log_hint(
|
|
1443
|
-
log_hint: Union[Dict[str, str], str, None]
|
|
1444
|
-
) -> Union[Dict[str, str], None]:
|
|
1445
|
-
"""
|
|
1446
|
-
Parse a given log hint from string to a logging configuration dictionary. The string will be read as the artifact
|
|
1447
|
-
key ('key' in the dictionary) and if the string have a single colon, the following structure is assumed:
|
|
1448
|
-
"<artifact_key> : <artifact_type>". The artifact type must be on of the values of `ArtifactType`'s enum.
|
|
1449
|
-
|
|
1450
|
-
If a logging configuration dictionary is received, it will be validated to have a key field and valid artifact type
|
|
1451
|
-
value.
|
|
1452
|
-
|
|
1453
|
-
None will be returned as None.
|
|
1454
|
-
|
|
1455
|
-
:param log_hint: The log hint to parse.
|
|
1456
|
-
|
|
1457
|
-
:return: The hinted logging configuration.
|
|
1458
|
-
|
|
1459
|
-
:raise MLRunInvalidArgumentError: In case the log hint is not following the string structure, the artifact type is
|
|
1460
|
-
not valid or the dictionary is missing the key field.
|
|
1461
|
-
"""
|
|
1462
|
-
# Check for None value:
|
|
1463
|
-
if log_hint is None:
|
|
1464
|
-
return None
|
|
1465
|
-
|
|
1466
|
-
# If the log hint was provided as a string, construct a dictionary out of it:
|
|
1467
|
-
if isinstance(log_hint, str):
|
|
1468
|
-
# Check if only key is given:
|
|
1469
|
-
if ":" not in log_hint:
|
|
1470
|
-
log_hint = {"key": log_hint}
|
|
1471
|
-
# Check for valid "<key> : <artifact type>" pattern:
|
|
1472
|
-
else:
|
|
1473
|
-
if log_hint.count(":") > 1:
|
|
1474
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
1475
|
-
f"Incorrect log hint pattern. Output keys can have only a single ':' in them to specify the "
|
|
1476
|
-
f"desired artifact type the returned value will be logged as: '<artifact_key> : <artifact_type>', "
|
|
1477
|
-
f"but given: {log_hint}"
|
|
1478
|
-
)
|
|
1479
|
-
# Split into key and type:
|
|
1480
|
-
key, artifact_type = log_hint.replace(" ", "").split(":")
|
|
1481
|
-
log_hint = {"key": key, "artifact_type": artifact_type}
|
|
1482
|
-
|
|
1483
|
-
# TODO: Replace with constants keys once mlrun.package is implemented.
|
|
1484
|
-
# Validate the log hint dictionary has the mandatory key:
|
|
1485
|
-
if "key" not in log_hint:
|
|
1486
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
1487
|
-
f"An output log hint dictionary must include the 'key' - the artifact key (it's name). The following "
|
|
1488
|
-
f"log hint is missing the key: {log_hint}."
|
|
1489
|
-
)
|
|
1490
|
-
|
|
1491
|
-
# Validate the artifact type is valid:
|
|
1492
|
-
if "artifact_type" in log_hint:
|
|
1493
|
-
valid_artifact_types = [t.value for t in ArtifactType.__members__.values()]
|
|
1494
|
-
if log_hint["artifact_type"] not in valid_artifact_types:
|
|
1495
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
1496
|
-
f"The following artifact type '{log_hint['artifact_type']}' is not a valid `ArtifactType`. "
|
|
1497
|
-
f"Please select one of the following: {','.join(valid_artifact_types)}"
|
|
1498
|
-
)
|
|
1499
|
-
|
|
1500
|
-
return log_hint
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
def handler(
|
|
1504
|
-
labels: Dict[str, str] = None,
|
|
1505
|
-
outputs: List[Union[str, Dict[str, str]]] = None,
|
|
1506
|
-
inputs: Union[bool, Dict[str, Union[str, Type]]] = True,
|
|
1507
|
-
):
|
|
1508
|
-
"""
|
|
1509
|
-
MLRun's handler is a decorator to wrap a function and enable setting labels, automatic `mlrun.DataItem` parsing and
|
|
1510
|
-
outputs logging.
|
|
1511
|
-
|
|
1512
|
-
:param labels: Labels to add to the run. Expecting a dictionary with the labels names as keys. Default: None.
|
|
1513
|
-
:param outputs: Logging configurations for the function's returned values. Expecting a list of tuples and None
|
|
1514
|
-
values:
|
|
1515
|
-
|
|
1516
|
-
* str - A string in the format of '{key}:{artifact_type}'. If a string was given without ':' it will
|
|
1517
|
-
indicate the key and the artifact type will be according to the returned value type. The artifact
|
|
1518
|
-
types can be one of: "dataset", "directory", "file", "object", "plot" and "result".
|
|
1519
|
-
|
|
1520
|
-
* Dict[str, str] - A dictionary of logging configuration. the key 'key' is mandatory for the logged
|
|
1521
|
-
artifact key.
|
|
1522
|
-
|
|
1523
|
-
* None - Do not log the output.
|
|
1524
|
-
|
|
1525
|
-
The list length must be equal to the total amount of returned values from the function. Default is
|
|
1526
|
-
None - meaning no outputs will be logged.
|
|
1527
|
-
|
|
1528
|
-
:param inputs: Parsing configurations for the arguments passed as inputs via the `run` method of an MLRun function.
|
|
1529
|
-
Can be passed as a boolean value or a dictionary:
|
|
1530
|
-
|
|
1531
|
-
* True - Parse all found inputs to the assigned type hint in the function's signature. If there is no
|
|
1532
|
-
type hint assigned, the value will remain an `mlrun.DataItem`.
|
|
1533
|
-
* False - Do not parse inputs, leaving the inputs as `mlrun.DataItem`.
|
|
1534
|
-
* Dict[str, Union[Type, str]] - A dictionary with argument name as key and the expected type to parse
|
|
1535
|
-
the `mlrun.DataItem` to. The expected type can be a string as well, idicating the full module path.
|
|
1536
|
-
|
|
1537
|
-
**Notice**: Type hints from the `typing` module (e.g. `typing.Optional`, `typing.Union`,
|
|
1538
|
-
`typing.List` etc.) are currently not supported but will be in the future.
|
|
1539
|
-
|
|
1540
|
-
Default: True.
|
|
1541
|
-
|
|
1542
|
-
Example::
|
|
1543
|
-
|
|
1544
|
-
import mlrun
|
|
1545
|
-
|
|
1546
|
-
@mlrun.handler(outputs=["my_array", None, "my_multiplier"])
|
|
1547
|
-
def my_handler(array: np.ndarray, m: int):
|
|
1548
|
-
array = array * m
|
|
1549
|
-
m += 1
|
|
1550
|
-
return array, "I won't be logged", m
|
|
1551
|
-
|
|
1552
|
-
>>> mlrun_function = mlrun.code_to_function("my_code.py", kind="job")
|
|
1553
|
-
>>> run_object = mlrun_function.run(
|
|
1554
|
-
... handler="my_handler",
|
|
1555
|
-
... inputs={"array": "store://my_array_Artifact"},
|
|
1556
|
-
... params={"m": 2}
|
|
1557
|
-
... )
|
|
1558
|
-
>>> run_object.outputs
|
|
1559
|
-
{'my_multiplier': 3, 'my_array': 'store://...'}
|
|
1560
|
-
"""
|
|
1561
|
-
|
|
1562
|
-
def decorator(func: Callable):
|
|
1563
|
-
def wrapper(*args: tuple, **kwargs: dict):
|
|
1564
|
-
nonlocal labels
|
|
1565
|
-
nonlocal outputs
|
|
1566
|
-
nonlocal inputs
|
|
1567
|
-
|
|
1568
|
-
# Set default `inputs` - inspect the full signature and add the user's input on top of it:
|
|
1569
|
-
if inputs:
|
|
1570
|
-
# Get the available parameters type hints from the function's signature:
|
|
1571
|
-
func_signature = inspect.signature(func)
|
|
1572
|
-
parameters = OrderedDict(
|
|
1573
|
-
{
|
|
1574
|
-
parameter.name: parameter.annotation
|
|
1575
|
-
for parameter in func_signature.parameters.values()
|
|
1576
|
-
}
|
|
1577
|
-
)
|
|
1578
|
-
# If user input is given, add it on top of the collected defaults (from signature), strings type hints
|
|
1579
|
-
# will be parsed to their actual types:
|
|
1580
|
-
if isinstance(inputs, dict):
|
|
1581
|
-
parameters.update(
|
|
1582
|
-
{
|
|
1583
|
-
parameter_name: _parse_type_hint(type_hint=type_hint)
|
|
1584
|
-
for parameter_name, type_hint in inputs.items()
|
|
1585
|
-
}
|
|
1586
|
-
)
|
|
1587
|
-
inputs = parameters
|
|
1588
|
-
|
|
1589
|
-
# Create a context handler and look for a context:
|
|
1590
|
-
context_handler = ContextHandler()
|
|
1591
|
-
context_handler.look_for_context(args=args, kwargs=kwargs)
|
|
1592
|
-
|
|
1593
|
-
# If an MLRun context is found, parse arguments pre-run (kwargs are parsed inplace):
|
|
1594
|
-
if context_handler.is_context_available() and inputs:
|
|
1595
|
-
args = context_handler.parse_inputs(
|
|
1596
|
-
args=args, kwargs=kwargs, type_hints=inputs
|
|
1597
|
-
)
|
|
1598
|
-
|
|
1599
|
-
# Call the original function and get the returning values:
|
|
1600
|
-
func_outputs = func(*args, **kwargs)
|
|
1601
|
-
|
|
1602
|
-
# If an MLRun context is found, set the given labels and log the returning values to MLRun via the context:
|
|
1603
|
-
if context_handler.is_context_available():
|
|
1604
|
-
if labels:
|
|
1605
|
-
context_handler.set_labels(labels=labels)
|
|
1606
|
-
if outputs:
|
|
1607
|
-
context_handler.log_outputs(
|
|
1608
|
-
outputs=func_outputs
|
|
1609
|
-
if isinstance(func_outputs, tuple)
|
|
1610
|
-
else [func_outputs],
|
|
1611
|
-
log_hints=[
|
|
1612
|
-
_parse_log_hint(log_hint=log_hint) for log_hint in outputs
|
|
1613
|
-
],
|
|
1614
|
-
)
|
|
1615
|
-
return # Do not return any values as the returning values were logged to MLRun.
|
|
1616
|
-
return func_outputs
|
|
1617
|
-
|
|
1618
|
-
# Make sure to pass the wrapped function's signature (argument list, type hints and doc strings) to the wrapper:
|
|
1619
|
-
wrapper = functools.wraps(func)(wrapper)
|
|
1620
|
-
|
|
1621
|
-
return wrapper
|
|
1622
|
-
|
|
1623
|
-
return decorator
|
mlrun/runtimes/__init__.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.
|
|
@@ -25,8 +25,6 @@ __all__ = [
|
|
|
25
25
|
"RemoteSparkRuntime",
|
|
26
26
|
]
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
from mlrun.runtimes.package.context_handler import ArtifactType, ContextHandler
|
|
30
28
|
from mlrun.runtimes.utils import (
|
|
31
29
|
resolve_mpijob_crd_version,
|
|
32
30
|
resolve_spark_operator_version,
|
|
@@ -47,7 +45,7 @@ from .mpijob import ( # noqa
|
|
|
47
45
|
from .nuclio import nuclio_init_hook
|
|
48
46
|
from .remotesparkjob import RemoteSparkRuntime, RemoteSparkRuntimeHandler
|
|
49
47
|
from .serving import ServingRuntime, new_v2_model_server
|
|
50
|
-
from .sparkjob import
|
|
48
|
+
from .sparkjob import Spark3Runtime, SparkRuntimeHandler
|
|
51
49
|
|
|
52
50
|
# for legacy imports (MLModelServer moved from here to /serving)
|
|
53
51
|
from ..serving import MLModelServer, new_v1_model_server # noqa isort: skip
|
|
@@ -260,11 +258,7 @@ def get_runtime_class(kind: str):
|
|
|
260
258
|
return crd_version_to_runtime[mpijob_crd_version]
|
|
261
259
|
|
|
262
260
|
if kind == RuntimeKinds.spark:
|
|
263
|
-
|
|
264
|
-
if spark_operator_version == 2:
|
|
265
|
-
return Spark2Runtime
|
|
266
|
-
elif spark_operator_version == 3:
|
|
267
|
-
return Spark3Runtime
|
|
261
|
+
return Spark3Runtime
|
|
268
262
|
|
|
269
263
|
kind_runtime_map = {
|
|
270
264
|
RuntimeKinds.remote: RemoteRuntime,
|