mlrun 1.3.3__py3-none-any.whl → 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mlrun might be problematic. Click here for more details.
- mlrun/__init__.py +3 -3
- mlrun/__main__.py +79 -37
- mlrun/api/__init__.py +1 -1
- mlrun/api/api/__init__.py +1 -1
- mlrun/api/api/api.py +4 -4
- mlrun/api/api/deps.py +10 -21
- mlrun/api/api/endpoints/__init__.py +1 -1
- mlrun/api/api/endpoints/artifacts.py +64 -36
- mlrun/api/api/endpoints/auth.py +4 -4
- mlrun/api/api/endpoints/background_tasks.py +11 -11
- mlrun/api/api/endpoints/client_spec.py +5 -5
- mlrun/api/api/endpoints/clusterization_spec.py +6 -4
- mlrun/api/api/endpoints/feature_store.py +124 -115
- mlrun/api/api/endpoints/files.py +22 -14
- mlrun/api/api/endpoints/frontend_spec.py +28 -21
- mlrun/api/api/endpoints/functions.py +142 -87
- mlrun/api/api/endpoints/grafana_proxy.py +89 -442
- mlrun/api/api/endpoints/healthz.py +20 -7
- mlrun/api/api/endpoints/hub.py +320 -0
- mlrun/api/api/endpoints/internal/__init__.py +1 -1
- mlrun/api/api/endpoints/internal/config.py +1 -1
- mlrun/api/api/endpoints/internal/memory_reports.py +9 -9
- mlrun/api/api/endpoints/logs.py +11 -11
- mlrun/api/api/endpoints/model_endpoints.py +74 -70
- mlrun/api/api/endpoints/operations.py +13 -9
- mlrun/api/api/endpoints/pipelines.py +93 -88
- mlrun/api/api/endpoints/projects.py +35 -35
- mlrun/api/api/endpoints/runs.py +69 -27
- mlrun/api/api/endpoints/runtime_resources.py +28 -28
- mlrun/api/api/endpoints/schedules.py +98 -41
- mlrun/api/api/endpoints/secrets.py +37 -32
- mlrun/api/api/endpoints/submit.py +12 -12
- mlrun/api/api/endpoints/tags.py +20 -22
- mlrun/api/api/utils.py +251 -42
- mlrun/api/constants.py +1 -1
- mlrun/api/crud/__init__.py +18 -15
- mlrun/api/crud/artifacts.py +10 -10
- mlrun/api/crud/client_spec.py +4 -4
- mlrun/api/crud/clusterization_spec.py +3 -3
- mlrun/api/crud/feature_store.py +54 -46
- mlrun/api/crud/functions.py +3 -3
- mlrun/api/crud/hub.py +312 -0
- mlrun/api/crud/logs.py +11 -9
- mlrun/api/crud/model_monitoring/__init__.py +3 -3
- mlrun/api/crud/model_monitoring/grafana.py +435 -0
- mlrun/api/crud/model_monitoring/model_endpoints.py +352 -129
- mlrun/api/crud/notifications.py +149 -0
- mlrun/api/crud/pipelines.py +67 -52
- mlrun/api/crud/projects.py +51 -23
- mlrun/api/crud/runs.py +7 -5
- mlrun/api/crud/runtime_resources.py +13 -13
- mlrun/api/{db/filedb → crud/runtimes}/__init__.py +1 -1
- mlrun/api/crud/runtimes/nuclio/__init__.py +14 -0
- mlrun/api/crud/runtimes/nuclio/function.py +505 -0
- mlrun/api/crud/runtimes/nuclio/helpers.py +310 -0
- mlrun/api/crud/secrets.py +88 -46
- mlrun/api/crud/tags.py +5 -5
- mlrun/api/db/__init__.py +1 -1
- mlrun/api/db/base.py +102 -54
- mlrun/api/db/init_db.py +2 -3
- mlrun/api/db/session.py +4 -12
- mlrun/api/db/sqldb/__init__.py +1 -1
- mlrun/api/db/sqldb/db.py +439 -196
- mlrun/api/db/sqldb/helpers.py +1 -1
- mlrun/api/db/sqldb/models/__init__.py +3 -3
- mlrun/api/db/sqldb/models/models_mysql.py +82 -64
- mlrun/api/db/sqldb/models/models_sqlite.py +76 -64
- mlrun/api/db/sqldb/session.py +27 -20
- mlrun/api/initial_data.py +82 -24
- mlrun/api/launcher.py +196 -0
- mlrun/api/main.py +91 -22
- mlrun/api/middlewares.py +6 -5
- mlrun/api/migrations_mysql/env.py +1 -1
- mlrun/api/migrations_mysql/versions/28383af526f3_market_place_to_hub.py +40 -0
- mlrun/api/migrations_mysql/versions/32bae1b0e29c_increase_timestamp_fields_precision.py +1 -1
- mlrun/api/migrations_mysql/versions/4903aef6a91d_tag_foreign_key_and_cascades.py +1 -1
- mlrun/api/migrations_mysql/versions/5f1351c88a19_adding_background_tasks_table.py +1 -1
- mlrun/api/migrations_mysql/versions/88e656800d6a_add_requested_logs_column_and_index_to_.py +1 -1
- mlrun/api/migrations_mysql/versions/9d16de5f03a7_adding_data_versions_table.py +1 -1
- mlrun/api/migrations_mysql/versions/b86f5b53f3d7_adding_name_and_updated_to_runs_table.py +1 -1
- mlrun/api/migrations_mysql/versions/c4af40b0bf61_init.py +1 -1
- mlrun/api/migrations_mysql/versions/c905d15bd91d_notifications.py +72 -0
- mlrun/api/migrations_mysql/versions/ee041e8fdaa0_adding_next_run_time_column_to_schedule_.py +1 -1
- mlrun/api/migrations_sqlite/env.py +1 -1
- mlrun/api/migrations_sqlite/versions/11f8dd2dc9fe_init.py +1 -1
- mlrun/api/migrations_sqlite/versions/1c954f8cb32d_schedule_last_run_uri.py +1 -1
- mlrun/api/migrations_sqlite/versions/2b6d23c715aa_adding_feature_sets.py +1 -1
- mlrun/api/migrations_sqlite/versions/4acd9430b093_market_place_to_hub.py +77 -0
- mlrun/api/migrations_sqlite/versions/6401142f2d7c_adding_next_run_time_column_to_schedule_.py +1 -1
- mlrun/api/migrations_sqlite/versions/64d90a1a69bc_adding_background_tasks_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/803438ecd005_add_requested_logs_column_to_runs.py +1 -1
- mlrun/api/migrations_sqlite/versions/863114f0c659_refactoring_feature_set.py +1 -1
- mlrun/api/migrations_sqlite/versions/959ae00528ad_notifications.py +63 -0
- mlrun/api/migrations_sqlite/versions/accf9fc83d38_adding_data_versions_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/b68e8e897a28_schedule_labels.py +1 -1
- mlrun/api/migrations_sqlite/versions/bcd0c1f9720c_adding_project_labels.py +1 -1
- mlrun/api/migrations_sqlite/versions/cf21882f938e_schedule_id.py +1 -1
- mlrun/api/migrations_sqlite/versions/d781f58f607f_tag_object_name_string.py +1 -1
- mlrun/api/migrations_sqlite/versions/deac06871ace_adding_marketplace_sources_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/e1dd5983c06b_schedule_concurrency_limit.py +1 -1
- mlrun/api/migrations_sqlite/versions/e5594ed3ab53_adding_name_and_updated_to_runs_table.py +1 -1
- mlrun/api/migrations_sqlite/versions/f4249b4ba6fa_adding_feature_vectors.py +1 -1
- mlrun/api/migrations_sqlite/versions/f7b5a1a03629_adding_feature_labels.py +1 -1
- mlrun/api/schemas/__init__.py +216 -138
- mlrun/api/utils/__init__.py +1 -1
- mlrun/api/utils/asyncio.py +1 -1
- mlrun/api/utils/auth/__init__.py +1 -1
- mlrun/api/utils/auth/providers/__init__.py +1 -1
- mlrun/api/utils/auth/providers/base.py +7 -7
- mlrun/api/utils/auth/providers/nop.py +6 -7
- mlrun/api/utils/auth/providers/opa.py +17 -17
- mlrun/api/utils/auth/verifier.py +36 -34
- mlrun/api/utils/background_tasks.py +24 -24
- mlrun/{builder.py → api/utils/builder.py} +216 -123
- mlrun/api/utils/clients/__init__.py +1 -1
- mlrun/api/utils/clients/chief.py +19 -4
- mlrun/api/utils/clients/iguazio.py +106 -60
- mlrun/api/utils/clients/log_collector.py +1 -1
- mlrun/api/utils/clients/nuclio.py +23 -23
- mlrun/api/utils/clients/protocols/grpc.py +2 -2
- mlrun/api/utils/db/__init__.py +1 -1
- mlrun/api/utils/db/alembic.py +1 -1
- mlrun/api/utils/db/backup.py +1 -1
- mlrun/api/utils/db/mysql.py +24 -25
- mlrun/api/utils/db/sql_collation.py +1 -1
- mlrun/api/utils/db/sqlite_migration.py +2 -2
- mlrun/api/utils/events/__init__.py +14 -0
- mlrun/api/utils/events/base.py +57 -0
- mlrun/api/utils/events/events_factory.py +41 -0
- mlrun/api/utils/events/iguazio.py +217 -0
- mlrun/api/utils/events/nop.py +55 -0
- mlrun/api/utils/helpers.py +16 -13
- mlrun/api/utils/memory_reports.py +1 -1
- mlrun/api/utils/periodic.py +6 -3
- mlrun/api/utils/projects/__init__.py +1 -1
- mlrun/api/utils/projects/follower.py +33 -33
- mlrun/api/utils/projects/leader.py +36 -34
- mlrun/api/utils/projects/member.py +27 -27
- mlrun/api/utils/projects/remotes/__init__.py +1 -1
- mlrun/api/utils/projects/remotes/follower.py +13 -13
- mlrun/api/utils/projects/remotes/leader.py +10 -10
- mlrun/api/utils/projects/remotes/nop_follower.py +27 -21
- mlrun/api/utils/projects/remotes/nop_leader.py +17 -16
- mlrun/api/utils/scheduler.py +140 -51
- mlrun/api/utils/singletons/__init__.py +1 -1
- mlrun/api/utils/singletons/db.py +9 -15
- mlrun/api/utils/singletons/k8s.py +677 -5
- mlrun/api/utils/singletons/logs_dir.py +1 -1
- mlrun/api/utils/singletons/project_member.py +1 -1
- mlrun/api/utils/singletons/scheduler.py +1 -1
- mlrun/artifacts/__init__.py +2 -2
- mlrun/artifacts/base.py +8 -2
- mlrun/artifacts/dataset.py +5 -3
- mlrun/artifacts/manager.py +7 -1
- mlrun/artifacts/model.py +15 -4
- mlrun/artifacts/plots.py +1 -1
- mlrun/common/__init__.py +1 -1
- mlrun/common/constants.py +15 -0
- mlrun/common/model_monitoring.py +209 -0
- mlrun/common/schemas/__init__.py +167 -0
- mlrun/{api → common}/schemas/artifact.py +13 -14
- mlrun/{api → common}/schemas/auth.py +10 -8
- mlrun/{api → common}/schemas/background_task.py +3 -3
- mlrun/{api → common}/schemas/client_spec.py +1 -1
- mlrun/{api → common}/schemas/clusterization_spec.py +3 -3
- mlrun/{api → common}/schemas/constants.py +21 -8
- mlrun/common/schemas/events.py +36 -0
- mlrun/{api → common}/schemas/feature_store.py +2 -1
- mlrun/{api → common}/schemas/frontend_spec.py +7 -6
- mlrun/{api → common}/schemas/function.py +5 -5
- mlrun/{api → common}/schemas/http.py +3 -3
- mlrun/common/schemas/hub.py +134 -0
- mlrun/{api → common}/schemas/k8s.py +3 -3
- mlrun/{api → common}/schemas/memory_reports.py +1 -1
- mlrun/common/schemas/model_endpoints.py +342 -0
- mlrun/common/schemas/notification.py +57 -0
- mlrun/{api → common}/schemas/object.py +6 -6
- mlrun/{api → common}/schemas/pipeline.py +3 -3
- mlrun/{api → common}/schemas/project.py +6 -5
- mlrun/common/schemas/regex.py +24 -0
- mlrun/common/schemas/runs.py +30 -0
- mlrun/{api → common}/schemas/runtime_resource.py +3 -3
- mlrun/{api → common}/schemas/schedule.py +19 -7
- mlrun/{api → common}/schemas/secret.py +3 -3
- mlrun/{api → common}/schemas/tag.py +2 -2
- mlrun/common/types.py +25 -0
- mlrun/config.py +152 -20
- mlrun/data_types/__init__.py +7 -2
- mlrun/data_types/data_types.py +4 -2
- mlrun/data_types/infer.py +1 -1
- mlrun/data_types/spark.py +10 -3
- mlrun/datastore/__init__.py +10 -3
- mlrun/datastore/azure_blob.py +1 -1
- mlrun/datastore/base.py +185 -53
- mlrun/datastore/datastore.py +1 -1
- mlrun/datastore/filestore.py +1 -1
- mlrun/datastore/google_cloud_storage.py +1 -1
- mlrun/datastore/inmem.py +4 -1
- mlrun/datastore/redis.py +1 -1
- mlrun/datastore/s3.py +1 -1
- mlrun/datastore/sources.py +192 -70
- mlrun/datastore/spark_udf.py +44 -0
- mlrun/datastore/store_resources.py +4 -4
- mlrun/datastore/targets.py +115 -45
- mlrun/datastore/utils.py +127 -5
- mlrun/datastore/v3io.py +1 -1
- mlrun/datastore/wasbfs/__init__.py +1 -1
- mlrun/datastore/wasbfs/fs.py +1 -1
- mlrun/db/__init__.py +7 -5
- mlrun/db/base.py +112 -68
- mlrun/db/httpdb.py +445 -277
- mlrun/db/nopdb.py +491 -0
- mlrun/db/sqldb.py +112 -65
- mlrun/errors.py +6 -1
- mlrun/execution.py +44 -22
- mlrun/feature_store/__init__.py +1 -1
- mlrun/feature_store/api.py +143 -95
- mlrun/feature_store/common.py +16 -20
- mlrun/feature_store/feature_set.py +42 -12
- mlrun/feature_store/feature_vector.py +32 -21
- mlrun/feature_store/ingestion.py +9 -12
- mlrun/feature_store/retrieval/__init__.py +3 -2
- mlrun/feature_store/retrieval/base.py +388 -66
- mlrun/feature_store/retrieval/dask_merger.py +63 -151
- mlrun/feature_store/retrieval/job.py +30 -12
- mlrun/feature_store/retrieval/local_merger.py +40 -133
- mlrun/feature_store/retrieval/spark_merger.py +129 -127
- mlrun/feature_store/retrieval/storey_merger.py +173 -0
- mlrun/feature_store/steps.py +132 -15
- mlrun/features.py +8 -3
- mlrun/frameworks/__init__.py +1 -1
- mlrun/frameworks/_common/__init__.py +1 -1
- mlrun/frameworks/_common/artifacts_library.py +1 -1
- mlrun/frameworks/_common/mlrun_interface.py +1 -1
- mlrun/frameworks/_common/model_handler.py +1 -1
- mlrun/frameworks/_common/plan.py +1 -1
- mlrun/frameworks/_common/producer.py +1 -1
- mlrun/frameworks/_common/utils.py +1 -1
- mlrun/frameworks/_dl_common/__init__.py +1 -1
- mlrun/frameworks/_dl_common/loggers/__init__.py +1 -1
- mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
- mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +1 -1
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +1 -1
- mlrun/frameworks/_dl_common/model_handler.py +1 -1
- mlrun/frameworks/_dl_common/utils.py +1 -1
- mlrun/frameworks/_ml_common/__init__.py +1 -1
- mlrun/frameworks/_ml_common/artifacts_library.py +1 -1
- mlrun/frameworks/_ml_common/loggers/__init__.py +1 -1
- mlrun/frameworks/_ml_common/loggers/logger.py +1 -1
- mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
- mlrun/frameworks/_ml_common/model_handler.py +1 -1
- mlrun/frameworks/_ml_common/pkl_model_server.py +13 -1
- mlrun/frameworks/_ml_common/plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/__init__.py +1 -1
- mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +1 -6
- mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/dataset_plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +1 -1
- mlrun/frameworks/_ml_common/producer.py +1 -1
- mlrun/frameworks/_ml_common/utils.py +1 -1
- mlrun/frameworks/auto_mlrun/__init__.py +1 -1
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +1 -1
- mlrun/frameworks/huggingface/__init__.py +1 -1
- mlrun/frameworks/huggingface/model_server.py +1 -1
- mlrun/frameworks/lgbm/__init__.py +1 -1
- mlrun/frameworks/lgbm/callbacks/__init__.py +1 -1
- mlrun/frameworks/lgbm/callbacks/callback.py +1 -1
- mlrun/frameworks/lgbm/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +1 -1
- mlrun/frameworks/lgbm/mlrun_interfaces/model_mlrun_interface.py +1 -1
- mlrun/frameworks/lgbm/model_handler.py +1 -1
- mlrun/frameworks/lgbm/model_server.py +1 -1
- mlrun/frameworks/lgbm/utils.py +1 -1
- mlrun/frameworks/onnx/__init__.py +1 -1
- mlrun/frameworks/onnx/dataset.py +1 -1
- mlrun/frameworks/onnx/mlrun_interface.py +1 -1
- mlrun/frameworks/onnx/model_handler.py +1 -1
- mlrun/frameworks/onnx/model_server.py +1 -1
- mlrun/frameworks/parallel_coordinates.py +1 -1
- mlrun/frameworks/pytorch/__init__.py +1 -1
- mlrun/frameworks/pytorch/callbacks/__init__.py +1 -1
- mlrun/frameworks/pytorch/callbacks/callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +1 -1
- mlrun/frameworks/pytorch/callbacks_handler.py +1 -1
- mlrun/frameworks/pytorch/mlrun_interface.py +1 -1
- mlrun/frameworks/pytorch/model_handler.py +1 -1
- mlrun/frameworks/pytorch/model_server.py +1 -1
- mlrun/frameworks/pytorch/utils.py +1 -1
- mlrun/frameworks/sklearn/__init__.py +1 -1
- mlrun/frameworks/sklearn/estimator.py +1 -1
- mlrun/frameworks/sklearn/metric.py +1 -1
- mlrun/frameworks/sklearn/metrics_library.py +1 -1
- mlrun/frameworks/sklearn/mlrun_interface.py +1 -1
- mlrun/frameworks/sklearn/model_handler.py +1 -1
- mlrun/frameworks/sklearn/utils.py +1 -1
- mlrun/frameworks/tf_keras/__init__.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/mlrun_interface.py +1 -1
- mlrun/frameworks/tf_keras/model_handler.py +1 -1
- mlrun/frameworks/tf_keras/model_server.py +1 -1
- mlrun/frameworks/tf_keras/utils.py +1 -1
- mlrun/frameworks/xgboost/__init__.py +1 -1
- mlrun/frameworks/xgboost/mlrun_interface.py +1 -1
- mlrun/frameworks/xgboost/model_handler.py +1 -1
- mlrun/frameworks/xgboost/utils.py +1 -1
- mlrun/k8s_utils.py +14 -765
- mlrun/kfpops.py +14 -17
- mlrun/launcher/__init__.py +13 -0
- mlrun/launcher/base.py +406 -0
- mlrun/launcher/client.py +159 -0
- mlrun/launcher/factory.py +50 -0
- mlrun/launcher/local.py +276 -0
- mlrun/launcher/remote.py +178 -0
- mlrun/lists.py +10 -2
- mlrun/mlutils/__init__.py +1 -1
- mlrun/mlutils/data.py +1 -1
- mlrun/mlutils/models.py +1 -1
- mlrun/mlutils/plots.py +1 -1
- mlrun/model.py +252 -14
- mlrun/model_monitoring/__init__.py +41 -0
- mlrun/model_monitoring/features_drift_table.py +1 -1
- mlrun/model_monitoring/helpers.py +123 -38
- mlrun/model_monitoring/model_endpoint.py +144 -0
- mlrun/model_monitoring/model_monitoring_batch.py +310 -259
- mlrun/model_monitoring/stores/__init__.py +106 -0
- mlrun/model_monitoring/stores/kv_model_endpoint_store.py +448 -0
- mlrun/model_monitoring/stores/model_endpoint_store.py +147 -0
- mlrun/model_monitoring/stores/models/__init__.py +23 -0
- mlrun/model_monitoring/stores/models/base.py +18 -0
- mlrun/model_monitoring/stores/models/mysql.py +100 -0
- mlrun/model_monitoring/stores/models/sqlite.py +98 -0
- mlrun/model_monitoring/stores/sql_model_endpoint_store.py +370 -0
- mlrun/model_monitoring/stream_processing_fs.py +239 -271
- mlrun/package/__init__.py +163 -0
- mlrun/package/context_handler.py +325 -0
- mlrun/package/errors.py +47 -0
- mlrun/package/packager.py +298 -0
- mlrun/{runtimes/package → package/packagers}/__init__.py +3 -1
- mlrun/package/packagers/default_packager.py +422 -0
- mlrun/package/packagers/numpy_packagers.py +612 -0
- mlrun/package/packagers/pandas_packagers.py +968 -0
- mlrun/package/packagers/python_standard_library_packagers.py +616 -0
- mlrun/package/packagers_manager.py +786 -0
- mlrun/package/utils/__init__.py +53 -0
- mlrun/package/utils/_archiver.py +226 -0
- mlrun/package/utils/_formatter.py +211 -0
- mlrun/package/utils/_pickler.py +234 -0
- mlrun/package/utils/_supported_format.py +71 -0
- mlrun/package/utils/log_hint_utils.py +93 -0
- mlrun/package/utils/type_hint_utils.py +298 -0
- mlrun/platforms/__init__.py +1 -1
- mlrun/platforms/iguazio.py +34 -2
- mlrun/platforms/other.py +1 -1
- mlrun/projects/__init__.py +1 -1
- mlrun/projects/operations.py +14 -9
- mlrun/projects/pipelines.py +31 -13
- mlrun/projects/project.py +762 -238
- mlrun/render.py +49 -19
- mlrun/run.py +57 -326
- mlrun/runtimes/__init__.py +3 -9
- mlrun/runtimes/base.py +247 -784
- mlrun/runtimes/constants.py +1 -1
- mlrun/runtimes/daskjob.py +45 -41
- mlrun/runtimes/funcdoc.py +43 -7
- mlrun/runtimes/function.py +66 -656
- mlrun/runtimes/function_reference.py +1 -1
- mlrun/runtimes/generators.py +1 -1
- mlrun/runtimes/kubejob.py +99 -116
- mlrun/runtimes/local.py +59 -66
- mlrun/runtimes/mpijob/__init__.py +1 -1
- mlrun/runtimes/mpijob/abstract.py +13 -15
- mlrun/runtimes/mpijob/v1.py +3 -1
- mlrun/runtimes/mpijob/v1alpha1.py +1 -1
- mlrun/runtimes/nuclio.py +1 -1
- mlrun/runtimes/pod.py +51 -26
- mlrun/runtimes/remotesparkjob.py +3 -1
- mlrun/runtimes/serving.py +12 -4
- mlrun/runtimes/sparkjob/__init__.py +1 -2
- mlrun/runtimes/sparkjob/abstract.py +44 -31
- mlrun/runtimes/sparkjob/spark3job.py +11 -9
- mlrun/runtimes/utils.py +61 -42
- mlrun/secrets.py +16 -18
- mlrun/serving/__init__.py +3 -2
- mlrun/serving/merger.py +1 -1
- mlrun/serving/remote.py +1 -1
- mlrun/serving/routers.py +39 -42
- mlrun/serving/server.py +23 -13
- mlrun/serving/serving_wrapper.py +1 -1
- mlrun/serving/states.py +172 -39
- mlrun/serving/utils.py +1 -1
- mlrun/serving/v1_serving.py +1 -1
- mlrun/serving/v2_serving.py +29 -21
- mlrun/utils/__init__.py +1 -2
- mlrun/utils/async_http.py +8 -1
- mlrun/utils/azure_vault.py +1 -1
- mlrun/utils/clones.py +2 -2
- mlrun/utils/condition_evaluator.py +65 -0
- mlrun/utils/db.py +52 -0
- mlrun/utils/helpers.py +188 -13
- mlrun/utils/http.py +89 -54
- mlrun/utils/logger.py +48 -8
- mlrun/utils/model_monitoring.py +132 -100
- mlrun/utils/notifications/__init__.py +1 -1
- mlrun/utils/notifications/notification/__init__.py +8 -6
- mlrun/utils/notifications/notification/base.py +20 -14
- mlrun/utils/notifications/notification/console.py +7 -4
- mlrun/utils/notifications/notification/git.py +36 -19
- mlrun/utils/notifications/notification/ipython.py +10 -8
- mlrun/utils/notifications/notification/slack.py +18 -13
- mlrun/utils/notifications/notification_pusher.py +377 -56
- mlrun/utils/regex.py +6 -1
- mlrun/utils/singleton.py +1 -1
- mlrun/utils/v3io_clients.py +1 -1
- mlrun/utils/vault.py +270 -269
- mlrun/utils/version/__init__.py +1 -1
- mlrun/utils/version/version.json +2 -2
- mlrun/utils/version/version.py +1 -1
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/METADATA +16 -10
- mlrun-1.4.0.dist-info/RECORD +434 -0
- mlrun/api/api/endpoints/marketplace.py +0 -257
- mlrun/api/crud/marketplace.py +0 -221
- mlrun/api/crud/model_monitoring/model_endpoint_store.py +0 -847
- mlrun/api/db/filedb/db.py +0 -518
- mlrun/api/schemas/marketplace.py +0 -128
- mlrun/api/schemas/model_endpoints.py +0 -185
- mlrun/db/filedb.py +0 -891
- mlrun/feature_store/retrieval/online.py +0 -92
- mlrun/model_monitoring/constants.py +0 -67
- mlrun/runtimes/package/context_handler.py +0 -711
- mlrun/runtimes/sparkjob/spark2job.py +0 -59
- mlrun-1.3.3.dist-info/RECORD +0 -381
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
- {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
mlrun/runtimes/function.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,8 @@ import asyncio
|
|
|
16
16
|
import json
|
|
17
17
|
import typing
|
|
18
18
|
import warnings
|
|
19
|
-
from base64 import b64encode
|
|
20
19
|
from datetime import datetime
|
|
21
20
|
from time import sleep
|
|
22
|
-
from urllib.parse import urlparse
|
|
23
21
|
|
|
24
22
|
import nuclio
|
|
25
23
|
import nuclio.utils
|
|
@@ -31,15 +29,13 @@ from nuclio.deploy import find_dashboard_url, get_deploy_status
|
|
|
31
29
|
from nuclio.triggers import V3IOStreamTrigger
|
|
32
30
|
|
|
33
31
|
import mlrun.errors
|
|
32
|
+
import mlrun.k8s_utils
|
|
34
33
|
import mlrun.utils
|
|
35
|
-
from mlrun.
|
|
34
|
+
from mlrun.common.schemas import AuthInfo
|
|
36
35
|
from mlrun.db import RunDBError
|
|
37
36
|
|
|
38
|
-
from ..api.schemas import AuthInfo
|
|
39
37
|
from ..config import config as mlconf
|
|
40
|
-
from ..config import is_running_as_api
|
|
41
38
|
from ..errors import err_to_str
|
|
42
|
-
from ..k8s_utils import get_k8s_helper
|
|
43
39
|
from ..kfpops import deploy_op
|
|
44
40
|
from ..lists import RunList
|
|
45
41
|
from ..model import RunObject
|
|
@@ -50,9 +46,8 @@ from ..platforms.iguazio import (
|
|
|
50
46
|
split_path,
|
|
51
47
|
v3io_cred,
|
|
52
48
|
)
|
|
53
|
-
from ..utils import
|
|
49
|
+
from ..utils import get_in, logger, update_in
|
|
54
50
|
from .base import FunctionStatus, RunError
|
|
55
|
-
from .constants import NuclioIngressAddTemplatedIngressModes
|
|
56
51
|
from .pod import KubeResource, KubeResourceSpec
|
|
57
52
|
from .utils import get_item_name, log_std
|
|
58
53
|
|
|
@@ -138,9 +133,12 @@ class NuclioSpec(KubeResourceSpec):
|
|
|
138
133
|
"source",
|
|
139
134
|
"function_kind",
|
|
140
135
|
"readiness_timeout",
|
|
136
|
+
"readiness_timeout_before_failure",
|
|
141
137
|
"function_handler",
|
|
142
138
|
"nuclio_runtime",
|
|
143
139
|
"base_image_pull",
|
|
140
|
+
"service_type",
|
|
141
|
+
"add_templated_ingress_host_mode",
|
|
144
142
|
]
|
|
145
143
|
|
|
146
144
|
def __init__(
|
|
@@ -167,6 +165,7 @@ class NuclioSpec(KubeResourceSpec):
|
|
|
167
165
|
build=None,
|
|
168
166
|
service_account=None,
|
|
169
167
|
readiness_timeout=None,
|
|
168
|
+
readiness_timeout_before_failure=None,
|
|
170
169
|
default_handler=None,
|
|
171
170
|
node_name=None,
|
|
172
171
|
node_selector=None,
|
|
@@ -179,6 +178,9 @@ class NuclioSpec(KubeResourceSpec):
|
|
|
179
178
|
tolerations=None,
|
|
180
179
|
preemption_mode=None,
|
|
181
180
|
security_context=None,
|
|
181
|
+
service_type=None,
|
|
182
|
+
add_templated_ingress_host_mode=None,
|
|
183
|
+
clone_target_dir=None,
|
|
182
184
|
):
|
|
183
185
|
|
|
184
186
|
super().__init__(
|
|
@@ -208,6 +210,7 @@ class NuclioSpec(KubeResourceSpec):
|
|
|
208
210
|
tolerations=tolerations,
|
|
209
211
|
preemption_mode=preemption_mode,
|
|
210
212
|
security_context=security_context,
|
|
213
|
+
clone_target_dir=clone_target_dir,
|
|
211
214
|
)
|
|
212
215
|
|
|
213
216
|
self.base_spec = base_spec or {}
|
|
@@ -218,6 +221,9 @@ class NuclioSpec(KubeResourceSpec):
|
|
|
218
221
|
self.nuclio_runtime = None
|
|
219
222
|
self.no_cache = no_cache
|
|
220
223
|
self.readiness_timeout = readiness_timeout
|
|
224
|
+
self.readiness_timeout_before_failure = readiness_timeout_before_failure
|
|
225
|
+
self.service_type = service_type
|
|
226
|
+
self.add_templated_ingress_host_mode = add_templated_ingress_host_mode
|
|
221
227
|
|
|
222
228
|
self.min_replicas = min_replicas or 1
|
|
223
229
|
self.max_replicas = max_replicas or 4
|
|
@@ -560,66 +566,39 @@ class RemoteRuntime(KubeResource):
|
|
|
560
566
|
if tag:
|
|
561
567
|
self.metadata.tag = tag
|
|
562
568
|
|
|
563
|
-
|
|
564
|
-
if not dashboard:
|
|
565
|
-
# Attempt auto-mounting, before sending to remote build
|
|
566
|
-
self.try_auto_mount_based_on_config()
|
|
567
|
-
self._fill_credentials()
|
|
568
|
-
db = self._get_db()
|
|
569
|
-
logger.info("Starting remote function deploy")
|
|
570
|
-
data = db.remote_builder(self, False, builder_env=builder_env)
|
|
571
|
-
self.status = data["data"].get("status")
|
|
572
|
-
self._update_credentials_from_remote_build(data["data"])
|
|
573
|
-
|
|
574
|
-
# when a function is deployed, we wait for it to be ready by default
|
|
575
|
-
# this also means that the function object will be updated with the function status
|
|
576
|
-
self._wait_for_function_deployment(db, verbose=verbose)
|
|
577
|
-
|
|
578
|
-
# NOTE: on older mlrun versions & nuclio versions, function are exposed via NodePort
|
|
579
|
-
# now, functions can be not exposed (using service type ClusterIP) and hence
|
|
580
|
-
# for BC we first try to populate the external invocation url, and then
|
|
581
|
-
# if not exists, take the internal invocation url
|
|
582
|
-
if self.status.external_invocation_urls:
|
|
583
|
-
self.spec.command = f"http://{self.status.external_invocation_urls[0]}"
|
|
584
|
-
save_record = True
|
|
585
|
-
elif self.status.internal_invocation_urls:
|
|
586
|
-
self.spec.command = f"http://{self.status.internal_invocation_urls[0]}"
|
|
587
|
-
save_record = True
|
|
588
|
-
elif self.status.address:
|
|
589
|
-
self.spec.command = f"http://{self.status.address}"
|
|
590
|
-
save_record = True
|
|
591
|
-
|
|
592
|
-
else:
|
|
593
|
-
|
|
569
|
+
if dashboard:
|
|
594
570
|
warnings.warn(
|
|
595
|
-
"'dashboard' is
|
|
596
|
-
"
|
|
597
|
-
# TODO: Remove in 1.5.0
|
|
598
|
-
FutureWarning,
|
|
571
|
+
"'dashboard' parameter is no longer supported on client side, "
|
|
572
|
+
"it is being configured through the MLRun API.",
|
|
599
573
|
)
|
|
600
574
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
575
|
+
save_record = False
|
|
576
|
+
# Attempt auto-mounting, before sending to remote build
|
|
577
|
+
self.try_auto_mount_based_on_config()
|
|
578
|
+
self._fill_credentials()
|
|
579
|
+
db = self._get_db()
|
|
580
|
+
logger.info("Starting remote function deploy")
|
|
581
|
+
data = db.remote_builder(self, False, builder_env=builder_env)
|
|
582
|
+
self.status = data["data"].get("status")
|
|
583
|
+
self._update_credentials_from_remote_build(data["data"])
|
|
584
|
+
|
|
585
|
+
# when a function is deployed, we wait for it to be ready by default
|
|
586
|
+
# this also means that the function object will be updated with the function status
|
|
587
|
+
self._wait_for_function_deployment(db, verbose=verbose)
|
|
588
|
+
|
|
589
|
+
# NOTE: on older mlrun versions & nuclio versions, function are exposed via NodePort
|
|
590
|
+
# now, functions can be not exposed (using service type ClusterIP) and hence
|
|
591
|
+
# for BC we first try to populate the external invocation url, and then
|
|
592
|
+
# if not exists, take the internal invocation url
|
|
593
|
+
if self.status.external_invocation_urls:
|
|
594
|
+
self.spec.command = f"http://{self.status.external_invocation_urls[0]}"
|
|
595
|
+
save_record = True
|
|
596
|
+
elif self.status.internal_invocation_urls:
|
|
597
|
+
self.spec.command = f"http://{self.status.internal_invocation_urls[0]}"
|
|
598
|
+
save_record = True
|
|
599
|
+
elif self.status.address:
|
|
600
|
+
self.spec.command = f"http://{self.status.address}"
|
|
601
|
+
save_record = True
|
|
623
602
|
|
|
624
603
|
logger.info(
|
|
625
604
|
"successfully deployed function",
|
|
@@ -685,7 +664,7 @@ class RemoteRuntime(KubeResource):
|
|
|
685
664
|
The default preemption mode is configurable in mlrun.mlconf.function_defaults.preemption_mode,
|
|
686
665
|
by default it's set to **prevent**
|
|
687
666
|
|
|
688
|
-
:param mode: allow | constrain | prevent | none defined in :py:class:`~mlrun.
|
|
667
|
+
:param mode: allow | constrain | prevent | none defined in :py:class:`~mlrun.common.schemas.PreemptionModes`
|
|
689
668
|
"""
|
|
690
669
|
super().with_preemption_mode(mode=mode)
|
|
691
670
|
|
|
@@ -694,6 +673,22 @@ class RemoteRuntime(KubeResource):
|
|
|
694
673
|
"""k8s priority class"""
|
|
695
674
|
super().with_priority_class(name)
|
|
696
675
|
|
|
676
|
+
def with_service_type(
|
|
677
|
+
self, service_type: str, add_templated_ingress_host_mode: str = None
|
|
678
|
+
):
|
|
679
|
+
"""
|
|
680
|
+
Enables to control the service type of the pod and the addition of templated ingress host
|
|
681
|
+
|
|
682
|
+
:param service_type: service type (ClusterIP, NodePort), defaults to
|
|
683
|
+
mlrun.mlconf.httpdb.nuclio.service_type
|
|
684
|
+
:param add_templated_ingress_host_mode: add templated ingress host mode (never, always, onClusterIP),
|
|
685
|
+
see mlrun.mlconf.httpdb.nuclio.add_templated_ingress_host_mode
|
|
686
|
+
for the default and more information
|
|
687
|
+
|
|
688
|
+
"""
|
|
689
|
+
self.spec.service_type = service_type
|
|
690
|
+
self.spec.add_templated_ingress_host_mode = add_templated_ingress_host_mode
|
|
691
|
+
|
|
697
692
|
def _get_state(
|
|
698
693
|
self,
|
|
699
694
|
dashboard="",
|
|
@@ -816,13 +811,12 @@ class RemoteRuntime(KubeResource):
|
|
|
816
811
|
# verify auto mount is applied (with the client credentials)
|
|
817
812
|
self.try_auto_mount_based_on_config()
|
|
818
813
|
|
|
819
|
-
# if the function spec contain KFP PipelineParams (futures) pass the full spec to the
|
|
820
|
-
# ContainerOp this way KFP will substitute the params with previous step outputs
|
|
821
|
-
func_has_pipeline_params = self.to_json().find("{{pipelineparam:op") > 0
|
|
822
814
|
if (
|
|
823
815
|
use_function_from_db
|
|
824
816
|
or use_function_from_db is None
|
|
825
|
-
|
|
817
|
+
# if the function contain KFP PipelineParams (futures) pass the full spec to the
|
|
818
|
+
# ContainerOp this way KFP will substitute the params with previous step outputs
|
|
819
|
+
and not self._has_pipeline_param()
|
|
826
820
|
):
|
|
827
821
|
url = self.save(versioned=True, refresh=True)
|
|
828
822
|
else:
|
|
@@ -1058,9 +1052,7 @@ class RemoteRuntime(KubeResource):
|
|
|
1058
1052
|
if (
|
|
1059
1053
|
not force_external_address
|
|
1060
1054
|
and self.status.internal_invocation_urls
|
|
1061
|
-
and
|
|
1062
|
-
silent=True, log=False
|
|
1063
|
-
).is_running_inside_kubernetes_cluster()
|
|
1055
|
+
and mlrun.k8s_utils.is_running_inside_kubernetes_cluster()
|
|
1064
1056
|
):
|
|
1065
1057
|
return f"http://{self.status.internal_invocation_urls[0]}{path}"
|
|
1066
1058
|
|
|
@@ -1179,428 +1171,6 @@ def get_fullname(name, project, tag):
|
|
|
1179
1171
|
return name
|
|
1180
1172
|
|
|
1181
1173
|
|
|
1182
|
-
def deploy_nuclio_function(
|
|
1183
|
-
function: RemoteRuntime,
|
|
1184
|
-
dashboard="",
|
|
1185
|
-
watch=False,
|
|
1186
|
-
auth_info: AuthInfo = None,
|
|
1187
|
-
client_version: str = None,
|
|
1188
|
-
builder_env: dict = None,
|
|
1189
|
-
client_python_version: str = None,
|
|
1190
|
-
):
|
|
1191
|
-
"""Deploys a nuclio function.
|
|
1192
|
-
|
|
1193
|
-
:param function: nuclio function object
|
|
1194
|
-
:param dashboard: DEPRECATED. Keep empty to allow auto-detection by MLRun API.
|
|
1195
|
-
:param watch: wait for function to be ready
|
|
1196
|
-
:param auth_info: service AuthInfo
|
|
1197
|
-
:param client_version: mlrun client version
|
|
1198
|
-
:param builder_env: mlrun builder environment (for config/credentials)
|
|
1199
|
-
:param client_python_version: mlrun client python version
|
|
1200
|
-
"""
|
|
1201
|
-
dashboard = dashboard or mlconf.nuclio_dashboard_url
|
|
1202
|
-
function_name, project_name, function_config = compile_function_config(
|
|
1203
|
-
function,
|
|
1204
|
-
client_version=client_version,
|
|
1205
|
-
client_python_version=client_python_version,
|
|
1206
|
-
builder_env=builder_env or {},
|
|
1207
|
-
auth_info=auth_info,
|
|
1208
|
-
)
|
|
1209
|
-
|
|
1210
|
-
# if mode allows it, enrich function http trigger with an ingress
|
|
1211
|
-
enrich_function_with_ingress(
|
|
1212
|
-
function_config,
|
|
1213
|
-
mlconf.httpdb.nuclio.add_templated_ingress_host_mode,
|
|
1214
|
-
mlconf.httpdb.nuclio.default_service_type,
|
|
1215
|
-
)
|
|
1216
|
-
|
|
1217
|
-
try:
|
|
1218
|
-
return nuclio.deploy.deploy_config(
|
|
1219
|
-
function_config,
|
|
1220
|
-
dashboard_url=dashboard,
|
|
1221
|
-
name=function_name,
|
|
1222
|
-
project=project_name,
|
|
1223
|
-
tag=function.metadata.tag,
|
|
1224
|
-
verbose=function.verbose,
|
|
1225
|
-
create_new=True,
|
|
1226
|
-
watch=watch,
|
|
1227
|
-
return_address_mode=nuclio.deploy.ReturnAddressModes.all,
|
|
1228
|
-
auth_info=auth_info.to_nuclio_auth_info() if auth_info else None,
|
|
1229
|
-
)
|
|
1230
|
-
except nuclio.utils.DeployError as exc:
|
|
1231
|
-
if exc.err:
|
|
1232
|
-
err_message = (
|
|
1233
|
-
f"Failed to deploy nuclio function {project_name}/{function_name}"
|
|
1234
|
-
)
|
|
1235
|
-
|
|
1236
|
-
try:
|
|
1237
|
-
|
|
1238
|
-
# the error might not be jsonable, so we'll try to parse it
|
|
1239
|
-
# and extract the error message
|
|
1240
|
-
json_err = exc.err.response.json()
|
|
1241
|
-
if "error" in json_err:
|
|
1242
|
-
err_message += f" {json_err['error']}"
|
|
1243
|
-
if "errorStackTrace" in json_err:
|
|
1244
|
-
logger.warning(
|
|
1245
|
-
"Failed to deploy nuclio function",
|
|
1246
|
-
nuclio_stacktrace=json_err["errorStackTrace"],
|
|
1247
|
-
)
|
|
1248
|
-
except Exception as parse_exc:
|
|
1249
|
-
logger.warning(
|
|
1250
|
-
"Failed to parse nuclio deploy error",
|
|
1251
|
-
parse_exc=err_to_str(parse_exc),
|
|
1252
|
-
)
|
|
1253
|
-
|
|
1254
|
-
mlrun.errors.raise_for_status(
|
|
1255
|
-
exc.err.response,
|
|
1256
|
-
err_message,
|
|
1257
|
-
)
|
|
1258
|
-
raise
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
def resolve_function_ingresses(function_spec):
|
|
1262
|
-
http_trigger = resolve_function_http_trigger(function_spec)
|
|
1263
|
-
if not http_trigger:
|
|
1264
|
-
return []
|
|
1265
|
-
|
|
1266
|
-
ingresses = []
|
|
1267
|
-
for _, ingress_config in (
|
|
1268
|
-
http_trigger.get("attributes", {}).get("ingresses", {}).items()
|
|
1269
|
-
):
|
|
1270
|
-
ingresses.append(ingress_config)
|
|
1271
|
-
return ingresses
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
def resolve_function_http_trigger(function_spec):
|
|
1275
|
-
for trigger_name, trigger_config in function_spec.get("triggers", {}).items():
|
|
1276
|
-
if trigger_config.get("kind") != "http":
|
|
1277
|
-
continue
|
|
1278
|
-
return trigger_config
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
def _resolve_function_image_pull_secret(function):
|
|
1282
|
-
"""
|
|
1283
|
-
the corresponding attribute for 'build.secret' in nuclio is imagePullSecrets, attached link for reference
|
|
1284
|
-
https://github.com/nuclio/nuclio/blob/e4af2a000dc52ee17337e75181ecb2652b9bf4e5/pkg/processor/build/builder.go#L1073
|
|
1285
|
-
if only one of the secrets is set, use it.
|
|
1286
|
-
if both are set, use the non default one and give precedence to image_pull_secret
|
|
1287
|
-
"""
|
|
1288
|
-
# enrich only on server side
|
|
1289
|
-
if not is_running_as_api():
|
|
1290
|
-
return function.spec.image_pull_secret or function.spec.build.secret
|
|
1291
|
-
|
|
1292
|
-
if function.spec.image_pull_secret is None:
|
|
1293
|
-
function.spec.image_pull_secret = (
|
|
1294
|
-
mlrun.mlconf.function.spec.image_pull_secret.default
|
|
1295
|
-
)
|
|
1296
|
-
elif (
|
|
1297
|
-
function.spec.image_pull_secret
|
|
1298
|
-
!= mlrun.mlconf.function.spec.image_pull_secret.default
|
|
1299
|
-
):
|
|
1300
|
-
return function.spec.image_pull_secret
|
|
1301
|
-
|
|
1302
|
-
if function.spec.build.secret is None:
|
|
1303
|
-
function.spec.build.secret = mlrun.mlconf.httpdb.builder.docker_registry_secret
|
|
1304
|
-
elif (
|
|
1305
|
-
function.spec.build.secret != mlrun.mlconf.httpdb.builder.docker_registry_secret
|
|
1306
|
-
):
|
|
1307
|
-
return function.spec.build.secret
|
|
1308
|
-
|
|
1309
|
-
return function.spec.image_pull_secret or function.spec.build.secret
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
def compile_function_config(
|
|
1313
|
-
function: RemoteRuntime,
|
|
1314
|
-
client_version: str = None,
|
|
1315
|
-
client_python_version: str = None,
|
|
1316
|
-
builder_env=None,
|
|
1317
|
-
auth_info=None,
|
|
1318
|
-
):
|
|
1319
|
-
labels = function.metadata.labels or {}
|
|
1320
|
-
labels.update({"mlrun/class": function.kind})
|
|
1321
|
-
for key, value in labels.items():
|
|
1322
|
-
# Adding escaping to the key to prevent it from being split by dots if it contains any
|
|
1323
|
-
function.set_config(f"metadata.labels.\\{key}\\", value)
|
|
1324
|
-
|
|
1325
|
-
# Add secret configurations to function's pod spec, if secret sources were added.
|
|
1326
|
-
# Needs to be here, since it adds env params, which are handled in the next lines.
|
|
1327
|
-
# This only needs to run if we're running within k8s context. If running in Docker, for example, skip.
|
|
1328
|
-
if get_k8s_helper(silent=True).is_running_inside_kubernetes_cluster():
|
|
1329
|
-
function.add_secrets_config_to_spec()
|
|
1330
|
-
|
|
1331
|
-
env_dict, external_source_env_dict = function._get_nuclio_config_spec_env()
|
|
1332
|
-
|
|
1333
|
-
nuclio_runtime = (
|
|
1334
|
-
function.spec.nuclio_runtime
|
|
1335
|
-
or _resolve_nuclio_runtime_python_image(
|
|
1336
|
-
mlrun_client_version=client_version, python_version=client_python_version
|
|
1337
|
-
)
|
|
1338
|
-
)
|
|
1339
|
-
|
|
1340
|
-
if is_nuclio_version_in_range("0.0.0", "1.6.0") and nuclio_runtime in [
|
|
1341
|
-
"python:3.7",
|
|
1342
|
-
"python:3.8",
|
|
1343
|
-
]:
|
|
1344
|
-
nuclio_runtime_set_from_spec = nuclio_runtime == function.spec.nuclio_runtime
|
|
1345
|
-
if nuclio_runtime_set_from_spec:
|
|
1346
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
1347
|
-
f"Nuclio version does not support the configured runtime: {nuclio_runtime}"
|
|
1348
|
-
)
|
|
1349
|
-
else:
|
|
1350
|
-
# our default is python:3.9, simply set it to python:3.6 to keep supporting envs with old Nuclio
|
|
1351
|
-
nuclio_runtime = "python:3.6"
|
|
1352
|
-
|
|
1353
|
-
# In nuclio 1.6.0<=v<1.8.0, python runtimes default behavior was to not decode event strings
|
|
1354
|
-
# Our code is counting on the strings to be decoded, so add the needed env var for those versions
|
|
1355
|
-
if (
|
|
1356
|
-
is_nuclio_version_in_range("1.6.0", "1.8.0")
|
|
1357
|
-
and "NUCLIO_PYTHON_DECODE_EVENT_STRINGS" not in env_dict
|
|
1358
|
-
):
|
|
1359
|
-
env_dict["NUCLIO_PYTHON_DECODE_EVENT_STRINGS"] = "true"
|
|
1360
|
-
|
|
1361
|
-
nuclio_spec = nuclio.ConfigSpec(
|
|
1362
|
-
env=env_dict,
|
|
1363
|
-
external_source_env=external_source_env_dict,
|
|
1364
|
-
config=function.spec.config,
|
|
1365
|
-
)
|
|
1366
|
-
nuclio_spec.cmd = function.spec.build.commands or []
|
|
1367
|
-
project = function.metadata.project or "default"
|
|
1368
|
-
tag = function.metadata.tag
|
|
1369
|
-
handler = function.spec.function_handler
|
|
1370
|
-
|
|
1371
|
-
if function.spec.build.source:
|
|
1372
|
-
_compile_nuclio_archive_config(
|
|
1373
|
-
nuclio_spec, function, builder_env, project, auth_info=auth_info
|
|
1374
|
-
)
|
|
1375
|
-
|
|
1376
|
-
nuclio_spec.set_config("spec.runtime", nuclio_runtime)
|
|
1377
|
-
|
|
1378
|
-
# In Nuclio >= 1.6.x default serviceType has changed to "ClusterIP".
|
|
1379
|
-
nuclio_spec.set_config(
|
|
1380
|
-
"spec.serviceType", mlconf.httpdb.nuclio.default_service_type
|
|
1381
|
-
)
|
|
1382
|
-
if function.spec.readiness_timeout:
|
|
1383
|
-
nuclio_spec.set_config(
|
|
1384
|
-
"spec.readinessTimeoutSeconds", function.spec.readiness_timeout
|
|
1385
|
-
)
|
|
1386
|
-
if function.spec.resources:
|
|
1387
|
-
nuclio_spec.set_config("spec.resources", function.spec.resources)
|
|
1388
|
-
if function.spec.no_cache:
|
|
1389
|
-
nuclio_spec.set_config("spec.build.noCache", True)
|
|
1390
|
-
if function.spec.build.functionSourceCode:
|
|
1391
|
-
nuclio_spec.set_config(
|
|
1392
|
-
"spec.build.functionSourceCode", function.spec.build.functionSourceCode
|
|
1393
|
-
)
|
|
1394
|
-
|
|
1395
|
-
image_pull_secret = _resolve_function_image_pull_secret(function)
|
|
1396
|
-
if image_pull_secret:
|
|
1397
|
-
nuclio_spec.set_config("spec.imagePullSecrets", image_pull_secret)
|
|
1398
|
-
|
|
1399
|
-
if function.spec.base_image_pull:
|
|
1400
|
-
nuclio_spec.set_config("spec.build.noBaseImagesPull", False)
|
|
1401
|
-
# don't send node selections if nuclio is not compatible
|
|
1402
|
-
if validate_nuclio_version_compatibility("1.5.20", "1.6.10"):
|
|
1403
|
-
if function.spec.node_selector:
|
|
1404
|
-
nuclio_spec.set_config("spec.nodeSelector", function.spec.node_selector)
|
|
1405
|
-
if function.spec.node_name:
|
|
1406
|
-
nuclio_spec.set_config("spec.nodeName", function.spec.node_name)
|
|
1407
|
-
if function.spec.affinity:
|
|
1408
|
-
nuclio_spec.set_config(
|
|
1409
|
-
"spec.affinity",
|
|
1410
|
-
mlrun.runtimes.pod.get_sanitized_attribute(function.spec, "affinity"),
|
|
1411
|
-
)
|
|
1412
|
-
|
|
1413
|
-
# don't send tolerations if nuclio is not compatible
|
|
1414
|
-
if validate_nuclio_version_compatibility("1.7.5"):
|
|
1415
|
-
if function.spec.tolerations:
|
|
1416
|
-
nuclio_spec.set_config(
|
|
1417
|
-
"spec.tolerations",
|
|
1418
|
-
mlrun.runtimes.pod.get_sanitized_attribute(
|
|
1419
|
-
function.spec, "tolerations"
|
|
1420
|
-
),
|
|
1421
|
-
)
|
|
1422
|
-
# don't send preemption_mode if nuclio is not compatible
|
|
1423
|
-
if validate_nuclio_version_compatibility("1.8.6"):
|
|
1424
|
-
if function.spec.preemption_mode:
|
|
1425
|
-
nuclio_spec.set_config(
|
|
1426
|
-
"spec.PreemptionMode",
|
|
1427
|
-
function.spec.preemption_mode,
|
|
1428
|
-
)
|
|
1429
|
-
|
|
1430
|
-
# don't send default or any priority class name if nuclio is not compatible
|
|
1431
|
-
if (
|
|
1432
|
-
function.spec.priority_class_name
|
|
1433
|
-
and validate_nuclio_version_compatibility("1.6.18")
|
|
1434
|
-
and len(mlconf.get_valid_function_priority_class_names())
|
|
1435
|
-
):
|
|
1436
|
-
nuclio_spec.set_config(
|
|
1437
|
-
"spec.priorityClassName", function.spec.priority_class_name
|
|
1438
|
-
)
|
|
1439
|
-
|
|
1440
|
-
if function.spec.replicas:
|
|
1441
|
-
|
|
1442
|
-
nuclio_spec.set_config(
|
|
1443
|
-
"spec.minReplicas", as_number("spec.Replicas", function.spec.replicas)
|
|
1444
|
-
)
|
|
1445
|
-
nuclio_spec.set_config(
|
|
1446
|
-
"spec.maxReplicas", as_number("spec.Replicas", function.spec.replicas)
|
|
1447
|
-
)
|
|
1448
|
-
|
|
1449
|
-
else:
|
|
1450
|
-
nuclio_spec.set_config(
|
|
1451
|
-
"spec.minReplicas",
|
|
1452
|
-
as_number("spec.minReplicas", function.spec.min_replicas),
|
|
1453
|
-
)
|
|
1454
|
-
nuclio_spec.set_config(
|
|
1455
|
-
"spec.maxReplicas",
|
|
1456
|
-
as_number("spec.maxReplicas", function.spec.max_replicas),
|
|
1457
|
-
)
|
|
1458
|
-
|
|
1459
|
-
if function.spec.service_account:
|
|
1460
|
-
nuclio_spec.set_config("spec.serviceAccount", function.spec.service_account)
|
|
1461
|
-
|
|
1462
|
-
if function.spec.security_context:
|
|
1463
|
-
nuclio_spec.set_config(
|
|
1464
|
-
"spec.securityContext",
|
|
1465
|
-
mlrun.runtimes.pod.get_sanitized_attribute(
|
|
1466
|
-
function.spec, "security_context"
|
|
1467
|
-
),
|
|
1468
|
-
)
|
|
1469
|
-
|
|
1470
|
-
if (
|
|
1471
|
-
function.spec.base_spec
|
|
1472
|
-
or function.spec.build.functionSourceCode
|
|
1473
|
-
or function.spec.build.source
|
|
1474
|
-
or function.kind == mlrun.runtimes.RuntimeKinds.serving # serving can be empty
|
|
1475
|
-
):
|
|
1476
|
-
config = function.spec.base_spec
|
|
1477
|
-
if not config:
|
|
1478
|
-
# if base_spec was not set (when not using code_to_function) and we have base64 code
|
|
1479
|
-
# we create the base spec with essential attributes
|
|
1480
|
-
config = nuclio.config.new_config()
|
|
1481
|
-
update_in(config, "spec.handler", handler or "main:handler")
|
|
1482
|
-
|
|
1483
|
-
config = nuclio.config.extend_config(
|
|
1484
|
-
config, nuclio_spec, tag, function.spec.build.code_origin
|
|
1485
|
-
)
|
|
1486
|
-
|
|
1487
|
-
update_in(config, "metadata.name", function.metadata.name)
|
|
1488
|
-
update_in(config, "spec.volumes", function.spec.generate_nuclio_volumes())
|
|
1489
|
-
base_image = (
|
|
1490
|
-
get_in(config, "spec.build.baseImage")
|
|
1491
|
-
or function.spec.image
|
|
1492
|
-
or function.spec.build.base_image
|
|
1493
|
-
)
|
|
1494
|
-
if base_image:
|
|
1495
|
-
update_in(
|
|
1496
|
-
config,
|
|
1497
|
-
"spec.build.baseImage",
|
|
1498
|
-
enrich_image_url(base_image, client_version, client_python_version),
|
|
1499
|
-
)
|
|
1500
|
-
|
|
1501
|
-
logger.info("deploy started")
|
|
1502
|
-
name = get_fullname(function.metadata.name, project, tag)
|
|
1503
|
-
function.status.nuclio_name = name
|
|
1504
|
-
update_in(config, "metadata.name", name)
|
|
1505
|
-
|
|
1506
|
-
if function.kind == mlrun.runtimes.RuntimeKinds.serving and not get_in(
|
|
1507
|
-
config, "spec.build.functionSourceCode"
|
|
1508
|
-
):
|
|
1509
|
-
if not function.spec.build.source:
|
|
1510
|
-
# set the source to the mlrun serving wrapper
|
|
1511
|
-
body = nuclio.build.mlrun_footer.format(
|
|
1512
|
-
mlrun.runtimes.serving.serving_subkind
|
|
1513
|
-
)
|
|
1514
|
-
update_in(
|
|
1515
|
-
config,
|
|
1516
|
-
"spec.build.functionSourceCode",
|
|
1517
|
-
b64encode(body.encode("utf-8")).decode("utf-8"),
|
|
1518
|
-
)
|
|
1519
|
-
elif not function.spec.function_handler:
|
|
1520
|
-
# point the nuclio function handler to mlrun serving wrapper handlers
|
|
1521
|
-
update_in(
|
|
1522
|
-
config,
|
|
1523
|
-
"spec.handler",
|
|
1524
|
-
"mlrun.serving.serving_wrapper:handler",
|
|
1525
|
-
)
|
|
1526
|
-
else:
|
|
1527
|
-
# todo: should be deprecated (only work via MLRun service)
|
|
1528
|
-
# this may also be called in case of using single file code_to_function(embed_code=False)
|
|
1529
|
-
# this option need to be removed or be limited to using remote files (this code runs in server)
|
|
1530
|
-
name, config, code = nuclio.build_file(
|
|
1531
|
-
function.spec.source,
|
|
1532
|
-
name=function.metadata.name,
|
|
1533
|
-
project=project,
|
|
1534
|
-
handler=handler,
|
|
1535
|
-
tag=tag,
|
|
1536
|
-
spec=nuclio_spec,
|
|
1537
|
-
kind=function.spec.function_kind,
|
|
1538
|
-
verbose=function.verbose,
|
|
1539
|
-
)
|
|
1540
|
-
|
|
1541
|
-
update_in(config, "spec.volumes", function.spec.generate_nuclio_volumes())
|
|
1542
|
-
base_image = function.spec.image or function.spec.build.base_image
|
|
1543
|
-
if base_image:
|
|
1544
|
-
update_in(
|
|
1545
|
-
config,
|
|
1546
|
-
"spec.build.baseImage",
|
|
1547
|
-
enrich_image_url(base_image, client_version, client_python_version),
|
|
1548
|
-
)
|
|
1549
|
-
|
|
1550
|
-
name = get_fullname(name, project, tag)
|
|
1551
|
-
function.status.nuclio_name = name
|
|
1552
|
-
|
|
1553
|
-
update_in(config, "metadata.name", name)
|
|
1554
|
-
|
|
1555
|
-
return name, project, config
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
def enrich_function_with_ingress(config, mode, service_type):
|
|
1559
|
-
# do not enrich with an ingress
|
|
1560
|
-
if mode == NuclioIngressAddTemplatedIngressModes.never:
|
|
1561
|
-
return
|
|
1562
|
-
|
|
1563
|
-
ingresses = resolve_function_ingresses(config["spec"])
|
|
1564
|
-
|
|
1565
|
-
# function has ingresses already, nothing to add / enrich
|
|
1566
|
-
if ingresses:
|
|
1567
|
-
return
|
|
1568
|
-
|
|
1569
|
-
# if exists, get the http trigger the function has
|
|
1570
|
-
# we would enrich it with an ingress
|
|
1571
|
-
http_trigger = resolve_function_http_trigger(config["spec"])
|
|
1572
|
-
if not http_trigger:
|
|
1573
|
-
# function has an HTTP trigger without an ingress
|
|
1574
|
-
# TODO: read from nuclio-api frontend-spec
|
|
1575
|
-
http_trigger = {
|
|
1576
|
-
"kind": "http",
|
|
1577
|
-
"name": "http",
|
|
1578
|
-
"maxWorkers": 1,
|
|
1579
|
-
"workerAvailabilityTimeoutMilliseconds": 10000, # 10 seconds
|
|
1580
|
-
"attributes": {},
|
|
1581
|
-
}
|
|
1582
|
-
|
|
1583
|
-
def enrich():
|
|
1584
|
-
http_trigger.setdefault("attributes", {}).setdefault("ingresses", {})["0"] = {
|
|
1585
|
-
"paths": ["/"],
|
|
1586
|
-
# this would tell Nuclio to use its default ingress host template
|
|
1587
|
-
# and would auto assign a host for the ingress
|
|
1588
|
-
"hostTemplate": "@nuclio.fromDefault",
|
|
1589
|
-
}
|
|
1590
|
-
http_trigger["attributes"]["serviceType"] = service_type
|
|
1591
|
-
config["spec"].setdefault("triggers", {})[http_trigger["name"]] = http_trigger
|
|
1592
|
-
|
|
1593
|
-
if mode == NuclioIngressAddTemplatedIngressModes.always:
|
|
1594
|
-
enrich()
|
|
1595
|
-
elif mode == NuclioIngressAddTemplatedIngressModes.on_cluster_ip:
|
|
1596
|
-
|
|
1597
|
-
# service type is not cluster ip, bail out
|
|
1598
|
-
if service_type and service_type.lower() != "clusterip":
|
|
1599
|
-
return
|
|
1600
|
-
|
|
1601
|
-
enrich()
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
1174
|
def get_nuclio_deploy_status(
|
|
1605
1175
|
name,
|
|
1606
1176
|
project,
|
|
@@ -1659,163 +1229,3 @@ def get_nuclio_deploy_status(
|
|
|
1659
1229
|
else:
|
|
1660
1230
|
text = "\n".join(outputs) if outputs else ""
|
|
1661
1231
|
return state, address, name, last_log_timestamp, text, function_status
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
def _compile_nuclio_archive_config(
|
|
1665
|
-
nuclio_spec,
|
|
1666
|
-
function: RemoteRuntime,
|
|
1667
|
-
builder_env,
|
|
1668
|
-
project=None,
|
|
1669
|
-
auth_info=None,
|
|
1670
|
-
):
|
|
1671
|
-
secrets = {}
|
|
1672
|
-
if project and get_k8s_helper(silent=True).is_running_inside_kubernetes_cluster():
|
|
1673
|
-
secrets = get_k8s_helper().get_project_secret_data(project)
|
|
1674
|
-
|
|
1675
|
-
def get_secret(key):
|
|
1676
|
-
return builder_env.get(key) or secrets.get(key, "")
|
|
1677
|
-
|
|
1678
|
-
source = function.spec.build.source
|
|
1679
|
-
parsed_url = urlparse(source)
|
|
1680
|
-
code_entry_type = ""
|
|
1681
|
-
if source.startswith("s3://"):
|
|
1682
|
-
code_entry_type = "s3"
|
|
1683
|
-
if source.startswith("git://"):
|
|
1684
|
-
code_entry_type = "git"
|
|
1685
|
-
for archive_prefix in ["http://", "https://", "v3io://", "v3ios://"]:
|
|
1686
|
-
if source.startswith(archive_prefix):
|
|
1687
|
-
code_entry_type = "archive"
|
|
1688
|
-
|
|
1689
|
-
if code_entry_type == "":
|
|
1690
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
1691
|
-
"Couldn't resolve code entry type from source"
|
|
1692
|
-
)
|
|
1693
|
-
|
|
1694
|
-
code_entry_attributes = {}
|
|
1695
|
-
|
|
1696
|
-
# resolve work_dir and handler
|
|
1697
|
-
work_dir, handler = _resolve_work_dir_and_handler(function.spec.function_handler)
|
|
1698
|
-
work_dir = function.spec.workdir or work_dir
|
|
1699
|
-
if work_dir != "":
|
|
1700
|
-
code_entry_attributes["workDir"] = work_dir
|
|
1701
|
-
|
|
1702
|
-
# archive
|
|
1703
|
-
if code_entry_type == "archive":
|
|
1704
|
-
v3io_access_key = builder_env.get("V3IO_ACCESS_KEY", "")
|
|
1705
|
-
if source.startswith("v3io"):
|
|
1706
|
-
if not parsed_url.netloc:
|
|
1707
|
-
source = mlrun.mlconf.v3io_api + parsed_url.path
|
|
1708
|
-
else:
|
|
1709
|
-
source = f"http{source[len('v3io'):]}"
|
|
1710
|
-
if auth_info and not v3io_access_key:
|
|
1711
|
-
v3io_access_key = auth_info.data_session or auth_info.access_key
|
|
1712
|
-
|
|
1713
|
-
if v3io_access_key:
|
|
1714
|
-
code_entry_attributes["headers"] = {"X-V3io-Session-Key": v3io_access_key}
|
|
1715
|
-
|
|
1716
|
-
# s3
|
|
1717
|
-
if code_entry_type == "s3":
|
|
1718
|
-
bucket, item_key = parse_s3_bucket_and_key(source)
|
|
1719
|
-
|
|
1720
|
-
code_entry_attributes["s3Bucket"] = bucket
|
|
1721
|
-
code_entry_attributes["s3ItemKey"] = item_key
|
|
1722
|
-
|
|
1723
|
-
code_entry_attributes["s3AccessKeyId"] = get_secret("AWS_ACCESS_KEY_ID")
|
|
1724
|
-
code_entry_attributes["s3SecretAccessKey"] = get_secret("AWS_SECRET_ACCESS_KEY")
|
|
1725
|
-
code_entry_attributes["s3SessionToken"] = get_secret("AWS_SESSION_TOKEN")
|
|
1726
|
-
|
|
1727
|
-
# git
|
|
1728
|
-
if code_entry_type == "git":
|
|
1729
|
-
|
|
1730
|
-
# change git:// to https:// as nuclio expects it to be
|
|
1731
|
-
if source.startswith("git://"):
|
|
1732
|
-
source = source.replace("git://", "https://")
|
|
1733
|
-
|
|
1734
|
-
source, reference, branch = mlrun.utils.resolve_git_reference_from_source(
|
|
1735
|
-
source
|
|
1736
|
-
)
|
|
1737
|
-
if not branch and not reference:
|
|
1738
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
1739
|
-
"git branch or refs must be specified in the source e.g.: "
|
|
1740
|
-
"'git://<url>/org/repo.git#<branch-name or refs/heads/..>'"
|
|
1741
|
-
)
|
|
1742
|
-
if reference:
|
|
1743
|
-
code_entry_attributes["reference"] = reference
|
|
1744
|
-
if branch:
|
|
1745
|
-
code_entry_attributes["branch"] = branch
|
|
1746
|
-
|
|
1747
|
-
password = get_secret("GIT_PASSWORD")
|
|
1748
|
-
username = get_secret("GIT_USERNAME")
|
|
1749
|
-
|
|
1750
|
-
token = get_secret("GIT_TOKEN")
|
|
1751
|
-
if token:
|
|
1752
|
-
username, password = mlrun.utils.get_git_username_password_from_token(token)
|
|
1753
|
-
|
|
1754
|
-
code_entry_attributes["username"] = username
|
|
1755
|
-
code_entry_attributes["password"] = password
|
|
1756
|
-
|
|
1757
|
-
# populate spec with relevant fields
|
|
1758
|
-
nuclio_spec.set_config("spec.handler", handler)
|
|
1759
|
-
nuclio_spec.set_config("spec.build.path", source)
|
|
1760
|
-
nuclio_spec.set_config("spec.build.codeEntryType", code_entry_type)
|
|
1761
|
-
nuclio_spec.set_config("spec.build.codeEntryAttributes", code_entry_attributes)
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
def _resolve_work_dir_and_handler(handler):
|
|
1765
|
-
"""
|
|
1766
|
-
Resolves a nuclio function working dir and handler inside an archive/git repo
|
|
1767
|
-
:param handler: a path describing working dir and handler of a nuclio function
|
|
1768
|
-
:return: (working_dir, handler) tuple, as nuclio expects to get it
|
|
1769
|
-
|
|
1770
|
-
Example: ("a/b/c#main:Handler") -> ("a/b/c", "main:Handler")
|
|
1771
|
-
"""
|
|
1772
|
-
|
|
1773
|
-
def extend_handler(base_handler):
|
|
1774
|
-
# return default handler and module if not specified
|
|
1775
|
-
if not base_handler:
|
|
1776
|
-
return "main:handler"
|
|
1777
|
-
if ":" not in base_handler:
|
|
1778
|
-
base_handler = f"{base_handler}:handler"
|
|
1779
|
-
return base_handler
|
|
1780
|
-
|
|
1781
|
-
if not handler:
|
|
1782
|
-
return "", "main:handler"
|
|
1783
|
-
|
|
1784
|
-
split_handler = handler.split("#")
|
|
1785
|
-
if len(split_handler) == 1:
|
|
1786
|
-
return "", extend_handler(handler)
|
|
1787
|
-
|
|
1788
|
-
return split_handler[0], extend_handler(split_handler[1])
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
def _resolve_nuclio_runtime_python_image(
|
|
1792
|
-
mlrun_client_version: str = None, python_version: str = None
|
|
1793
|
-
):
|
|
1794
|
-
# if no python version or mlrun version is passed it means we use mlrun client older than 1.3.0 therefore need
|
|
1795
|
-
# to use the previoud default runtime which is python 3.7
|
|
1796
|
-
if not python_version or not mlrun_client_version:
|
|
1797
|
-
return "python:3.7"
|
|
1798
|
-
|
|
1799
|
-
# If the mlrun version is 0.0.0-<unstable>, it is a dev version,
|
|
1800
|
-
# so we can't check if it is higher than 1.3.0, but if the python version was passed,
|
|
1801
|
-
# it means it is 1.3.0-rc or higher, so use the image according to the python version
|
|
1802
|
-
if mlrun_client_version.startswith("0.0.0-") or "unstable" in mlrun_client_version:
|
|
1803
|
-
if python_version.startswith("3.7"):
|
|
1804
|
-
return "python:3.7"
|
|
1805
|
-
|
|
1806
|
-
return mlrun.mlconf.default_nuclio_runtime
|
|
1807
|
-
|
|
1808
|
-
# if mlrun version is older than 1.3.0 we need to use the previous default runtime which is python 3.7
|
|
1809
|
-
if semver.VersionInfo.parse(mlrun_client_version) < semver.VersionInfo.parse(
|
|
1810
|
-
"1.3.0-X"
|
|
1811
|
-
):
|
|
1812
|
-
return "python:3.7"
|
|
1813
|
-
|
|
1814
|
-
# if mlrun version is 1.3.0 or newer and python version is 3.7 we need to use python 3.7 image
|
|
1815
|
-
if semver.VersionInfo.parse(mlrun_client_version) >= semver.VersionInfo.parse(
|
|
1816
|
-
"1.3.0-X"
|
|
1817
|
-
) and python_version.startswith("3.7"):
|
|
1818
|
-
return "python:3.7"
|
|
1819
|
-
|
|
1820
|
-
# if none of the above conditions are met we use the default runtime which is python 3.9
|
|
1821
|
-
return mlrun.mlconf.default_nuclio_runtime
|