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
|
@@ -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.
|
|
@@ -31,9 +31,10 @@ from sqlalchemy import (
|
|
|
31
31
|
UniqueConstraint,
|
|
32
32
|
)
|
|
33
33
|
from sqlalchemy.ext.declarative import declarative_base
|
|
34
|
-
from sqlalchemy.orm import
|
|
34
|
+
from sqlalchemy.orm import relationship
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
import mlrun.common.schemas
|
|
37
|
+
import mlrun.utils.db
|
|
37
38
|
from mlrun.api.utils.db.sql_collation import SQLCollationUtil
|
|
38
39
|
|
|
39
40
|
Base = declarative_base()
|
|
@@ -41,42 +42,8 @@ NULL = None # Avoid flake8 issuing warnings when comparing in filter
|
|
|
41
42
|
run_time_fmt = "%Y-%m-%dT%H:%M:%S.%fZ"
|
|
42
43
|
|
|
43
44
|
|
|
44
|
-
class BaseModel:
|
|
45
|
-
def to_dict(self, exclude=None):
|
|
46
|
-
"""
|
|
47
|
-
NOTE - this function (currently) does not handle serializing relationships
|
|
48
|
-
"""
|
|
49
|
-
exclude = exclude or []
|
|
50
|
-
mapper = class_mapper(self.__class__)
|
|
51
|
-
columns = [column.key for column in mapper.columns if column.key not in exclude]
|
|
52
|
-
get_key_value = (
|
|
53
|
-
lambda c: (c, getattr(self, c).isoformat())
|
|
54
|
-
if isinstance(getattr(self, c), datetime)
|
|
55
|
-
else (c, getattr(self, c))
|
|
56
|
-
)
|
|
57
|
-
return dict(map(get_key_value, columns))
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
class HasStruct(BaseModel):
|
|
61
|
-
@property
|
|
62
|
-
def struct(self):
|
|
63
|
-
return pickle.loads(self.body)
|
|
64
|
-
|
|
65
|
-
@struct.setter
|
|
66
|
-
def struct(self, value):
|
|
67
|
-
self.body = pickle.dumps(value)
|
|
68
|
-
|
|
69
|
-
def to_dict(self, exclude=None):
|
|
70
|
-
"""
|
|
71
|
-
NOTE - this function (currently) does not handle serializing relationships
|
|
72
|
-
"""
|
|
73
|
-
exclude = exclude or []
|
|
74
|
-
exclude.append("body")
|
|
75
|
-
return super().to_dict(exclude)
|
|
76
|
-
|
|
77
|
-
|
|
78
45
|
def make_label(table):
|
|
79
|
-
class Label(Base, BaseModel):
|
|
46
|
+
class Label(Base, mlrun.utils.db.BaseModel):
|
|
80
47
|
__tablename__ = f"{table}_labels"
|
|
81
48
|
__table_args__ = (
|
|
82
49
|
UniqueConstraint("name", "parent", name=f"_{table}_labels_uc"),
|
|
@@ -91,7 +58,7 @@ def make_label(table):
|
|
|
91
58
|
|
|
92
59
|
|
|
93
60
|
def make_tag(table):
|
|
94
|
-
class Tag(Base, BaseModel):
|
|
61
|
+
class Tag(Base, mlrun.utils.db.BaseModel):
|
|
95
62
|
__tablename__ = f"{table}_tags"
|
|
96
63
|
__table_args__ = (
|
|
97
64
|
UniqueConstraint("project", "name", "obj_id", name=f"_{table}_tags_uc"),
|
|
@@ -108,7 +75,7 @@ def make_tag(table):
|
|
|
108
75
|
# TODO: don't want to refactor everything in one PR so splitting this function to 2 versions - eventually only this one
|
|
109
76
|
# should be used
|
|
110
77
|
def make_tag_v2(table):
|
|
111
|
-
class Tag(Base, BaseModel):
|
|
78
|
+
class Tag(Base, mlrun.utils.db.BaseModel):
|
|
112
79
|
__tablename__ = f"{table}_tags"
|
|
113
80
|
__table_args__ = (
|
|
114
81
|
UniqueConstraint("project", "name", "obj_name", name=f"_{table}_tags_uc"),
|
|
@@ -126,11 +93,51 @@ def make_tag_v2(table):
|
|
|
126
93
|
return Tag
|
|
127
94
|
|
|
128
95
|
|
|
96
|
+
def make_notification(table):
|
|
97
|
+
class Notification(Base, mlrun.utils.db.BaseModel):
|
|
98
|
+
__tablename__ = f"{table}_notifications"
|
|
99
|
+
__table_args__ = (
|
|
100
|
+
UniqueConstraint("name", "parent_id", name=f"_{table}_notifications_uc"),
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
id = Column(Integer, primary_key=True)
|
|
104
|
+
project = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
105
|
+
name = Column(
|
|
106
|
+
String(255, collation=SQLCollationUtil.collation()), nullable=False
|
|
107
|
+
)
|
|
108
|
+
kind = Column(
|
|
109
|
+
String(255, collation=SQLCollationUtil.collation()), nullable=False
|
|
110
|
+
)
|
|
111
|
+
message = Column(
|
|
112
|
+
String(255, collation=SQLCollationUtil.collation()), nullable=False
|
|
113
|
+
)
|
|
114
|
+
severity = Column(
|
|
115
|
+
String(255, collation=SQLCollationUtil.collation()), nullable=False
|
|
116
|
+
)
|
|
117
|
+
when = Column(
|
|
118
|
+
String(255, collation=SQLCollationUtil.collation()), nullable=False
|
|
119
|
+
)
|
|
120
|
+
condition = Column(
|
|
121
|
+
String(255, collation=SQLCollationUtil.collation()), nullable=False
|
|
122
|
+
)
|
|
123
|
+
params = Column("params", JSON)
|
|
124
|
+
parent_id = Column(Integer, ForeignKey(f"{table}.id"))
|
|
125
|
+
sent_time = Column(
|
|
126
|
+
TIMESTAMP(),
|
|
127
|
+
nullable=True,
|
|
128
|
+
)
|
|
129
|
+
status = Column(
|
|
130
|
+
String(255, collation=SQLCollationUtil.collation()), nullable=False
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
return Notification
|
|
134
|
+
|
|
135
|
+
|
|
129
136
|
# quell SQLAlchemy warnings on duplicate class name (Label)
|
|
130
137
|
with warnings.catch_warnings():
|
|
131
138
|
warnings.simplefilter("ignore")
|
|
132
139
|
|
|
133
|
-
class Artifact(Base, HasStruct):
|
|
140
|
+
class Artifact(Base, mlrun.utils.db.HasStruct):
|
|
134
141
|
__tablename__ = "artifacts"
|
|
135
142
|
__table_args__ = (
|
|
136
143
|
UniqueConstraint("uid", "project", "key", name="_artifacts_uc"),
|
|
@@ -144,14 +151,14 @@ with warnings.catch_warnings():
|
|
|
144
151
|
project = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
145
152
|
uid = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
146
153
|
updated = Column(TIMESTAMP)
|
|
147
|
-
# TODO: change to JSON, see mlrun/
|
|
154
|
+
# TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
|
|
148
155
|
body = Column(BLOB)
|
|
149
156
|
labels = relationship(Label)
|
|
150
157
|
|
|
151
158
|
def get_identifier_string(self) -> str:
|
|
152
159
|
return f"{self.project}/{self.key}/{self.uid}"
|
|
153
160
|
|
|
154
|
-
class Function(Base, HasStruct):
|
|
161
|
+
class Function(Base, mlrun.utils.db.HasStruct):
|
|
155
162
|
__tablename__ = "functions"
|
|
156
163
|
__table_args__ = (
|
|
157
164
|
UniqueConstraint("name", "project", "uid", name="_functions_uc"),
|
|
@@ -164,7 +171,7 @@ with warnings.catch_warnings():
|
|
|
164
171
|
name = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
165
172
|
project = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
166
173
|
uid = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
167
|
-
# TODO: change to JSON, see mlrun/
|
|
174
|
+
# TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
|
|
168
175
|
body = Column(BLOB)
|
|
169
176
|
updated = Column(TIMESTAMP)
|
|
170
177
|
labels = relationship(Label)
|
|
@@ -172,19 +179,19 @@ with warnings.catch_warnings():
|
|
|
172
179
|
def get_identifier_string(self) -> str:
|
|
173
180
|
return f"{self.project}/{self.name}/{self.uid}"
|
|
174
181
|
|
|
175
|
-
class Log(Base, BaseModel):
|
|
182
|
+
class Log(Base, mlrun.utils.db.BaseModel):
|
|
176
183
|
__tablename__ = "logs"
|
|
177
184
|
|
|
178
185
|
id = Column(Integer, primary_key=True)
|
|
179
186
|
uid = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
180
187
|
project = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
181
|
-
# TODO: change to JSON, see mlrun/
|
|
188
|
+
# TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
|
|
182
189
|
body = Column(BLOB)
|
|
183
190
|
|
|
184
191
|
def get_identifier_string(self) -> str:
|
|
185
192
|
return f"{self.project}/{self.uid}"
|
|
186
193
|
|
|
187
|
-
class Run(Base, HasStruct):
|
|
194
|
+
class Run(Base, mlrun.utils.db.HasStruct):
|
|
188
195
|
__tablename__ = "runs"
|
|
189
196
|
__table_args__ = (
|
|
190
197
|
UniqueConstraint("uid", "project", "iteration", name="_runs_uc"),
|
|
@@ -192,6 +199,7 @@ with warnings.catch_warnings():
|
|
|
192
199
|
|
|
193
200
|
Label = make_label(__tablename__)
|
|
194
201
|
Tag = make_tag(__tablename__)
|
|
202
|
+
Notification = make_notification(__tablename__)
|
|
195
203
|
|
|
196
204
|
id = Column(Integer, primary_key=True)
|
|
197
205
|
uid = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
@@ -201,7 +209,7 @@ with warnings.catch_warnings():
|
|
|
201
209
|
)
|
|
202
210
|
iteration = Column(Integer)
|
|
203
211
|
state = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
204
|
-
# TODO: change to JSON, see mlrun/
|
|
212
|
+
# TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
|
|
205
213
|
body = Column(BLOB)
|
|
206
214
|
start_time = Column(TIMESTAMP)
|
|
207
215
|
# requested logs column indicates whether logs were requested for this run
|
|
@@ -211,11 +219,12 @@ with warnings.catch_warnings():
|
|
|
211
219
|
requested_logs = Column(BOOLEAN)
|
|
212
220
|
updated = Column(TIMESTAMP, default=datetime.utcnow)
|
|
213
221
|
labels = relationship(Label)
|
|
222
|
+
notifications = relationship(Notification, cascade="all, delete-orphan")
|
|
214
223
|
|
|
215
224
|
def get_identifier_string(self) -> str:
|
|
216
225
|
return f"{self.project}/{self.uid}/{self.iteration}"
|
|
217
226
|
|
|
218
|
-
class BackgroundTask(Base, BaseModel):
|
|
227
|
+
class BackgroundTask(Base, mlrun.utils.db.BaseModel):
|
|
219
228
|
__tablename__ = "background_tasks"
|
|
220
229
|
__table_args__ = (
|
|
221
230
|
UniqueConstraint("name", "project", name="_background_tasks_uc"),
|
|
@@ -233,7 +242,7 @@ with warnings.catch_warnings():
|
|
|
233
242
|
state = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
234
243
|
timeout = Column(Integer)
|
|
235
244
|
|
|
236
|
-
class Schedule(Base, BaseModel):
|
|
245
|
+
class Schedule(Base, mlrun.utils.db.BaseModel):
|
|
237
246
|
__tablename__ = "schedules_v2"
|
|
238
247
|
__table_args__ = (UniqueConstraint("project", "name", name="_schedules_v2_uc"),)
|
|
239
248
|
|
|
@@ -252,7 +261,7 @@ with warnings.catch_warnings():
|
|
|
252
261
|
creation_time = Column(TIMESTAMP)
|
|
253
262
|
cron_trigger_str = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
254
263
|
last_run_uri = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
255
|
-
# TODO: change to JSON, see mlrun/
|
|
264
|
+
# TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
|
|
256
265
|
struct = Column(BLOB)
|
|
257
266
|
labels = relationship(Label, cascade="all, delete-orphan")
|
|
258
267
|
concurrency_limit = Column(Integer, nullable=False)
|
|
@@ -270,11 +279,11 @@ with warnings.catch_warnings():
|
|
|
270
279
|
self.struct = pickle.dumps(value)
|
|
271
280
|
|
|
272
281
|
@property
|
|
273
|
-
def cron_trigger(self) -> schemas.ScheduleCronTrigger:
|
|
282
|
+
def cron_trigger(self) -> mlrun.common.schemas.ScheduleCronTrigger:
|
|
274
283
|
return orjson.loads(self.cron_trigger_str)
|
|
275
284
|
|
|
276
285
|
@cron_trigger.setter
|
|
277
|
-
def cron_trigger(self, trigger: schemas.ScheduleCronTrigger):
|
|
286
|
+
def cron_trigger(self, trigger: mlrun.common.schemas.ScheduleCronTrigger):
|
|
278
287
|
self.cron_trigger_str = orjson.dumps(trigger.dict(exclude_unset=True))
|
|
279
288
|
|
|
280
289
|
# Define "many to many" users/projects
|
|
@@ -285,14 +294,14 @@ with warnings.catch_warnings():
|
|
|
285
294
|
Column("user_id", Integer, ForeignKey("users.id")),
|
|
286
295
|
)
|
|
287
296
|
|
|
288
|
-
class User(Base, BaseModel):
|
|
297
|
+
class User(Base, mlrun.utils.db.BaseModel):
|
|
289
298
|
__tablename__ = "users"
|
|
290
299
|
__table_args__ = (UniqueConstraint("name", name="_users_uc"),)
|
|
291
300
|
|
|
292
301
|
id = Column(Integer, primary_key=True)
|
|
293
302
|
name = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
294
303
|
|
|
295
|
-
class Project(Base, BaseModel):
|
|
304
|
+
class Project(Base, mlrun.utils.db.BaseModel):
|
|
296
305
|
__tablename__ = "projects"
|
|
297
306
|
# For now since we use project name a lot
|
|
298
307
|
__table_args__ = (UniqueConstraint("name", name="_projects_uc"),)
|
|
@@ -304,7 +313,7 @@ with warnings.catch_warnings():
|
|
|
304
313
|
source = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
305
314
|
# the attribute name used to be _spec which is just a wrong naming, the attribute was renamed to _full_object
|
|
306
315
|
# leaving the column as is to prevent redundant migration
|
|
307
|
-
# TODO: change to JSON, see mlrun/
|
|
316
|
+
# TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
|
|
308
317
|
_full_object = Column("spec", BLOB)
|
|
309
318
|
created = Column(TIMESTAMP, default=datetime.utcnow)
|
|
310
319
|
state = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
@@ -326,7 +335,7 @@ with warnings.catch_warnings():
|
|
|
326
335
|
def full_object(self, value):
|
|
327
336
|
self._full_object = pickle.dumps(value)
|
|
328
337
|
|
|
329
|
-
class Feature(Base, BaseModel):
|
|
338
|
+
class Feature(Base, mlrun.utils.db.BaseModel):
|
|
330
339
|
__tablename__ = "features"
|
|
331
340
|
id = Column(Integer, primary_key=True)
|
|
332
341
|
feature_set_id = Column(Integer, ForeignKey("feature_sets.id"))
|
|
@@ -340,7 +349,7 @@ with warnings.catch_warnings():
|
|
|
340
349
|
def get_identifier_string(self) -> str:
|
|
341
350
|
return f"{self.project}/{self.name}"
|
|
342
351
|
|
|
343
|
-
class Entity(Base, BaseModel):
|
|
352
|
+
class Entity(Base, mlrun.utils.db.BaseModel):
|
|
344
353
|
__tablename__ = "entities"
|
|
345
354
|
id = Column(Integer, primary_key=True)
|
|
346
355
|
feature_set_id = Column(Integer, ForeignKey("feature_sets.id"))
|
|
@@ -354,7 +363,7 @@ with warnings.catch_warnings():
|
|
|
354
363
|
def get_identifier_string(self) -> str:
|
|
355
364
|
return f"{self.project}/{self.name}"
|
|
356
365
|
|
|
357
|
-
class FeatureSet(Base, BaseModel):
|
|
366
|
+
class FeatureSet(Base, mlrun.utils.db.BaseModel):
|
|
358
367
|
__tablename__ = "feature_sets"
|
|
359
368
|
__table_args__ = (
|
|
360
369
|
UniqueConstraint("name", "project", "uid", name="_feature_set_uc"),
|
|
@@ -390,7 +399,7 @@ with warnings.catch_warnings():
|
|
|
390
399
|
def full_object(self, value):
|
|
391
400
|
self._full_object = json.dumps(value, default=str)
|
|
392
401
|
|
|
393
|
-
class FeatureVector(Base, BaseModel):
|
|
402
|
+
class FeatureVector(Base, mlrun.utils.db.BaseModel):
|
|
394
403
|
__tablename__ = "feature_vectors"
|
|
395
404
|
__table_args__ = (
|
|
396
405
|
UniqueConstraint("name", "project", "uid", name="_feature_vectors_uc"),
|
|
@@ -423,9 +432,9 @@ with warnings.catch_warnings():
|
|
|
423
432
|
def full_object(self, value):
|
|
424
433
|
self._full_object = json.dumps(value, default=str)
|
|
425
434
|
|
|
426
|
-
class
|
|
427
|
-
__tablename__ = "
|
|
428
|
-
__table_args__ = (UniqueConstraint("name", name="
|
|
435
|
+
class HubSource(Base, mlrun.utils.db.BaseModel):
|
|
436
|
+
__tablename__ = "hub_sources"
|
|
437
|
+
__table_args__ = (UniqueConstraint("name", name="_hub_sources_uc"),)
|
|
429
438
|
|
|
430
439
|
id = Column(Integer, primary_key=True)
|
|
431
440
|
name = Column(String(255, collation=SQLCollationUtil.collation()))
|
|
@@ -447,7 +456,7 @@ with warnings.catch_warnings():
|
|
|
447
456
|
def full_object(self, value):
|
|
448
457
|
self._full_object = json.dumps(value, default=str)
|
|
449
458
|
|
|
450
|
-
class DataVersion(Base, BaseModel):
|
|
459
|
+
class DataVersion(Base, mlrun.utils.db.BaseModel):
|
|
451
460
|
__tablename__ = "data_versions"
|
|
452
461
|
__table_args__ = (UniqueConstraint("version", name="_versions_uc"),)
|
|
453
462
|
|
|
@@ -459,5 +468,8 @@ with warnings.catch_warnings():
|
|
|
459
468
|
# Must be after all table definitions
|
|
460
469
|
_tagged = [cls for cls in Base.__subclasses__() if hasattr(cls, "Tag")]
|
|
461
470
|
_labeled = [cls for cls in Base.__subclasses__() if hasattr(cls, "Label")]
|
|
471
|
+
_with_notifications = [
|
|
472
|
+
cls for cls in Base.__subclasses__() if hasattr(cls, "Notification")
|
|
473
|
+
]
|
|
462
474
|
_classes = [cls for cls in Base.__subclasses__()]
|
|
463
475
|
_table2cls = {cls.__table__.name: cls for cls in Base.__subclasses__()}
|
mlrun/api/db/sqldb/session.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.
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
#
|
|
15
|
+
|
|
16
|
+
import typing
|
|
17
|
+
|
|
15
18
|
from sqlalchemy import create_engine
|
|
16
19
|
from sqlalchemy.engine import Engine
|
|
17
20
|
from sqlalchemy.orm import Session
|
|
@@ -19,35 +22,38 @@ from sqlalchemy.orm import sessionmaker as SessionMaker
|
|
|
19
22
|
|
|
20
23
|
from mlrun.config import config
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
# TODO: wrap the following functions in a singleton class
|
|
26
|
+
_engines: typing.Dict[str, Engine] = {}
|
|
27
|
+
_session_makers: typing.Dict[str, SessionMaker] = {}
|
|
24
28
|
|
|
25
29
|
|
|
26
30
|
# doing lazy load to allow tests to initialize the engine
|
|
27
|
-
def get_engine() -> Engine:
|
|
28
|
-
global
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
def get_engine(dsn=None) -> Engine:
|
|
32
|
+
global _engines
|
|
33
|
+
dsn = dsn or config.httpdb.dsn
|
|
34
|
+
if dsn not in _engines:
|
|
35
|
+
_init_engine(dsn=dsn)
|
|
36
|
+
return _engines[dsn]
|
|
32
37
|
|
|
33
38
|
|
|
34
|
-
def create_session() -> Session:
|
|
35
|
-
session_maker = _get_session_maker()
|
|
39
|
+
def create_session(dsn=None) -> Session:
|
|
40
|
+
session_maker = _get_session_maker(dsn=dsn)
|
|
36
41
|
return session_maker()
|
|
37
42
|
|
|
38
43
|
|
|
39
44
|
# doing lazy load to allow tests to initialize the engine
|
|
40
|
-
def _get_session_maker() -> SessionMaker:
|
|
41
|
-
global
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
def _get_session_maker(dsn) -> SessionMaker:
|
|
46
|
+
global _session_makers
|
|
47
|
+
dsn = dsn or config.httpdb.dsn
|
|
48
|
+
if dsn not in _session_makers:
|
|
49
|
+
_init_session_maker(dsn=dsn)
|
|
50
|
+
return _session_makers[dsn]
|
|
45
51
|
|
|
46
52
|
|
|
47
53
|
# TODO: we accept the dsn here to enable tests to override it, the "right" thing will be that config will be easily
|
|
48
54
|
# overridable by tests (today when you import the config it is already being initialized.. should be lazy load)
|
|
49
55
|
def _init_engine(dsn=None):
|
|
50
|
-
global
|
|
56
|
+
global _engines
|
|
51
57
|
dsn = dsn or config.httpdb.dsn
|
|
52
58
|
kwargs = {}
|
|
53
59
|
if "mysql" in dsn:
|
|
@@ -62,9 +68,10 @@ def _init_engine(dsn=None):
|
|
|
62
68
|
"max_overflow": max_overflow,
|
|
63
69
|
}
|
|
64
70
|
engine = create_engine(dsn, **kwargs)
|
|
65
|
-
|
|
71
|
+
_engines[dsn] = engine
|
|
72
|
+
_init_session_maker(dsn=dsn)
|
|
66
73
|
|
|
67
74
|
|
|
68
|
-
def _init_session_maker():
|
|
69
|
-
global
|
|
70
|
-
|
|
75
|
+
def _init_session_maker(dsn):
|
|
76
|
+
global _session_makers
|
|
77
|
+
_session_makers[dsn] = SessionMaker(bind=get_engine(dsn=dsn))
|
mlrun/api/initial_data.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.
|
|
@@ -19,6 +19,7 @@ import pathlib
|
|
|
19
19
|
import typing
|
|
20
20
|
|
|
21
21
|
import dateutil.parser
|
|
22
|
+
import pydantic.error_wrappers
|
|
22
23
|
import pymysql.err
|
|
23
24
|
import sqlalchemy.exc
|
|
24
25
|
import sqlalchemy.orm
|
|
@@ -26,12 +27,12 @@ import sqlalchemy.orm
|
|
|
26
27
|
import mlrun.api.db.sqldb.db
|
|
27
28
|
import mlrun.api.db.sqldb.helpers
|
|
28
29
|
import mlrun.api.db.sqldb.models
|
|
29
|
-
import mlrun.api.schemas
|
|
30
30
|
import mlrun.api.utils.db.alembic
|
|
31
31
|
import mlrun.api.utils.db.backup
|
|
32
32
|
import mlrun.api.utils.db.mysql
|
|
33
33
|
import mlrun.api.utils.db.sqlite_migration
|
|
34
34
|
import mlrun.artifacts
|
|
35
|
+
import mlrun.common.schemas
|
|
35
36
|
from mlrun.api.db.init_db import init_db
|
|
36
37
|
from mlrun.api.db.session import close_session, create_session
|
|
37
38
|
from mlrun.config import config
|
|
@@ -43,7 +44,20 @@ def init_data(
|
|
|
43
44
|
from_scratch: bool = False, perform_migrations_if_needed: bool = False
|
|
44
45
|
) -> None:
|
|
45
46
|
logger.info("Initializing DB data")
|
|
46
|
-
|
|
47
|
+
|
|
48
|
+
# create mysql util, and if mlrun is configured to use mysql, wait for it to be live and set its db modes
|
|
49
|
+
mysql_util = mlrun.api.utils.db.mysql.MySQLUtil(logger)
|
|
50
|
+
if mysql_util.get_mysql_dsn_data():
|
|
51
|
+
mysql_util.wait_for_db_liveness()
|
|
52
|
+
mysql_util.set_modes(mlrun.mlconf.httpdb.db.mysql.modes)
|
|
53
|
+
else:
|
|
54
|
+
dsn = mysql_util.get_dsn()
|
|
55
|
+
if "sqlite" in dsn:
|
|
56
|
+
logger.debug("SQLite DB is used, liveness check not needed")
|
|
57
|
+
else:
|
|
58
|
+
logger.warn(
|
|
59
|
+
f"Invalid mysql dsn: {dsn}, assuming live and skipping liveness verification"
|
|
60
|
+
)
|
|
47
61
|
|
|
48
62
|
sqlite_migration_util = None
|
|
49
63
|
if not from_scratch and config.httpdb.db.database_migration_mode == "enabled":
|
|
@@ -62,7 +76,7 @@ def init_data(
|
|
|
62
76
|
and not perform_migrations_if_needed
|
|
63
77
|
and is_migration_needed
|
|
64
78
|
):
|
|
65
|
-
state = mlrun.
|
|
79
|
+
state = mlrun.common.schemas.APIStates.waiting_for_migrations
|
|
66
80
|
logger.info("Migration is needed, changing API state", state=state)
|
|
67
81
|
config.httpdb.state = state
|
|
68
82
|
return
|
|
@@ -73,7 +87,7 @@ def init_data(
|
|
|
73
87
|
db_backup.backup_database()
|
|
74
88
|
|
|
75
89
|
logger.info("Creating initial data")
|
|
76
|
-
config.httpdb.state = mlrun.
|
|
90
|
+
config.httpdb.state = mlrun.common.schemas.APIStates.migrations_in_progress
|
|
77
91
|
|
|
78
92
|
if is_migration_from_scratch or is_migration_needed:
|
|
79
93
|
try:
|
|
@@ -81,15 +95,15 @@ def init_data(
|
|
|
81
95
|
|
|
82
96
|
_perform_database_migration(sqlite_migration_util)
|
|
83
97
|
|
|
98
|
+
init_db()
|
|
84
99
|
db_session = create_session()
|
|
85
100
|
try:
|
|
86
|
-
init_db(db_session)
|
|
87
101
|
_add_initial_data(db_session)
|
|
88
102
|
_perform_data_migrations(db_session)
|
|
89
103
|
finally:
|
|
90
104
|
close_session(db_session)
|
|
91
105
|
except Exception:
|
|
92
|
-
state = mlrun.
|
|
106
|
+
state = mlrun.common.schemas.APIStates.migrations_failed
|
|
93
107
|
logger.warning("Migrations failed, changing API state", state=state)
|
|
94
108
|
config.httpdb.state = state
|
|
95
109
|
raise
|
|
@@ -97,17 +111,19 @@ def init_data(
|
|
|
97
111
|
# should happen - we can't do it here because it requires an asyncio loop which can't be accessible here
|
|
98
112
|
# therefore moving to migration_completed state, and other component will take care of moving to online
|
|
99
113
|
if not is_migration_from_scratch and is_migration_needed:
|
|
100
|
-
config.httpdb.state = mlrun.
|
|
114
|
+
config.httpdb.state = mlrun.common.schemas.APIStates.migrations_completed
|
|
101
115
|
else:
|
|
102
|
-
config.httpdb.state = mlrun.
|
|
116
|
+
config.httpdb.state = mlrun.common.schemas.APIStates.online
|
|
103
117
|
logger.info("Initial data created")
|
|
104
118
|
|
|
105
119
|
|
|
106
120
|
# If the data_table version doesn't exist, we can assume the data version is 1.
|
|
107
|
-
# This is because data version 1 points to
|
|
121
|
+
# This is because data version 1 points to a data migration which was added back in 0.6.0, and
|
|
108
122
|
# upgrading from a version earlier than 0.6.0 to v>=0.8.0 is not supported.
|
|
109
123
|
data_version_prior_to_table_addition = 1
|
|
110
|
-
|
|
124
|
+
|
|
125
|
+
# NOTE: Bump this number when adding a new data migration
|
|
126
|
+
latest_data_version = 3
|
|
111
127
|
|
|
112
128
|
|
|
113
129
|
def _resolve_needed_operations(
|
|
@@ -212,13 +228,16 @@ def _perform_data_migrations(db_session: sqlalchemy.orm.Session):
|
|
|
212
228
|
_perform_version_1_data_migrations(db, db_session)
|
|
213
229
|
if current_data_version < 2:
|
|
214
230
|
_perform_version_2_data_migrations(db, db_session)
|
|
231
|
+
if current_data_version < 3:
|
|
232
|
+
_perform_version_3_data_migrations(db, db_session)
|
|
233
|
+
|
|
215
234
|
db.create_data_version(db_session, str(latest_data_version))
|
|
216
235
|
|
|
217
236
|
|
|
218
237
|
def _add_initial_data(db_session: sqlalchemy.orm.Session):
|
|
219
238
|
# FileDB is not really a thing anymore, so using SQLDB directly
|
|
220
239
|
db = mlrun.api.db.sqldb.db.SQLDB("")
|
|
221
|
-
|
|
240
|
+
_add_default_hub_source_if_needed(db, db_session)
|
|
222
241
|
_add_data_version(db, db_session)
|
|
223
242
|
|
|
224
243
|
|
|
@@ -465,6 +484,30 @@ def _align_runs_table(
|
|
|
465
484
|
db._upsert(db_session, [run], ignore=True)
|
|
466
485
|
|
|
467
486
|
|
|
487
|
+
def _perform_version_3_data_migrations(
|
|
488
|
+
db: mlrun.api.db.sqldb.db.SQLDB, db_session: sqlalchemy.orm.Session
|
|
489
|
+
):
|
|
490
|
+
_rename_marketplace_kind_to_hub(db, db_session)
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
def _rename_marketplace_kind_to_hub(
|
|
494
|
+
db: mlrun.api.db.sqldb.db.SQLDB, db_session: sqlalchemy.orm.Session
|
|
495
|
+
):
|
|
496
|
+
logger.info("Renaming 'Marketplace' kinds to 'Hub'")
|
|
497
|
+
|
|
498
|
+
hubs = db._list_hub_sources_without_transform(db_session)
|
|
499
|
+
for hub in hubs:
|
|
500
|
+
hub_dict = hub.full_object
|
|
501
|
+
|
|
502
|
+
# rename kind from "MarketplaceSource" to "HubSource"
|
|
503
|
+
if "Marketplace" in hub_dict.get("kind", ""):
|
|
504
|
+
hub_dict["kind"] = hub_dict["kind"].replace("Marketplace", "Hub")
|
|
505
|
+
|
|
506
|
+
# save the object back to the db
|
|
507
|
+
hub.full_object = hub_dict
|
|
508
|
+
db._upsert(db_session, [hub], ignore=True)
|
|
509
|
+
|
|
510
|
+
|
|
468
511
|
def _perform_version_1_data_migrations(
|
|
469
512
|
db: mlrun.api.db.sqldb.db.SQLDB, db_session: sqlalchemy.orm.Session
|
|
470
513
|
):
|
|
@@ -482,7 +525,7 @@ def _enrich_project_state(
|
|
|
482
525
|
changed = False
|
|
483
526
|
if not project.spec.desired_state:
|
|
484
527
|
changed = True
|
|
485
|
-
project.spec.desired_state = mlrun.
|
|
528
|
+
project.spec.desired_state = mlrun.common.schemas.ProjectState.online
|
|
486
529
|
if not project.status.state:
|
|
487
530
|
changed = True
|
|
488
531
|
project.status.state = project.spec.desired_state
|
|
@@ -494,32 +537,47 @@ def _enrich_project_state(
|
|
|
494
537
|
db.store_project(db_session, project.metadata.name, project)
|
|
495
538
|
|
|
496
539
|
|
|
497
|
-
def
|
|
540
|
+
def _add_default_hub_source_if_needed(
|
|
498
541
|
db: mlrun.api.db.sqldb.db.SQLDB, db_session: sqlalchemy.orm.Session
|
|
499
542
|
):
|
|
500
543
|
try:
|
|
501
|
-
hub_marketplace_source = db.
|
|
502
|
-
db_session, config.
|
|
544
|
+
hub_marketplace_source = db.get_hub_source(
|
|
545
|
+
db_session, config.hub.default_source.name
|
|
503
546
|
)
|
|
504
547
|
except mlrun.errors.MLRunNotFoundError:
|
|
505
548
|
hub_marketplace_source = None
|
|
549
|
+
except pydantic.error_wrappers.ValidationError as exc:
|
|
550
|
+
|
|
551
|
+
# following the renaming of 'marketplace' to 'hub', validation errors can occur on the old 'marketplace'.
|
|
552
|
+
# this will be handled later in the data migrations, but for now - if a validation error occurs, we assume
|
|
553
|
+
# that a default hub source exists
|
|
554
|
+
if all(
|
|
555
|
+
[
|
|
556
|
+
"validation error for HubSource" in str(exc),
|
|
557
|
+
"value is not a valid enumeration member" in str(exc),
|
|
558
|
+
]
|
|
559
|
+
):
|
|
560
|
+
logger.info("Found existing default hub source, data migration needed")
|
|
561
|
+
hub_marketplace_source = True
|
|
562
|
+
else:
|
|
563
|
+
raise exc
|
|
506
564
|
|
|
507
565
|
if not hub_marketplace_source:
|
|
508
|
-
hub_source = mlrun.
|
|
509
|
-
# hub_source will be None if the configuration has
|
|
566
|
+
hub_source = mlrun.common.schemas.HubSource.generate_default_source()
|
|
567
|
+
# hub_source will be None if the configuration has hub.default_source.create=False
|
|
510
568
|
if hub_source:
|
|
511
|
-
logger.info("Adding default
|
|
512
|
-
# Not using db.store_marketplace_source() since it doesn't allow changing the default
|
|
513
|
-
hub_record = db.
|
|
514
|
-
mlrun.
|
|
515
|
-
index=mlrun.
|
|
569
|
+
logger.info("Adding default hub source")
|
|
570
|
+
# Not using db.store_marketplace_source() since it doesn't allow changing the default hub source.
|
|
571
|
+
hub_record = db._transform_hub_source_schema_to_record(
|
|
572
|
+
mlrun.common.schemas.IndexedHubSource(
|
|
573
|
+
index=mlrun.common.schemas.hub.last_source_index,
|
|
516
574
|
source=hub_source,
|
|
517
575
|
)
|
|
518
576
|
)
|
|
519
577
|
db_session.add(hub_record)
|
|
520
578
|
db_session.commit()
|
|
521
579
|
else:
|
|
522
|
-
logger.info("Not adding default
|
|
580
|
+
logger.info("Not adding default hub source, per configuration")
|
|
523
581
|
return
|
|
524
582
|
|
|
525
583
|
|