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/api/crud/feature_store.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2023 Iguazio
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -16,10 +16,10 @@ import typing
|
|
|
16
16
|
|
|
17
17
|
import sqlalchemy.orm
|
|
18
18
|
|
|
19
|
-
import mlrun.api.schemas
|
|
20
19
|
import mlrun.api.utils.projects.remotes.follower
|
|
21
20
|
import mlrun.api.utils.singletons.db
|
|
22
21
|
import mlrun.api.utils.singletons.project_member
|
|
22
|
+
import mlrun.common.schemas
|
|
23
23
|
import mlrun.config
|
|
24
24
|
import mlrun.errors
|
|
25
25
|
import mlrun.utils.singleton
|
|
@@ -32,9 +32,12 @@ class FeatureStore(
|
|
|
32
32
|
self,
|
|
33
33
|
db_session: sqlalchemy.orm.Session,
|
|
34
34
|
project: str,
|
|
35
|
-
feature_set: mlrun.
|
|
35
|
+
feature_set: mlrun.common.schemas.FeatureSet,
|
|
36
36
|
versioned: bool = True,
|
|
37
37
|
) -> str:
|
|
38
|
+
if not feature_set.spec.engine:
|
|
39
|
+
feature_set.spec.engine = "storey"
|
|
40
|
+
|
|
38
41
|
return self._create_object(
|
|
39
42
|
db_session,
|
|
40
43
|
project,
|
|
@@ -47,11 +50,14 @@ class FeatureStore(
|
|
|
47
50
|
db_session: sqlalchemy.orm.Session,
|
|
48
51
|
project: str,
|
|
49
52
|
name: str,
|
|
50
|
-
feature_set: mlrun.
|
|
53
|
+
feature_set: mlrun.common.schemas.FeatureSet,
|
|
51
54
|
tag: typing.Optional[str] = None,
|
|
52
55
|
uid: typing.Optional[str] = None,
|
|
53
56
|
versioned: bool = True,
|
|
54
57
|
) -> str:
|
|
58
|
+
if not feature_set.spec.engine:
|
|
59
|
+
feature_set.spec.engine = "storey"
|
|
60
|
+
|
|
55
61
|
return self._store_object(
|
|
56
62
|
db_session,
|
|
57
63
|
project,
|
|
@@ -70,11 +76,11 @@ class FeatureStore(
|
|
|
70
76
|
feature_set_patch: dict,
|
|
71
77
|
tag: typing.Optional[str] = None,
|
|
72
78
|
uid: typing.Optional[str] = None,
|
|
73
|
-
patch_mode: mlrun.
|
|
79
|
+
patch_mode: mlrun.common.schemas.PatchMode = mlrun.common.schemas.PatchMode.replace,
|
|
74
80
|
) -> str:
|
|
75
81
|
return self._patch_object(
|
|
76
82
|
db_session,
|
|
77
|
-
mlrun.
|
|
83
|
+
mlrun.common.schemas.FeatureSet,
|
|
78
84
|
project,
|
|
79
85
|
name,
|
|
80
86
|
feature_set_patch,
|
|
@@ -90,9 +96,9 @@ class FeatureStore(
|
|
|
90
96
|
name: str,
|
|
91
97
|
tag: typing.Optional[str] = None,
|
|
92
98
|
uid: typing.Optional[str] = None,
|
|
93
|
-
) -> mlrun.
|
|
99
|
+
) -> mlrun.common.schemas.FeatureSet:
|
|
94
100
|
return self._get_object(
|
|
95
|
-
db_session, mlrun.
|
|
101
|
+
db_session, mlrun.common.schemas.FeatureSet, project, name, tag, uid
|
|
96
102
|
)
|
|
97
103
|
|
|
98
104
|
def list_feature_sets_tags(
|
|
@@ -104,7 +110,7 @@ class FeatureStore(
|
|
|
104
110
|
:return: a list of Tuple of (project, feature_set.name, tag)
|
|
105
111
|
"""
|
|
106
112
|
return self._list_object_type_tags(
|
|
107
|
-
db_session, mlrun.
|
|
113
|
+
db_session, mlrun.common.schemas.FeatureSet, project
|
|
108
114
|
)
|
|
109
115
|
|
|
110
116
|
def list_feature_sets(
|
|
@@ -117,11 +123,11 @@ class FeatureStore(
|
|
|
117
123
|
entities: typing.List[str] = None,
|
|
118
124
|
features: typing.List[str] = None,
|
|
119
125
|
labels: typing.List[str] = None,
|
|
120
|
-
partition_by: mlrun.
|
|
126
|
+
partition_by: mlrun.common.schemas.FeatureStorePartitionByField = None,
|
|
121
127
|
rows_per_partition: int = 1,
|
|
122
|
-
partition_sort_by: mlrun.
|
|
123
|
-
partition_order: mlrun.
|
|
124
|
-
) -> mlrun.
|
|
128
|
+
partition_sort_by: mlrun.common.schemas.SortField = None,
|
|
129
|
+
partition_order: mlrun.common.schemas.OrderType = mlrun.common.schemas.OrderType.desc,
|
|
130
|
+
) -> mlrun.common.schemas.FeatureSetsOutput:
|
|
125
131
|
project = project or mlrun.mlconf.default_project
|
|
126
132
|
return mlrun.api.utils.singletons.db.get_db().list_feature_sets(
|
|
127
133
|
db_session,
|
|
@@ -148,7 +154,7 @@ class FeatureStore(
|
|
|
148
154
|
):
|
|
149
155
|
self._delete_object(
|
|
150
156
|
db_session,
|
|
151
|
-
mlrun.
|
|
157
|
+
mlrun.common.schemas.FeatureSet,
|
|
152
158
|
project,
|
|
153
159
|
name,
|
|
154
160
|
tag,
|
|
@@ -163,7 +169,7 @@ class FeatureStore(
|
|
|
163
169
|
tag: typing.Optional[str] = None,
|
|
164
170
|
entities: typing.List[str] = None,
|
|
165
171
|
labels: typing.List[str] = None,
|
|
166
|
-
) -> mlrun.
|
|
172
|
+
) -> mlrun.common.schemas.FeaturesOutput:
|
|
167
173
|
project = project or mlrun.mlconf.default_project
|
|
168
174
|
return mlrun.api.utils.singletons.db.get_db().list_features(
|
|
169
175
|
db_session,
|
|
@@ -181,7 +187,7 @@ class FeatureStore(
|
|
|
181
187
|
name: str,
|
|
182
188
|
tag: typing.Optional[str] = None,
|
|
183
189
|
labels: typing.List[str] = None,
|
|
184
|
-
) -> mlrun.
|
|
190
|
+
) -> mlrun.common.schemas.EntitiesOutput:
|
|
185
191
|
project = project or mlrun.mlconf.default_project
|
|
186
192
|
return mlrun.api.utils.singletons.db.get_db().list_entities(
|
|
187
193
|
db_session,
|
|
@@ -195,7 +201,7 @@ class FeatureStore(
|
|
|
195
201
|
self,
|
|
196
202
|
db_session: sqlalchemy.orm.Session,
|
|
197
203
|
project: str,
|
|
198
|
-
feature_vector: mlrun.
|
|
204
|
+
feature_vector: mlrun.common.schemas.FeatureVector,
|
|
199
205
|
versioned: bool = True,
|
|
200
206
|
) -> str:
|
|
201
207
|
return self._create_object(db_session, project, feature_vector, versioned)
|
|
@@ -205,7 +211,7 @@ class FeatureStore(
|
|
|
205
211
|
db_session: sqlalchemy.orm.Session,
|
|
206
212
|
project: str,
|
|
207
213
|
name: str,
|
|
208
|
-
feature_vector: mlrun.
|
|
214
|
+
feature_vector: mlrun.common.schemas.FeatureVector,
|
|
209
215
|
tag: typing.Optional[str] = None,
|
|
210
216
|
uid: typing.Optional[str] = None,
|
|
211
217
|
versioned: bool = True,
|
|
@@ -228,11 +234,11 @@ class FeatureStore(
|
|
|
228
234
|
feature_vector_patch: dict,
|
|
229
235
|
tag: typing.Optional[str] = None,
|
|
230
236
|
uid: typing.Optional[str] = None,
|
|
231
|
-
patch_mode: mlrun.
|
|
237
|
+
patch_mode: mlrun.common.schemas.PatchMode = mlrun.common.schemas.PatchMode.replace,
|
|
232
238
|
) -> str:
|
|
233
239
|
return self._patch_object(
|
|
234
240
|
db_session,
|
|
235
|
-
mlrun.
|
|
241
|
+
mlrun.common.schemas.FeatureVector,
|
|
236
242
|
project,
|
|
237
243
|
name,
|
|
238
244
|
feature_vector_patch,
|
|
@@ -248,10 +254,10 @@ class FeatureStore(
|
|
|
248
254
|
name: str,
|
|
249
255
|
tag: typing.Optional[str] = None,
|
|
250
256
|
uid: typing.Optional[str] = None,
|
|
251
|
-
) -> mlrun.
|
|
257
|
+
) -> mlrun.common.schemas.FeatureVector:
|
|
252
258
|
return self._get_object(
|
|
253
259
|
db_session,
|
|
254
|
-
mlrun.
|
|
260
|
+
mlrun.common.schemas.FeatureVector,
|
|
255
261
|
project,
|
|
256
262
|
name,
|
|
257
263
|
tag,
|
|
@@ -267,7 +273,7 @@ class FeatureStore(
|
|
|
267
273
|
:return: a list of Tuple of (project, feature_vector.name, tag)
|
|
268
274
|
"""
|
|
269
275
|
return self._list_object_type_tags(
|
|
270
|
-
db_session, mlrun.
|
|
276
|
+
db_session, mlrun.common.schemas.FeatureVector, project
|
|
271
277
|
)
|
|
272
278
|
|
|
273
279
|
def list_feature_vectors(
|
|
@@ -278,11 +284,11 @@ class FeatureStore(
|
|
|
278
284
|
tag: typing.Optional[str] = None,
|
|
279
285
|
state: str = None,
|
|
280
286
|
labels: typing.List[str] = None,
|
|
281
|
-
partition_by: mlrun.
|
|
287
|
+
partition_by: mlrun.common.schemas.FeatureStorePartitionByField = None,
|
|
282
288
|
rows_per_partition: int = 1,
|
|
283
|
-
partition_sort_by: mlrun.
|
|
284
|
-
partition_order: mlrun.
|
|
285
|
-
) -> mlrun.
|
|
289
|
+
partition_sort_by: mlrun.common.schemas.SortField = None,
|
|
290
|
+
partition_order: mlrun.common.schemas.OrderType = mlrun.common.schemas.OrderType.desc,
|
|
291
|
+
) -> mlrun.common.schemas.FeatureVectorsOutput:
|
|
286
292
|
project = project or mlrun.mlconf.default_project
|
|
287
293
|
return mlrun.api.utils.singletons.db.get_db().list_feature_vectors(
|
|
288
294
|
db_session,
|
|
@@ -307,7 +313,7 @@ class FeatureStore(
|
|
|
307
313
|
):
|
|
308
314
|
self._delete_object(
|
|
309
315
|
db_session,
|
|
310
|
-
mlrun.
|
|
316
|
+
mlrun.common.schemas.FeatureVector,
|
|
311
317
|
project,
|
|
312
318
|
name,
|
|
313
319
|
tag,
|
|
@@ -319,17 +325,17 @@ class FeatureStore(
|
|
|
319
325
|
db_session: sqlalchemy.orm.Session,
|
|
320
326
|
project: str,
|
|
321
327
|
object_: typing.Union[
|
|
322
|
-
mlrun.
|
|
328
|
+
mlrun.common.schemas.FeatureSet, mlrun.common.schemas.FeatureVector
|
|
323
329
|
],
|
|
324
330
|
versioned: bool = True,
|
|
325
331
|
) -> str:
|
|
326
332
|
project = project or mlrun.mlconf.default_project
|
|
327
333
|
self._validate_and_enrich_identity_for_object_creation(project, object_)
|
|
328
|
-
if isinstance(object_, mlrun.
|
|
334
|
+
if isinstance(object_, mlrun.common.schemas.FeatureSet):
|
|
329
335
|
return mlrun.api.utils.singletons.db.get_db().create_feature_set(
|
|
330
336
|
db_session, project, object_, versioned
|
|
331
337
|
)
|
|
332
|
-
elif isinstance(object_, mlrun.
|
|
338
|
+
elif isinstance(object_, mlrun.common.schemas.FeatureVector):
|
|
333
339
|
return mlrun.api.utils.singletons.db.get_db().create_feature_vector(
|
|
334
340
|
db_session, project, object_, versioned
|
|
335
341
|
)
|
|
@@ -344,7 +350,7 @@ class FeatureStore(
|
|
|
344
350
|
project: str,
|
|
345
351
|
name: str,
|
|
346
352
|
object_: typing.Union[
|
|
347
|
-
mlrun.
|
|
353
|
+
mlrun.common.schemas.FeatureSet, mlrun.common.schemas.FeatureVector
|
|
348
354
|
],
|
|
349
355
|
tag: typing.Optional[str] = None,
|
|
350
356
|
uid: typing.Optional[str] = None,
|
|
@@ -354,7 +360,7 @@ class FeatureStore(
|
|
|
354
360
|
self._validate_and_enrich_identity_for_object_store(
|
|
355
361
|
object_, project, name, tag, uid
|
|
356
362
|
)
|
|
357
|
-
if isinstance(object_, mlrun.
|
|
363
|
+
if isinstance(object_, mlrun.common.schemas.FeatureSet):
|
|
358
364
|
return mlrun.api.utils.singletons.db.get_db().store_feature_set(
|
|
359
365
|
db_session,
|
|
360
366
|
project,
|
|
@@ -364,7 +370,7 @@ class FeatureStore(
|
|
|
364
370
|
uid,
|
|
365
371
|
versioned,
|
|
366
372
|
)
|
|
367
|
-
elif isinstance(object_, mlrun.
|
|
373
|
+
elif isinstance(object_, mlrun.common.schemas.FeatureVector):
|
|
368
374
|
return mlrun.api.utils.singletons.db.get_db().store_feature_vector(
|
|
369
375
|
db_session,
|
|
370
376
|
project,
|
|
@@ -388,7 +394,7 @@ class FeatureStore(
|
|
|
388
394
|
object_patch: dict,
|
|
389
395
|
tag: typing.Optional[str] = None,
|
|
390
396
|
uid: typing.Optional[str] = None,
|
|
391
|
-
patch_mode: mlrun.
|
|
397
|
+
patch_mode: mlrun.common.schemas.PatchMode = mlrun.common.schemas.PatchMode.replace,
|
|
392
398
|
) -> str:
|
|
393
399
|
project = project or mlrun.mlconf.default_project
|
|
394
400
|
self._validate_identity_for_object_patch(
|
|
@@ -399,7 +405,7 @@ class FeatureStore(
|
|
|
399
405
|
tag,
|
|
400
406
|
uid,
|
|
401
407
|
)
|
|
402
|
-
if object_schema.__name__ == mlrun.
|
|
408
|
+
if object_schema.__name__ == mlrun.common.schemas.FeatureSet.__name__:
|
|
403
409
|
return mlrun.api.utils.singletons.db.get_db().patch_feature_set(
|
|
404
410
|
db_session,
|
|
405
411
|
project,
|
|
@@ -409,7 +415,7 @@ class FeatureStore(
|
|
|
409
415
|
uid,
|
|
410
416
|
patch_mode,
|
|
411
417
|
)
|
|
412
|
-
elif object_schema.__name__ == mlrun.
|
|
418
|
+
elif object_schema.__name__ == mlrun.common.schemas.FeatureVector.__name__:
|
|
413
419
|
return mlrun.api.utils.singletons.db.get_db().patch_feature_vector(
|
|
414
420
|
db_session,
|
|
415
421
|
project,
|
|
@@ -432,13 +438,15 @@ class FeatureStore(
|
|
|
432
438
|
name: str,
|
|
433
439
|
tag: typing.Optional[str] = None,
|
|
434
440
|
uid: typing.Optional[str] = None,
|
|
435
|
-
) -> typing.Union[
|
|
441
|
+
) -> typing.Union[
|
|
442
|
+
mlrun.common.schemas.FeatureSet, mlrun.common.schemas.FeatureVector
|
|
443
|
+
]:
|
|
436
444
|
project = project or mlrun.mlconf.default_project
|
|
437
|
-
if object_schema.__name__ == mlrun.
|
|
445
|
+
if object_schema.__name__ == mlrun.common.schemas.FeatureSet.__name__:
|
|
438
446
|
return mlrun.api.utils.singletons.db.get_db().get_feature_set(
|
|
439
447
|
db_session, project, name, tag, uid
|
|
440
448
|
)
|
|
441
|
-
elif object_schema.__name__ == mlrun.
|
|
449
|
+
elif object_schema.__name__ == mlrun.common.schemas.FeatureVector.__name__:
|
|
442
450
|
return mlrun.api.utils.singletons.db.get_db().get_feature_vector(
|
|
443
451
|
db_session, project, name, tag, uid
|
|
444
452
|
)
|
|
@@ -454,11 +462,11 @@ class FeatureStore(
|
|
|
454
462
|
project: str,
|
|
455
463
|
) -> typing.List[typing.Tuple[str, str, str]]:
|
|
456
464
|
project = project or mlrun.mlconf.default_project
|
|
457
|
-
if object_schema.__name__ == mlrun.
|
|
465
|
+
if object_schema.__name__ == mlrun.common.schemas.FeatureSet.__name__:
|
|
458
466
|
return mlrun.api.utils.singletons.db.get_db().list_feature_sets_tags(
|
|
459
467
|
db_session, project
|
|
460
468
|
)
|
|
461
|
-
elif object_schema.__name__ == mlrun.
|
|
469
|
+
elif object_schema.__name__ == mlrun.common.schemas.FeatureVector.__name__:
|
|
462
470
|
return mlrun.api.utils.singletons.db.get_db().list_feature_vectors_tags(
|
|
463
471
|
db_session, project
|
|
464
472
|
)
|
|
@@ -477,11 +485,11 @@ class FeatureStore(
|
|
|
477
485
|
uid: typing.Optional[str] = None,
|
|
478
486
|
):
|
|
479
487
|
project = project or mlrun.mlconf.default_project
|
|
480
|
-
if object_schema.__name__ == mlrun.
|
|
488
|
+
if object_schema.__name__ == mlrun.common.schemas.FeatureSet.__name__:
|
|
481
489
|
mlrun.api.utils.singletons.db.get_db().delete_feature_set(
|
|
482
490
|
db_session, project, name, tag, uid
|
|
483
491
|
)
|
|
484
|
-
elif object_schema.__name__ == mlrun.
|
|
492
|
+
elif object_schema.__name__ == mlrun.common.schemas.FeatureVector.__name__:
|
|
485
493
|
mlrun.api.utils.singletons.db.get_db().delete_feature_vector(
|
|
486
494
|
db_session, project, name, tag, uid
|
|
487
495
|
)
|
|
@@ -519,7 +527,7 @@ class FeatureStore(
|
|
|
519
527
|
@staticmethod
|
|
520
528
|
def _validate_and_enrich_identity_for_object_store(
|
|
521
529
|
object_: typing.Union[
|
|
522
|
-
mlrun.
|
|
530
|
+
mlrun.common.schemas.FeatureSet, mlrun.common.schemas.FeatureVector
|
|
523
531
|
],
|
|
524
532
|
project: str,
|
|
525
533
|
name: str,
|
|
@@ -550,7 +558,7 @@ class FeatureStore(
|
|
|
550
558
|
def _validate_and_enrich_identity_for_object_creation(
|
|
551
559
|
project: str,
|
|
552
560
|
object_: typing.Union[
|
|
553
|
-
mlrun.
|
|
561
|
+
mlrun.common.schemas.FeatureSet, mlrun.common.schemas.FeatureVector
|
|
554
562
|
],
|
|
555
563
|
):
|
|
556
564
|
object_type = object_.__class__.__name__
|
mlrun/api/crud/functions.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.
|
|
@@ -17,10 +17,10 @@ import typing
|
|
|
17
17
|
import sqlalchemy.orm
|
|
18
18
|
|
|
19
19
|
import mlrun.api.api.utils
|
|
20
|
-
import mlrun.api.schemas
|
|
21
20
|
import mlrun.api.utils.projects.remotes.follower
|
|
22
21
|
import mlrun.api.utils.singletons.db
|
|
23
22
|
import mlrun.api.utils.singletons.project_member
|
|
23
|
+
import mlrun.common.schemas
|
|
24
24
|
import mlrun.config
|
|
25
25
|
import mlrun.errors
|
|
26
26
|
import mlrun.utils.singleton
|
|
@@ -37,7 +37,7 @@ class Functions(
|
|
|
37
37
|
project: str = mlrun.mlconf.default_project,
|
|
38
38
|
tag: str = "",
|
|
39
39
|
versioned: bool = False,
|
|
40
|
-
auth_info: mlrun.
|
|
40
|
+
auth_info: mlrun.common.schemas.AuthInfo = None,
|
|
41
41
|
) -> str:
|
|
42
42
|
project = project or mlrun.mlconf.default_project
|
|
43
43
|
if auth_info:
|
mlrun/api/crud/hub.py
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# Copyright 2023 Iguazio
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
#
|
|
15
|
+
import json
|
|
16
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
17
|
+
|
|
18
|
+
import mlrun.api.utils.singletons.k8s
|
|
19
|
+
import mlrun.common.schemas
|
|
20
|
+
import mlrun.common.schemas.hub
|
|
21
|
+
import mlrun.errors
|
|
22
|
+
import mlrun.utils.singleton
|
|
23
|
+
from mlrun.config import config
|
|
24
|
+
from mlrun.datastore import store_manager
|
|
25
|
+
|
|
26
|
+
from .secrets import Secrets, SecretsClientType
|
|
27
|
+
|
|
28
|
+
# Using a complex separator, as it's less likely someone will use it in a real secret name
|
|
29
|
+
secret_name_separator = "-__-"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Hub(metaclass=mlrun.utils.singleton.Singleton):
|
|
33
|
+
def __init__(self):
|
|
34
|
+
self._internal_project_name = config.hub.k8s_secrets_project_name
|
|
35
|
+
self._catalogs = {}
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def _in_k8s():
|
|
39
|
+
k8s_helper = mlrun.api.utils.singletons.k8s.get_k8s_helper()
|
|
40
|
+
return (
|
|
41
|
+
k8s_helper is not None and k8s_helper.is_running_inside_kubernetes_cluster()
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def _generate_credentials_secret_key(source, key=""):
|
|
46
|
+
full_key = source + secret_name_separator + key
|
|
47
|
+
return Secrets().generate_client_project_secret_key(
|
|
48
|
+
SecretsClientType.hub, full_key
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
def add_source(self, source: mlrun.common.schemas.hub.HubSource):
|
|
52
|
+
source_name = source.metadata.name
|
|
53
|
+
credentials = source.spec.credentials
|
|
54
|
+
if credentials:
|
|
55
|
+
self._store_source_credentials(source_name, credentials)
|
|
56
|
+
|
|
57
|
+
def remove_source(self, source_name):
|
|
58
|
+
self._catalogs.pop(source_name, None)
|
|
59
|
+
if not self._in_k8s():
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
source_credentials = self._get_source_credentials(source_name)
|
|
63
|
+
if not source_credentials:
|
|
64
|
+
return
|
|
65
|
+
secrets_to_delete = [
|
|
66
|
+
self._generate_credentials_secret_key(source_name, key)
|
|
67
|
+
for key in source_credentials
|
|
68
|
+
]
|
|
69
|
+
Secrets().delete_project_secrets(
|
|
70
|
+
self._internal_project_name,
|
|
71
|
+
mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
72
|
+
secrets_to_delete,
|
|
73
|
+
allow_internal_secrets=True,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
def _store_source_credentials(self, source_name, credentials: dict):
|
|
77
|
+
if not self._in_k8s():
|
|
78
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
79
|
+
"MLRun is not configured with k8s, hub source credentials cannot be stored securely"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
adjusted_credentials = {
|
|
83
|
+
self._generate_credentials_secret_key(source_name, key): value
|
|
84
|
+
for key, value in credentials.items()
|
|
85
|
+
}
|
|
86
|
+
Secrets().store_project_secrets(
|
|
87
|
+
self._internal_project_name,
|
|
88
|
+
mlrun.common.schemas.SecretsData(
|
|
89
|
+
provider=mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
90
|
+
secrets=adjusted_credentials,
|
|
91
|
+
),
|
|
92
|
+
allow_internal_secrets=True,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
def _get_source_credentials(self, source_name):
|
|
96
|
+
if not self._in_k8s():
|
|
97
|
+
return {}
|
|
98
|
+
|
|
99
|
+
secret_prefix = self._generate_credentials_secret_key(source_name)
|
|
100
|
+
secrets = (
|
|
101
|
+
Secrets()
|
|
102
|
+
.list_project_secrets(
|
|
103
|
+
self._internal_project_name,
|
|
104
|
+
mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
105
|
+
allow_secrets_from_k8s=True,
|
|
106
|
+
allow_internal_secrets=True,
|
|
107
|
+
)
|
|
108
|
+
.secrets
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
source_secrets = {}
|
|
112
|
+
for key, value in secrets.items():
|
|
113
|
+
if key.startswith(secret_prefix):
|
|
114
|
+
source_secrets[key[len(secret_prefix) :]] = value
|
|
115
|
+
|
|
116
|
+
return source_secrets
|
|
117
|
+
|
|
118
|
+
@staticmethod
|
|
119
|
+
def _get_asset_full_path(
|
|
120
|
+
source: mlrun.common.schemas.hub.HubSource,
|
|
121
|
+
item: mlrun.common.schemas.hub.HubItem,
|
|
122
|
+
asset: str,
|
|
123
|
+
):
|
|
124
|
+
"""
|
|
125
|
+
Combining the item path with the asset path.
|
|
126
|
+
|
|
127
|
+
:param source: Hub source object.
|
|
128
|
+
:param item: The relevant item to get the asset from.
|
|
129
|
+
:param asset: The asset name
|
|
130
|
+
:return: Full path to the asset, relative to the item directory.
|
|
131
|
+
"""
|
|
132
|
+
asset_path = item.spec.assets.get(asset, None)
|
|
133
|
+
if not asset_path:
|
|
134
|
+
raise mlrun.errors.MLRunNotFoundError(
|
|
135
|
+
f"Asset={asset} not found. "
|
|
136
|
+
f"item={item.metadata.name}, version={item.metadata.version}, tag={item.metadata.tag}"
|
|
137
|
+
)
|
|
138
|
+
item_path = item.metadata.get_relative_path()
|
|
139
|
+
return source.get_full_uri(item_path + asset_path)
|
|
140
|
+
|
|
141
|
+
@staticmethod
|
|
142
|
+
def _transform_catalog_dict_to_schema(
|
|
143
|
+
source: mlrun.common.schemas.hub.HubSource, catalog_dict: Dict[str, Any]
|
|
144
|
+
) -> mlrun.common.schemas.hub.HubCatalog:
|
|
145
|
+
"""
|
|
146
|
+
Transforms catalog dictionary to HubCatalog schema
|
|
147
|
+
:param source: Hub source object.
|
|
148
|
+
:param catalog_dict: raw catalog dict, top level keys are item names,
|
|
149
|
+
second level keys are version tags ("latest, "1.1.0", ...) and
|
|
150
|
+
bottom level keys include spec as a dict and all the rest is considered as metadata.
|
|
151
|
+
:return: catalog object
|
|
152
|
+
"""
|
|
153
|
+
catalog = mlrun.common.schemas.hub.HubCatalog(
|
|
154
|
+
catalog=[], channel=source.spec.channel
|
|
155
|
+
)
|
|
156
|
+
# Loop over objects, then over object versions.
|
|
157
|
+
for object_name, object_dict in catalog_dict.items():
|
|
158
|
+
for version_tag, version_dict in object_dict.items():
|
|
159
|
+
object_details_dict = version_dict.copy()
|
|
160
|
+
spec_dict = object_details_dict.pop("spec", {})
|
|
161
|
+
assets = object_details_dict.pop("assets", {})
|
|
162
|
+
metadata = mlrun.common.schemas.hub.HubItemMetadata(
|
|
163
|
+
tag=version_tag, **object_details_dict
|
|
164
|
+
)
|
|
165
|
+
item_uri = source.get_full_uri(metadata.get_relative_path())
|
|
166
|
+
spec = mlrun.common.schemas.hub.HubItemSpec(
|
|
167
|
+
item_uri=item_uri, assets=assets, **spec_dict
|
|
168
|
+
)
|
|
169
|
+
item = mlrun.common.schemas.hub.HubItem(
|
|
170
|
+
metadata=metadata,
|
|
171
|
+
spec=spec,
|
|
172
|
+
status=mlrun.common.schemas.ObjectStatus(),
|
|
173
|
+
)
|
|
174
|
+
catalog.catalog.append(item)
|
|
175
|
+
|
|
176
|
+
return catalog
|
|
177
|
+
|
|
178
|
+
def get_source_catalog(
|
|
179
|
+
self,
|
|
180
|
+
source: mlrun.common.schemas.hub.HubSource,
|
|
181
|
+
version: Optional[str] = None,
|
|
182
|
+
tag: Optional[str] = None,
|
|
183
|
+
force_refresh: bool = False,
|
|
184
|
+
) -> mlrun.common.schemas.hub.HubCatalog:
|
|
185
|
+
"""
|
|
186
|
+
Getting the catalog object by source.
|
|
187
|
+
If version and/or tag are given, the catalog will be filtered accordingly.
|
|
188
|
+
|
|
189
|
+
:param source: Hub source object.
|
|
190
|
+
:param version: version of items to filter by
|
|
191
|
+
:param tag: tag of items to filter by
|
|
192
|
+
:param force_refresh: if True, the catalog will be loaded from source always,
|
|
193
|
+
otherwise will be pulled from db (if loaded before)
|
|
194
|
+
:return: catalog object
|
|
195
|
+
"""
|
|
196
|
+
source_name = source.metadata.name
|
|
197
|
+
if not self._catalogs.get(source_name) or force_refresh:
|
|
198
|
+
url = source.get_catalog_uri()
|
|
199
|
+
credentials = self._get_source_credentials(source_name)
|
|
200
|
+
catalog_data = mlrun.run.get_object(url=url, secrets=credentials)
|
|
201
|
+
catalog_dict = json.loads(catalog_data)
|
|
202
|
+
catalog = self._transform_catalog_dict_to_schema(source, catalog_dict)
|
|
203
|
+
self._catalogs[source_name] = catalog
|
|
204
|
+
else:
|
|
205
|
+
catalog = self._catalogs[source_name]
|
|
206
|
+
|
|
207
|
+
result_catalog = mlrun.common.schemas.hub.HubCatalog(
|
|
208
|
+
catalog=[], channel=source.spec.channel
|
|
209
|
+
)
|
|
210
|
+
for item in catalog.catalog:
|
|
211
|
+
# Because tag and version are optionals,
|
|
212
|
+
# we filter the catalog by one of them with priority to tag
|
|
213
|
+
if (tag is None or item.metadata.tag == tag) and (
|
|
214
|
+
version is None or item.metadata.version == version
|
|
215
|
+
):
|
|
216
|
+
result_catalog.catalog.append(item)
|
|
217
|
+
|
|
218
|
+
return result_catalog
|
|
219
|
+
|
|
220
|
+
def get_item(
|
|
221
|
+
self,
|
|
222
|
+
source: mlrun.common.schemas.hub.HubSource,
|
|
223
|
+
item_name: str,
|
|
224
|
+
version: Optional[str] = None,
|
|
225
|
+
tag: Optional[str] = None,
|
|
226
|
+
force_refresh: bool = False,
|
|
227
|
+
) -> mlrun.common.schemas.hub.HubItem:
|
|
228
|
+
"""
|
|
229
|
+
Retrieve item from source. The item is filtered by tag and version.
|
|
230
|
+
|
|
231
|
+
:param source: Hub source object
|
|
232
|
+
:param item_name: name of the item to retrieve
|
|
233
|
+
:param version: version of the item
|
|
234
|
+
:param tag: tag of the item
|
|
235
|
+
:param force_refresh: if True, the catalog will be loaded from source always,
|
|
236
|
+
otherwise will be pulled from db (if loaded before)
|
|
237
|
+
|
|
238
|
+
:return: hub item object
|
|
239
|
+
|
|
240
|
+
:raise if the number of collected items from catalog is not exactly one.
|
|
241
|
+
"""
|
|
242
|
+
catalog = self.get_source_catalog(source, version, tag, force_refresh)
|
|
243
|
+
items = self._get_catalog_items_filtered_by_name(catalog.catalog, item_name)
|
|
244
|
+
num_items = len(items)
|
|
245
|
+
|
|
246
|
+
if not num_items:
|
|
247
|
+
raise mlrun.errors.MLRunNotFoundError(
|
|
248
|
+
f"Item not found. source={item_name}, version={version}"
|
|
249
|
+
)
|
|
250
|
+
if num_items > 1:
|
|
251
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
252
|
+
"Query resulted in more than 1 catalog items. "
|
|
253
|
+
+ f"source={item_name}, version={version}, tag={tag}"
|
|
254
|
+
)
|
|
255
|
+
return items[0]
|
|
256
|
+
|
|
257
|
+
@staticmethod
|
|
258
|
+
def _get_catalog_items_filtered_by_name(
|
|
259
|
+
catalog: List[mlrun.common.schemas.hub.HubItem],
|
|
260
|
+
item_name: str,
|
|
261
|
+
) -> List[mlrun.common.schemas.hub.HubItem]:
|
|
262
|
+
"""
|
|
263
|
+
Retrieve items from catalog filtered by name
|
|
264
|
+
|
|
265
|
+
:param catalog: list of items
|
|
266
|
+
:param item_name: item name to filter by
|
|
267
|
+
|
|
268
|
+
:return: list of item objects from catalog
|
|
269
|
+
"""
|
|
270
|
+
return [item for item in catalog if item.metadata.name == item_name]
|
|
271
|
+
|
|
272
|
+
def get_item_object_using_source_credentials(
|
|
273
|
+
self, source: mlrun.common.schemas.hub.HubSource, url
|
|
274
|
+
):
|
|
275
|
+
credentials = self._get_source_credentials(source.metadata.name)
|
|
276
|
+
|
|
277
|
+
if not url.startswith(source.spec.path):
|
|
278
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
279
|
+
"URL to retrieve must be located in the source filesystem tree"
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
if url.endswith("/"):
|
|
283
|
+
obj = store_manager.object(url=url, secrets=credentials)
|
|
284
|
+
listdir = obj.listdir()
|
|
285
|
+
return {
|
|
286
|
+
"listdir": listdir,
|
|
287
|
+
}
|
|
288
|
+
else:
|
|
289
|
+
catalog_data = mlrun.run.get_object(url=url, secrets=credentials)
|
|
290
|
+
return catalog_data
|
|
291
|
+
|
|
292
|
+
def get_asset(
|
|
293
|
+
self,
|
|
294
|
+
source: mlrun.common.schemas.hub.HubSource,
|
|
295
|
+
item: mlrun.common.schemas.hub.HubItem,
|
|
296
|
+
asset_name: str,
|
|
297
|
+
) -> Tuple[bytes, str]:
|
|
298
|
+
"""
|
|
299
|
+
Retrieve asset object from hub source.
|
|
300
|
+
|
|
301
|
+
:param source: hub source
|
|
302
|
+
:param item: hub item which contains the assets
|
|
303
|
+
:param asset_name: asset name, like source, example, etc.
|
|
304
|
+
|
|
305
|
+
:return: tuple of asset as bytes and url of asset
|
|
306
|
+
"""
|
|
307
|
+
credentials = self._get_source_credentials(source.metadata.name)
|
|
308
|
+
asset_path = self._get_asset_full_path(source, item, asset_name)
|
|
309
|
+
return (
|
|
310
|
+
mlrun.run.get_object(url=asset_path, secrets=credentials),
|
|
311
|
+
asset_path,
|
|
312
|
+
)
|