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.

Files changed (444) hide show
  1. mlrun/__init__.py +3 -3
  2. mlrun/__main__.py +79 -37
  3. mlrun/api/__init__.py +1 -1
  4. mlrun/api/api/__init__.py +1 -1
  5. mlrun/api/api/api.py +4 -4
  6. mlrun/api/api/deps.py +10 -21
  7. mlrun/api/api/endpoints/__init__.py +1 -1
  8. mlrun/api/api/endpoints/artifacts.py +64 -36
  9. mlrun/api/api/endpoints/auth.py +4 -4
  10. mlrun/api/api/endpoints/background_tasks.py +11 -11
  11. mlrun/api/api/endpoints/client_spec.py +5 -5
  12. mlrun/api/api/endpoints/clusterization_spec.py +6 -4
  13. mlrun/api/api/endpoints/feature_store.py +124 -115
  14. mlrun/api/api/endpoints/files.py +22 -14
  15. mlrun/api/api/endpoints/frontend_spec.py +28 -21
  16. mlrun/api/api/endpoints/functions.py +142 -87
  17. mlrun/api/api/endpoints/grafana_proxy.py +89 -442
  18. mlrun/api/api/endpoints/healthz.py +20 -7
  19. mlrun/api/api/endpoints/hub.py +320 -0
  20. mlrun/api/api/endpoints/internal/__init__.py +1 -1
  21. mlrun/api/api/endpoints/internal/config.py +1 -1
  22. mlrun/api/api/endpoints/internal/memory_reports.py +9 -9
  23. mlrun/api/api/endpoints/logs.py +11 -11
  24. mlrun/api/api/endpoints/model_endpoints.py +74 -70
  25. mlrun/api/api/endpoints/operations.py +13 -9
  26. mlrun/api/api/endpoints/pipelines.py +93 -88
  27. mlrun/api/api/endpoints/projects.py +35 -35
  28. mlrun/api/api/endpoints/runs.py +69 -27
  29. mlrun/api/api/endpoints/runtime_resources.py +28 -28
  30. mlrun/api/api/endpoints/schedules.py +98 -41
  31. mlrun/api/api/endpoints/secrets.py +37 -32
  32. mlrun/api/api/endpoints/submit.py +12 -12
  33. mlrun/api/api/endpoints/tags.py +20 -22
  34. mlrun/api/api/utils.py +251 -42
  35. mlrun/api/constants.py +1 -1
  36. mlrun/api/crud/__init__.py +18 -15
  37. mlrun/api/crud/artifacts.py +10 -10
  38. mlrun/api/crud/client_spec.py +4 -4
  39. mlrun/api/crud/clusterization_spec.py +3 -3
  40. mlrun/api/crud/feature_store.py +54 -46
  41. mlrun/api/crud/functions.py +3 -3
  42. mlrun/api/crud/hub.py +312 -0
  43. mlrun/api/crud/logs.py +11 -9
  44. mlrun/api/crud/model_monitoring/__init__.py +3 -3
  45. mlrun/api/crud/model_monitoring/grafana.py +435 -0
  46. mlrun/api/crud/model_monitoring/model_endpoints.py +352 -129
  47. mlrun/api/crud/notifications.py +149 -0
  48. mlrun/api/crud/pipelines.py +67 -52
  49. mlrun/api/crud/projects.py +51 -23
  50. mlrun/api/crud/runs.py +7 -5
  51. mlrun/api/crud/runtime_resources.py +13 -13
  52. mlrun/api/{db/filedb → crud/runtimes}/__init__.py +1 -1
  53. mlrun/api/crud/runtimes/nuclio/__init__.py +14 -0
  54. mlrun/api/crud/runtimes/nuclio/function.py +505 -0
  55. mlrun/api/crud/runtimes/nuclio/helpers.py +310 -0
  56. mlrun/api/crud/secrets.py +88 -46
  57. mlrun/api/crud/tags.py +5 -5
  58. mlrun/api/db/__init__.py +1 -1
  59. mlrun/api/db/base.py +102 -54
  60. mlrun/api/db/init_db.py +2 -3
  61. mlrun/api/db/session.py +4 -12
  62. mlrun/api/db/sqldb/__init__.py +1 -1
  63. mlrun/api/db/sqldb/db.py +439 -196
  64. mlrun/api/db/sqldb/helpers.py +1 -1
  65. mlrun/api/db/sqldb/models/__init__.py +3 -3
  66. mlrun/api/db/sqldb/models/models_mysql.py +82 -64
  67. mlrun/api/db/sqldb/models/models_sqlite.py +76 -64
  68. mlrun/api/db/sqldb/session.py +27 -20
  69. mlrun/api/initial_data.py +82 -24
  70. mlrun/api/launcher.py +196 -0
  71. mlrun/api/main.py +91 -22
  72. mlrun/api/middlewares.py +6 -5
  73. mlrun/api/migrations_mysql/env.py +1 -1
  74. mlrun/api/migrations_mysql/versions/28383af526f3_market_place_to_hub.py +40 -0
  75. mlrun/api/migrations_mysql/versions/32bae1b0e29c_increase_timestamp_fields_precision.py +1 -1
  76. mlrun/api/migrations_mysql/versions/4903aef6a91d_tag_foreign_key_and_cascades.py +1 -1
  77. mlrun/api/migrations_mysql/versions/5f1351c88a19_adding_background_tasks_table.py +1 -1
  78. mlrun/api/migrations_mysql/versions/88e656800d6a_add_requested_logs_column_and_index_to_.py +1 -1
  79. mlrun/api/migrations_mysql/versions/9d16de5f03a7_adding_data_versions_table.py +1 -1
  80. mlrun/api/migrations_mysql/versions/b86f5b53f3d7_adding_name_and_updated_to_runs_table.py +1 -1
  81. mlrun/api/migrations_mysql/versions/c4af40b0bf61_init.py +1 -1
  82. mlrun/api/migrations_mysql/versions/c905d15bd91d_notifications.py +72 -0
  83. mlrun/api/migrations_mysql/versions/ee041e8fdaa0_adding_next_run_time_column_to_schedule_.py +1 -1
  84. mlrun/api/migrations_sqlite/env.py +1 -1
  85. mlrun/api/migrations_sqlite/versions/11f8dd2dc9fe_init.py +1 -1
  86. mlrun/api/migrations_sqlite/versions/1c954f8cb32d_schedule_last_run_uri.py +1 -1
  87. mlrun/api/migrations_sqlite/versions/2b6d23c715aa_adding_feature_sets.py +1 -1
  88. mlrun/api/migrations_sqlite/versions/4acd9430b093_market_place_to_hub.py +77 -0
  89. mlrun/api/migrations_sqlite/versions/6401142f2d7c_adding_next_run_time_column_to_schedule_.py +1 -1
  90. mlrun/api/migrations_sqlite/versions/64d90a1a69bc_adding_background_tasks_table.py +1 -1
  91. mlrun/api/migrations_sqlite/versions/803438ecd005_add_requested_logs_column_to_runs.py +1 -1
  92. mlrun/api/migrations_sqlite/versions/863114f0c659_refactoring_feature_set.py +1 -1
  93. mlrun/api/migrations_sqlite/versions/959ae00528ad_notifications.py +63 -0
  94. mlrun/api/migrations_sqlite/versions/accf9fc83d38_adding_data_versions_table.py +1 -1
  95. mlrun/api/migrations_sqlite/versions/b68e8e897a28_schedule_labels.py +1 -1
  96. mlrun/api/migrations_sqlite/versions/bcd0c1f9720c_adding_project_labels.py +1 -1
  97. mlrun/api/migrations_sqlite/versions/cf21882f938e_schedule_id.py +1 -1
  98. mlrun/api/migrations_sqlite/versions/d781f58f607f_tag_object_name_string.py +1 -1
  99. mlrun/api/migrations_sqlite/versions/deac06871ace_adding_marketplace_sources_table.py +1 -1
  100. mlrun/api/migrations_sqlite/versions/e1dd5983c06b_schedule_concurrency_limit.py +1 -1
  101. mlrun/api/migrations_sqlite/versions/e5594ed3ab53_adding_name_and_updated_to_runs_table.py +1 -1
  102. mlrun/api/migrations_sqlite/versions/f4249b4ba6fa_adding_feature_vectors.py +1 -1
  103. mlrun/api/migrations_sqlite/versions/f7b5a1a03629_adding_feature_labels.py +1 -1
  104. mlrun/api/schemas/__init__.py +216 -138
  105. mlrun/api/utils/__init__.py +1 -1
  106. mlrun/api/utils/asyncio.py +1 -1
  107. mlrun/api/utils/auth/__init__.py +1 -1
  108. mlrun/api/utils/auth/providers/__init__.py +1 -1
  109. mlrun/api/utils/auth/providers/base.py +7 -7
  110. mlrun/api/utils/auth/providers/nop.py +6 -7
  111. mlrun/api/utils/auth/providers/opa.py +17 -17
  112. mlrun/api/utils/auth/verifier.py +36 -34
  113. mlrun/api/utils/background_tasks.py +24 -24
  114. mlrun/{builder.py → api/utils/builder.py} +216 -123
  115. mlrun/api/utils/clients/__init__.py +1 -1
  116. mlrun/api/utils/clients/chief.py +19 -4
  117. mlrun/api/utils/clients/iguazio.py +106 -60
  118. mlrun/api/utils/clients/log_collector.py +1 -1
  119. mlrun/api/utils/clients/nuclio.py +23 -23
  120. mlrun/api/utils/clients/protocols/grpc.py +2 -2
  121. mlrun/api/utils/db/__init__.py +1 -1
  122. mlrun/api/utils/db/alembic.py +1 -1
  123. mlrun/api/utils/db/backup.py +1 -1
  124. mlrun/api/utils/db/mysql.py +24 -25
  125. mlrun/api/utils/db/sql_collation.py +1 -1
  126. mlrun/api/utils/db/sqlite_migration.py +2 -2
  127. mlrun/api/utils/events/__init__.py +14 -0
  128. mlrun/api/utils/events/base.py +57 -0
  129. mlrun/api/utils/events/events_factory.py +41 -0
  130. mlrun/api/utils/events/iguazio.py +217 -0
  131. mlrun/api/utils/events/nop.py +55 -0
  132. mlrun/api/utils/helpers.py +16 -13
  133. mlrun/api/utils/memory_reports.py +1 -1
  134. mlrun/api/utils/periodic.py +6 -3
  135. mlrun/api/utils/projects/__init__.py +1 -1
  136. mlrun/api/utils/projects/follower.py +33 -33
  137. mlrun/api/utils/projects/leader.py +36 -34
  138. mlrun/api/utils/projects/member.py +27 -27
  139. mlrun/api/utils/projects/remotes/__init__.py +1 -1
  140. mlrun/api/utils/projects/remotes/follower.py +13 -13
  141. mlrun/api/utils/projects/remotes/leader.py +10 -10
  142. mlrun/api/utils/projects/remotes/nop_follower.py +27 -21
  143. mlrun/api/utils/projects/remotes/nop_leader.py +17 -16
  144. mlrun/api/utils/scheduler.py +140 -51
  145. mlrun/api/utils/singletons/__init__.py +1 -1
  146. mlrun/api/utils/singletons/db.py +9 -15
  147. mlrun/api/utils/singletons/k8s.py +677 -5
  148. mlrun/api/utils/singletons/logs_dir.py +1 -1
  149. mlrun/api/utils/singletons/project_member.py +1 -1
  150. mlrun/api/utils/singletons/scheduler.py +1 -1
  151. mlrun/artifacts/__init__.py +2 -2
  152. mlrun/artifacts/base.py +8 -2
  153. mlrun/artifacts/dataset.py +5 -3
  154. mlrun/artifacts/manager.py +7 -1
  155. mlrun/artifacts/model.py +15 -4
  156. mlrun/artifacts/plots.py +1 -1
  157. mlrun/common/__init__.py +1 -1
  158. mlrun/common/constants.py +15 -0
  159. mlrun/common/model_monitoring.py +209 -0
  160. mlrun/common/schemas/__init__.py +167 -0
  161. mlrun/{api → common}/schemas/artifact.py +13 -14
  162. mlrun/{api → common}/schemas/auth.py +10 -8
  163. mlrun/{api → common}/schemas/background_task.py +3 -3
  164. mlrun/{api → common}/schemas/client_spec.py +1 -1
  165. mlrun/{api → common}/schemas/clusterization_spec.py +3 -3
  166. mlrun/{api → common}/schemas/constants.py +21 -8
  167. mlrun/common/schemas/events.py +36 -0
  168. mlrun/{api → common}/schemas/feature_store.py +2 -1
  169. mlrun/{api → common}/schemas/frontend_spec.py +7 -6
  170. mlrun/{api → common}/schemas/function.py +5 -5
  171. mlrun/{api → common}/schemas/http.py +3 -3
  172. mlrun/common/schemas/hub.py +134 -0
  173. mlrun/{api → common}/schemas/k8s.py +3 -3
  174. mlrun/{api → common}/schemas/memory_reports.py +1 -1
  175. mlrun/common/schemas/model_endpoints.py +342 -0
  176. mlrun/common/schemas/notification.py +57 -0
  177. mlrun/{api → common}/schemas/object.py +6 -6
  178. mlrun/{api → common}/schemas/pipeline.py +3 -3
  179. mlrun/{api → common}/schemas/project.py +6 -5
  180. mlrun/common/schemas/regex.py +24 -0
  181. mlrun/common/schemas/runs.py +30 -0
  182. mlrun/{api → common}/schemas/runtime_resource.py +3 -3
  183. mlrun/{api → common}/schemas/schedule.py +19 -7
  184. mlrun/{api → common}/schemas/secret.py +3 -3
  185. mlrun/{api → common}/schemas/tag.py +2 -2
  186. mlrun/common/types.py +25 -0
  187. mlrun/config.py +152 -20
  188. mlrun/data_types/__init__.py +7 -2
  189. mlrun/data_types/data_types.py +4 -2
  190. mlrun/data_types/infer.py +1 -1
  191. mlrun/data_types/spark.py +10 -3
  192. mlrun/datastore/__init__.py +10 -3
  193. mlrun/datastore/azure_blob.py +1 -1
  194. mlrun/datastore/base.py +185 -53
  195. mlrun/datastore/datastore.py +1 -1
  196. mlrun/datastore/filestore.py +1 -1
  197. mlrun/datastore/google_cloud_storage.py +1 -1
  198. mlrun/datastore/inmem.py +4 -1
  199. mlrun/datastore/redis.py +1 -1
  200. mlrun/datastore/s3.py +1 -1
  201. mlrun/datastore/sources.py +192 -70
  202. mlrun/datastore/spark_udf.py +44 -0
  203. mlrun/datastore/store_resources.py +4 -4
  204. mlrun/datastore/targets.py +115 -45
  205. mlrun/datastore/utils.py +127 -5
  206. mlrun/datastore/v3io.py +1 -1
  207. mlrun/datastore/wasbfs/__init__.py +1 -1
  208. mlrun/datastore/wasbfs/fs.py +1 -1
  209. mlrun/db/__init__.py +7 -5
  210. mlrun/db/base.py +112 -68
  211. mlrun/db/httpdb.py +445 -277
  212. mlrun/db/nopdb.py +491 -0
  213. mlrun/db/sqldb.py +112 -65
  214. mlrun/errors.py +6 -1
  215. mlrun/execution.py +44 -22
  216. mlrun/feature_store/__init__.py +1 -1
  217. mlrun/feature_store/api.py +143 -95
  218. mlrun/feature_store/common.py +16 -20
  219. mlrun/feature_store/feature_set.py +42 -12
  220. mlrun/feature_store/feature_vector.py +32 -21
  221. mlrun/feature_store/ingestion.py +9 -12
  222. mlrun/feature_store/retrieval/__init__.py +3 -2
  223. mlrun/feature_store/retrieval/base.py +388 -66
  224. mlrun/feature_store/retrieval/dask_merger.py +63 -151
  225. mlrun/feature_store/retrieval/job.py +30 -12
  226. mlrun/feature_store/retrieval/local_merger.py +40 -133
  227. mlrun/feature_store/retrieval/spark_merger.py +129 -127
  228. mlrun/feature_store/retrieval/storey_merger.py +173 -0
  229. mlrun/feature_store/steps.py +132 -15
  230. mlrun/features.py +8 -3
  231. mlrun/frameworks/__init__.py +1 -1
  232. mlrun/frameworks/_common/__init__.py +1 -1
  233. mlrun/frameworks/_common/artifacts_library.py +1 -1
  234. mlrun/frameworks/_common/mlrun_interface.py +1 -1
  235. mlrun/frameworks/_common/model_handler.py +1 -1
  236. mlrun/frameworks/_common/plan.py +1 -1
  237. mlrun/frameworks/_common/producer.py +1 -1
  238. mlrun/frameworks/_common/utils.py +1 -1
  239. mlrun/frameworks/_dl_common/__init__.py +1 -1
  240. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -1
  241. mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
  242. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +1 -1
  243. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +1 -1
  244. mlrun/frameworks/_dl_common/model_handler.py +1 -1
  245. mlrun/frameworks/_dl_common/utils.py +1 -1
  246. mlrun/frameworks/_ml_common/__init__.py +1 -1
  247. mlrun/frameworks/_ml_common/artifacts_library.py +1 -1
  248. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -1
  249. mlrun/frameworks/_ml_common/loggers/logger.py +1 -1
  250. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
  251. mlrun/frameworks/_ml_common/model_handler.py +1 -1
  252. mlrun/frameworks/_ml_common/pkl_model_server.py +13 -1
  253. mlrun/frameworks/_ml_common/plan.py +1 -1
  254. mlrun/frameworks/_ml_common/plans/__init__.py +1 -1
  255. mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +1 -6
  256. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +1 -1
  257. mlrun/frameworks/_ml_common/plans/dataset_plan.py +1 -1
  258. mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +1 -1
  259. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +1 -1
  260. mlrun/frameworks/_ml_common/producer.py +1 -1
  261. mlrun/frameworks/_ml_common/utils.py +1 -1
  262. mlrun/frameworks/auto_mlrun/__init__.py +1 -1
  263. mlrun/frameworks/auto_mlrun/auto_mlrun.py +1 -1
  264. mlrun/frameworks/huggingface/__init__.py +1 -1
  265. mlrun/frameworks/huggingface/model_server.py +1 -1
  266. mlrun/frameworks/lgbm/__init__.py +1 -1
  267. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -1
  268. mlrun/frameworks/lgbm/callbacks/callback.py +1 -1
  269. mlrun/frameworks/lgbm/callbacks/logging_callback.py +1 -1
  270. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +1 -1
  271. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -1
  272. mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -1
  273. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +1 -1
  274. mlrun/frameworks/lgbm/mlrun_interfaces/model_mlrun_interface.py +1 -1
  275. mlrun/frameworks/lgbm/model_handler.py +1 -1
  276. mlrun/frameworks/lgbm/model_server.py +1 -1
  277. mlrun/frameworks/lgbm/utils.py +1 -1
  278. mlrun/frameworks/onnx/__init__.py +1 -1
  279. mlrun/frameworks/onnx/dataset.py +1 -1
  280. mlrun/frameworks/onnx/mlrun_interface.py +1 -1
  281. mlrun/frameworks/onnx/model_handler.py +1 -1
  282. mlrun/frameworks/onnx/model_server.py +1 -1
  283. mlrun/frameworks/parallel_coordinates.py +1 -1
  284. mlrun/frameworks/pytorch/__init__.py +1 -1
  285. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -1
  286. mlrun/frameworks/pytorch/callbacks/callback.py +1 -1
  287. mlrun/frameworks/pytorch/callbacks/logging_callback.py +1 -1
  288. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +1 -1
  289. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +1 -1
  290. mlrun/frameworks/pytorch/callbacks_handler.py +1 -1
  291. mlrun/frameworks/pytorch/mlrun_interface.py +1 -1
  292. mlrun/frameworks/pytorch/model_handler.py +1 -1
  293. mlrun/frameworks/pytorch/model_server.py +1 -1
  294. mlrun/frameworks/pytorch/utils.py +1 -1
  295. mlrun/frameworks/sklearn/__init__.py +1 -1
  296. mlrun/frameworks/sklearn/estimator.py +1 -1
  297. mlrun/frameworks/sklearn/metric.py +1 -1
  298. mlrun/frameworks/sklearn/metrics_library.py +1 -1
  299. mlrun/frameworks/sklearn/mlrun_interface.py +1 -1
  300. mlrun/frameworks/sklearn/model_handler.py +1 -1
  301. mlrun/frameworks/sklearn/utils.py +1 -1
  302. mlrun/frameworks/tf_keras/__init__.py +1 -1
  303. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -1
  304. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  305. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +1 -1
  306. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +1 -1
  307. mlrun/frameworks/tf_keras/mlrun_interface.py +1 -1
  308. mlrun/frameworks/tf_keras/model_handler.py +1 -1
  309. mlrun/frameworks/tf_keras/model_server.py +1 -1
  310. mlrun/frameworks/tf_keras/utils.py +1 -1
  311. mlrun/frameworks/xgboost/__init__.py +1 -1
  312. mlrun/frameworks/xgboost/mlrun_interface.py +1 -1
  313. mlrun/frameworks/xgboost/model_handler.py +1 -1
  314. mlrun/frameworks/xgboost/utils.py +1 -1
  315. mlrun/k8s_utils.py +14 -765
  316. mlrun/kfpops.py +14 -17
  317. mlrun/launcher/__init__.py +13 -0
  318. mlrun/launcher/base.py +406 -0
  319. mlrun/launcher/client.py +159 -0
  320. mlrun/launcher/factory.py +50 -0
  321. mlrun/launcher/local.py +276 -0
  322. mlrun/launcher/remote.py +178 -0
  323. mlrun/lists.py +10 -2
  324. mlrun/mlutils/__init__.py +1 -1
  325. mlrun/mlutils/data.py +1 -1
  326. mlrun/mlutils/models.py +1 -1
  327. mlrun/mlutils/plots.py +1 -1
  328. mlrun/model.py +252 -14
  329. mlrun/model_monitoring/__init__.py +41 -0
  330. mlrun/model_monitoring/features_drift_table.py +1 -1
  331. mlrun/model_monitoring/helpers.py +123 -38
  332. mlrun/model_monitoring/model_endpoint.py +144 -0
  333. mlrun/model_monitoring/model_monitoring_batch.py +310 -259
  334. mlrun/model_monitoring/stores/__init__.py +106 -0
  335. mlrun/model_monitoring/stores/kv_model_endpoint_store.py +448 -0
  336. mlrun/model_monitoring/stores/model_endpoint_store.py +147 -0
  337. mlrun/model_monitoring/stores/models/__init__.py +23 -0
  338. mlrun/model_monitoring/stores/models/base.py +18 -0
  339. mlrun/model_monitoring/stores/models/mysql.py +100 -0
  340. mlrun/model_monitoring/stores/models/sqlite.py +98 -0
  341. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +370 -0
  342. mlrun/model_monitoring/stream_processing_fs.py +239 -271
  343. mlrun/package/__init__.py +163 -0
  344. mlrun/package/context_handler.py +325 -0
  345. mlrun/package/errors.py +47 -0
  346. mlrun/package/packager.py +298 -0
  347. mlrun/{runtimes/package → package/packagers}/__init__.py +3 -1
  348. mlrun/package/packagers/default_packager.py +422 -0
  349. mlrun/package/packagers/numpy_packagers.py +612 -0
  350. mlrun/package/packagers/pandas_packagers.py +968 -0
  351. mlrun/package/packagers/python_standard_library_packagers.py +616 -0
  352. mlrun/package/packagers_manager.py +786 -0
  353. mlrun/package/utils/__init__.py +53 -0
  354. mlrun/package/utils/_archiver.py +226 -0
  355. mlrun/package/utils/_formatter.py +211 -0
  356. mlrun/package/utils/_pickler.py +234 -0
  357. mlrun/package/utils/_supported_format.py +71 -0
  358. mlrun/package/utils/log_hint_utils.py +93 -0
  359. mlrun/package/utils/type_hint_utils.py +298 -0
  360. mlrun/platforms/__init__.py +1 -1
  361. mlrun/platforms/iguazio.py +34 -2
  362. mlrun/platforms/other.py +1 -1
  363. mlrun/projects/__init__.py +1 -1
  364. mlrun/projects/operations.py +14 -9
  365. mlrun/projects/pipelines.py +31 -13
  366. mlrun/projects/project.py +762 -238
  367. mlrun/render.py +49 -19
  368. mlrun/run.py +57 -326
  369. mlrun/runtimes/__init__.py +3 -9
  370. mlrun/runtimes/base.py +247 -784
  371. mlrun/runtimes/constants.py +1 -1
  372. mlrun/runtimes/daskjob.py +45 -41
  373. mlrun/runtimes/funcdoc.py +43 -7
  374. mlrun/runtimes/function.py +66 -656
  375. mlrun/runtimes/function_reference.py +1 -1
  376. mlrun/runtimes/generators.py +1 -1
  377. mlrun/runtimes/kubejob.py +99 -116
  378. mlrun/runtimes/local.py +59 -66
  379. mlrun/runtimes/mpijob/__init__.py +1 -1
  380. mlrun/runtimes/mpijob/abstract.py +13 -15
  381. mlrun/runtimes/mpijob/v1.py +3 -1
  382. mlrun/runtimes/mpijob/v1alpha1.py +1 -1
  383. mlrun/runtimes/nuclio.py +1 -1
  384. mlrun/runtimes/pod.py +51 -26
  385. mlrun/runtimes/remotesparkjob.py +3 -1
  386. mlrun/runtimes/serving.py +12 -4
  387. mlrun/runtimes/sparkjob/__init__.py +1 -2
  388. mlrun/runtimes/sparkjob/abstract.py +44 -31
  389. mlrun/runtimes/sparkjob/spark3job.py +11 -9
  390. mlrun/runtimes/utils.py +61 -42
  391. mlrun/secrets.py +16 -18
  392. mlrun/serving/__init__.py +3 -2
  393. mlrun/serving/merger.py +1 -1
  394. mlrun/serving/remote.py +1 -1
  395. mlrun/serving/routers.py +39 -42
  396. mlrun/serving/server.py +23 -13
  397. mlrun/serving/serving_wrapper.py +1 -1
  398. mlrun/serving/states.py +172 -39
  399. mlrun/serving/utils.py +1 -1
  400. mlrun/serving/v1_serving.py +1 -1
  401. mlrun/serving/v2_serving.py +29 -21
  402. mlrun/utils/__init__.py +1 -2
  403. mlrun/utils/async_http.py +8 -1
  404. mlrun/utils/azure_vault.py +1 -1
  405. mlrun/utils/clones.py +2 -2
  406. mlrun/utils/condition_evaluator.py +65 -0
  407. mlrun/utils/db.py +52 -0
  408. mlrun/utils/helpers.py +188 -13
  409. mlrun/utils/http.py +89 -54
  410. mlrun/utils/logger.py +48 -8
  411. mlrun/utils/model_monitoring.py +132 -100
  412. mlrun/utils/notifications/__init__.py +1 -1
  413. mlrun/utils/notifications/notification/__init__.py +8 -6
  414. mlrun/utils/notifications/notification/base.py +20 -14
  415. mlrun/utils/notifications/notification/console.py +7 -4
  416. mlrun/utils/notifications/notification/git.py +36 -19
  417. mlrun/utils/notifications/notification/ipython.py +10 -8
  418. mlrun/utils/notifications/notification/slack.py +18 -13
  419. mlrun/utils/notifications/notification_pusher.py +377 -56
  420. mlrun/utils/regex.py +6 -1
  421. mlrun/utils/singleton.py +1 -1
  422. mlrun/utils/v3io_clients.py +1 -1
  423. mlrun/utils/vault.py +270 -269
  424. mlrun/utils/version/__init__.py +1 -1
  425. mlrun/utils/version/version.json +2 -2
  426. mlrun/utils/version/version.py +1 -1
  427. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/METADATA +16 -10
  428. mlrun-1.4.0.dist-info/RECORD +434 -0
  429. mlrun/api/api/endpoints/marketplace.py +0 -257
  430. mlrun/api/crud/marketplace.py +0 -221
  431. mlrun/api/crud/model_monitoring/model_endpoint_store.py +0 -847
  432. mlrun/api/db/filedb/db.py +0 -518
  433. mlrun/api/schemas/marketplace.py +0 -128
  434. mlrun/api/schemas/model_endpoints.py +0 -185
  435. mlrun/db/filedb.py +0 -891
  436. mlrun/feature_store/retrieval/online.py +0 -92
  437. mlrun/model_monitoring/constants.py +0 -67
  438. mlrun/runtimes/package/context_handler.py +0 -711
  439. mlrun/runtimes/sparkjob/spark2job.py +0 -59
  440. mlrun-1.3.3.dist-info/RECORD +0 -381
  441. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
  442. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
  443. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
  444. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
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.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
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.
mlrun/runtimes/kubejob.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -14,15 +14,15 @@
14
14
 
15
15
  import os
16
16
  import time
17
+ import warnings
17
18
 
18
19
  from kubernetes import client
19
20
  from kubernetes.client.rest import ApiException
20
21
 
21
- import mlrun.api.schemas
22
+ import mlrun.common.schemas
22
23
  import mlrun.errors
23
24
  from mlrun.runtimes.base import BaseRuntimeHandler
24
25
 
25
- from ..builder import build_runtime
26
26
  from ..db import RunDBError
27
27
  from ..errors import err_to_str
28
28
  from ..kfpops import build_op
@@ -30,7 +30,7 @@ from ..model import RunObject
30
30
  from ..utils import get_in, logger
31
31
  from .base import RunError, RuntimeClassMode
32
32
  from .pod import KubeResource, kube_resource_spec_to_pod_spec
33
- from .utils import AsyncLogWriter
33
+ from .utils import get_k8s
34
34
 
35
35
 
36
36
  class KubejobRuntime(KubeResource):
@@ -44,12 +44,13 @@ class KubejobRuntime(KubeResource):
44
44
  if self.spec.image:
45
45
  return True
46
46
 
47
- if self._is_remote_api():
48
- db = self._get_db()
49
- try:
50
- db.get_builder_status(self, logs=False)
51
- except Exception:
52
- pass
47
+ db = self._get_db()
48
+ try:
49
+ # getting builder status enriches the runtime when it needs to be fetched from the API,
50
+ # otherwise it's a no-op
51
+ db.get_builder_status(self, logs=False)
52
+ except Exception:
53
+ pass
53
54
 
54
55
  if self.spec.image:
55
56
  return True
@@ -58,27 +59,30 @@ class KubejobRuntime(KubeResource):
58
59
  return False
59
60
 
60
61
  def with_source_archive(
61
- self, source, workdir=None, handler=None, pull_at_runtime=True
62
+ self, source, workdir=None, handler=None, pull_at_runtime=True, target_dir=None
62
63
  ):
63
64
  """load the code from git/tar/zip archive at runtime or build
64
65
 
65
- :param source: valid path to git, zip, or tar file, e.g.
66
- git://github.com/mlrun/something.git
67
- http://some/url/file.zip
68
- :param handler: default function handler
69
- :param workdir: working dir relative to the archive root or absolute (e.g. './subdir')
66
+ :param source: valid absolute path or URL to git, zip, or tar file, e.g.
67
+ git://github.com/mlrun/something.git
68
+ http://some/url/file.zip
69
+ note path source must exist on the image or exist locally when run is local
70
+ (it is recommended to use 'workdir' when source is a filepath instead)
71
+ :param handler: default function handler
72
+ :param workdir: working dir relative to the archive root (e.g. './subdir') or absolute to the image root
70
73
  :param pull_at_runtime: load the archive into the container at job runtime vs on build/deploy
74
+ :param target_dir: target dir on runtime pod or repo clone / archive extraction
71
75
  """
72
- if source.endswith(".zip") and not pull_at_runtime:
73
- logger.warn(
74
- "zip files are not natively extracted by docker, use tar.gz for faster loading during build"
75
- )
76
+ mlrun.utils.helpers.validate_builder_source(source, pull_at_runtime, workdir)
76
77
 
77
78
  self.spec.build.source = source
78
79
  if handler:
79
80
  self.spec.default_handler = handler
80
81
  if workdir:
81
82
  self.spec.workdir = workdir
83
+ if target_dir:
84
+ self.spec.clone_target_dir = target_dir
85
+
82
86
  self.spec.build.load_source_on_run = pull_at_runtime
83
87
  if (
84
88
  self.spec.build.base_image
@@ -86,7 +90,7 @@ class KubejobRuntime(KubeResource):
86
90
  and pull_at_runtime
87
91
  and not self.spec.image
88
92
  ):
89
- # if we load source from repo and dont need a full build use the base_image as the image
93
+ # if we load source from repo and don't need a full build use the base_image as the image
90
94
  self.spec.image = self.spec.build.base_image
91
95
  elif not pull_at_runtime:
92
96
  # clear the image so build will not be skipped
@@ -106,7 +110,9 @@ class KubejobRuntime(KubeResource):
106
110
  auto_build=None,
107
111
  requirements=None,
108
112
  overwrite=False,
109
- verify_base_image=True,
113
+ verify_base_image=False,
114
+ prepare_image_for_deploy=True,
115
+ requirements_file=None,
110
116
  ):
111
117
  """specify builder configuration for the deploy operation
112
118
 
@@ -121,43 +127,43 @@ class KubejobRuntime(KubeResource):
121
127
  :param with_mlrun: add the current mlrun package to the container build
122
128
  :param auto_build: when set to True and the function require build it will be built on the first
123
129
  function run, use only if you dont plan on changing the build config between runs
124
- :param requirements: requirements.txt file to install or list of packages to install
130
+ :param requirements: a list of packages to install
131
+ :param requirements_file: requirements file to install
125
132
  :param overwrite: overwrite existing build configuration
126
133
 
127
134
  * False: the new params are merged with the existing (currently merge is applied to requirements and
128
135
  commands)
129
136
  * True: the existing params are replaced by the new ones
130
- :param verify_base_image: verify the base image is set
137
+ :param verify_base_image: verify that the base image is configured
138
+ (deprecated, use prepare_image_for_deploy)
139
+ :param prepare_image_for_deploy: prepare the image/base_image spec for deployment
131
140
  """
132
- if image:
133
- self.spec.build.image = image
134
- if base_image:
135
- self.spec.build.base_image = base_image
136
- # if overwrite and requirements or commands passed, clear the existing commands
137
- # (requirements are added to the commands parameter)
138
- if (requirements or commands) and overwrite:
139
- self.spec.build.commands = None
140
- if requirements:
141
- self.with_requirements(
142
- requirements, overwrite=False, verify_base_image=False
143
- )
144
- if commands:
145
- self.with_commands(commands, overwrite=False, verify_base_image=False)
146
- if extra:
147
- self.spec.build.extra = extra
148
- if secret is not None:
149
- self.spec.build.secret = secret
150
- if source:
151
- self.spec.build.source = source
152
- if load_source_on_run:
153
- self.spec.build.load_source_on_run = load_source_on_run
154
- if with_mlrun is not None:
155
- self.spec.build.with_mlrun = with_mlrun
156
- if auto_build:
157
- self.spec.build.auto_build = auto_build
158
-
159
- if verify_base_image:
160
- self.verify_base_image()
141
+
142
+ image = mlrun.utils.helpers.remove_image_protocol_prefix(image)
143
+ self.spec.build.build_config(
144
+ image,
145
+ base_image,
146
+ commands,
147
+ secret,
148
+ source,
149
+ extra,
150
+ load_source_on_run,
151
+ with_mlrun,
152
+ auto_build,
153
+ requirements,
154
+ requirements_file,
155
+ overwrite,
156
+ )
157
+
158
+ if verify_base_image or prepare_image_for_deploy:
159
+ if verify_base_image:
160
+ # TODO: remove verify_base_image in 1.6.0
161
+ warnings.warn(
162
+ "verify_base_image is deprecated in 1.4.0 and will be removed in 1.6.0, "
163
+ "use prepare_image_for_deploy",
164
+ category=FutureWarning,
165
+ )
166
+ self.prepare_image_for_deploy()
161
167
 
162
168
  def deploy(
163
169
  self,
@@ -194,7 +200,13 @@ class KubejobRuntime(KubeResource):
194
200
  or "/mlrun/" in build.base_image
195
201
  )
196
202
 
197
- if not build.source and not build.commands and not build.extra and with_mlrun:
203
+ if (
204
+ not build.source
205
+ and not build.commands
206
+ and not build.requirements
207
+ and not build.extra
208
+ and with_mlrun
209
+ ):
198
210
  logger.info(
199
211
  "running build to add mlrun package, set "
200
212
  "with_mlrun=False to skip if its already in the image"
@@ -209,6 +221,7 @@ class KubejobRuntime(KubeResource):
209
221
  if is_kfp:
210
222
  watch = True
211
223
 
224
+ ready = False
212
225
  if self._is_remote_api():
213
226
  db = self._get_db()
214
227
  data = db.remote_builder(
@@ -223,6 +236,8 @@ class KubejobRuntime(KubeResource):
223
236
  self.spec.build.base_image = self.spec.build.base_image or get_in(
224
237
  data, "data.spec.build.base_image"
225
238
  )
239
+ # get the clone target dir in case it was enriched due to loading source
240
+ self.spec.clone_target_dir = get_in(data, "data.spec.clone_target_dir")
226
241
  ready = data.get("ready", False)
227
242
  if not ready:
228
243
  logger.info(
@@ -232,17 +247,6 @@ class KubejobRuntime(KubeResource):
232
247
  state = self._build_watch(watch, show_on_failure=show_on_failure)
233
248
  ready = state == "ready"
234
249
  self.status.state = state
235
- else:
236
- self.save(versioned=False)
237
- ready = build_runtime(
238
- mlrun.api.schemas.AuthInfo(),
239
- self,
240
- with_mlrun,
241
- mlrun_version_specifier,
242
- skip_deployed,
243
- watch,
244
- )
245
- self.save(versioned=False)
246
250
 
247
251
  if watch and not ready:
248
252
  raise mlrun.errors.MLRunRuntimeError("Deploy failed")
@@ -279,36 +283,6 @@ class KubejobRuntime(KubeResource):
279
283
  print()
280
284
  return self.status.state
281
285
 
282
- def builder_status(self, watch=True, logs=True):
283
- if self._is_remote_api():
284
- return self._build_watch(watch, logs)
285
-
286
- else:
287
- pod = self.status.build_pod
288
- if not self.status.state == "ready" and pod:
289
- k8s = self._get_k8s()
290
- status = k8s.get_pod_status(pod)
291
- if logs:
292
- if watch:
293
- status = k8s.watch(pod)
294
- else:
295
- resp = k8s.logs(pod)
296
- if resp:
297
- print(resp.encode())
298
-
299
- if status == "succeeded":
300
- self.status.build_pod = None
301
- self.status.state = "ready"
302
- logger.info("build completed successfully")
303
- return "ready"
304
- if status in ["failed", "error"]:
305
- self.status.state = status
306
- logger.error(f" build {status}, watch the build pod logs: {pod}")
307
- return status
308
-
309
- logger.info(f"builder status is: {status}, wait for it to complete")
310
- return None
311
-
312
286
  def deploy_step(
313
287
  self,
314
288
  image=None,
@@ -335,23 +309,14 @@ class KubejobRuntime(KubeResource):
335
309
  )
336
310
 
337
311
  def _run(self, runobj: RunObject, execution):
338
-
339
312
  command, args, extra_env = self._get_cmd_args(runobj)
340
313
 
341
314
  if runobj.metadata.iteration:
342
315
  self.store_run(runobj)
343
- k8s = self._get_k8s()
344
316
  new_meta = self._get_meta(runobj)
345
317
 
346
318
  self._add_secrets_to_spec_before_running(runobj)
347
- workdir = self.spec.workdir
348
- if workdir:
349
- if self.spec.build.source and self.spec.build.load_source_on_run:
350
- # workdir will be set AFTER the clone
351
- workdir = None
352
- elif not workdir.startswith("/"):
353
- # relative path mapped to real path in the job pod
354
- workdir = os.path.join("/mlrun", workdir)
319
+ workdir = self._resolve_workdir()
355
320
 
356
321
  pod_spec = func_to_pod(
357
322
  self.full_image_path(
@@ -368,23 +333,41 @@ class KubejobRuntime(KubeResource):
368
333
  )
369
334
  pod = client.V1Pod(metadata=new_meta, spec=pod_spec)
370
335
  try:
371
- pod_name, namespace = k8s.create_pod(pod)
336
+ pod_name, namespace = get_k8s().create_pod(pod)
372
337
  except ApiException as exc:
373
338
  raise RunError(err_to_str(exc))
374
339
 
375
- if pod_name and self.kfp:
376
- writer = AsyncLogWriter(self._db_conn, runobj)
377
- status = k8s.watch(pod_name, namespace, writer=writer)
378
-
379
- if status in ["failed", "error"]:
380
- raise RunError(f"pod exited with {status}, check logs")
381
- else:
382
- txt = f"Job is running in the background, pod: {pod_name}"
383
- logger.info(txt)
384
- runobj.status.status_text = txt
340
+ txt = f"Job is running in the background, pod: {pod_name}"
341
+ logger.info(txt)
342
+ runobj.status.status_text = txt
385
343
 
386
344
  return None
387
345
 
346
+ def _resolve_workdir(self):
347
+ """
348
+ The workdir is relative to the source root, if the source is not loaded on run then the workdir
349
+ is relative to the clone target dir (where the source was copied to).
350
+ Otherwise, if the source is loaded on run, the workdir is resolved on the run as well.
351
+ If the workdir is absolute, keep it as is.
352
+ """
353
+ workdir = self.spec.workdir
354
+ if self.spec.build.source and self.spec.build.load_source_on_run:
355
+ # workdir will be set AFTER the clone which is done in the pre-run of local runtime
356
+ return None
357
+
358
+ if workdir and os.path.isabs(workdir):
359
+ return workdir
360
+
361
+ if self.spec.clone_target_dir:
362
+ workdir = workdir or ""
363
+ if workdir.startswith("./"):
364
+ # TODO: use 'removeprefix' when we drop python 3.7 support
365
+ # workdir.removeprefix("./")
366
+ workdir = workdir[2:]
367
+ return os.path.join(self.spec.clone_target_dir, workdir)
368
+
369
+ return workdir
370
+
388
371
 
389
372
  def func_to_pod(image, runtime, extra_env, command, args, workdir):
390
373
  container = client.V1Container(
mlrun/runtimes/local.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -41,7 +41,7 @@ from ..execution import MLClientCtx
41
41
  from ..model import RunObject
42
42
  from ..utils import get_handler_extended, get_in, logger, set_paths
43
43
  from ..utils.clones import extract_source
44
- from .base import BaseRuntime, FunctionSpec, spec_fields
44
+ from .base import BaseRuntime
45
45
  from .kubejob import KubejobRuntime
46
46
  from .remotesparkjob import RemoteSparkRuntime
47
47
  from .utils import RunError, global_context, log_std
@@ -172,48 +172,10 @@ class HandlerRuntime(BaseRuntime, ParallelRunner):
172
172
  return context.to_dict()
173
173
 
174
174
 
175
- class LocalFunctionSpec(FunctionSpec):
176
- _dict_fields = spec_fields + ["clone_target_dir"]
177
-
178
- def __init__(
179
- self,
180
- command=None,
181
- args=None,
182
- mode=None,
183
- default_handler=None,
184
- pythonpath=None,
185
- entry_points=None,
186
- description=None,
187
- workdir=None,
188
- build=None,
189
- clone_target_dir=None,
190
- ):
191
- super().__init__(
192
- command=command,
193
- args=args,
194
- mode=mode,
195
- build=build,
196
- entry_points=entry_points,
197
- description=description,
198
- workdir=workdir,
199
- default_handler=default_handler,
200
- pythonpath=pythonpath,
201
- )
202
- self.clone_target_dir = clone_target_dir
203
-
204
-
205
175
  class LocalRuntime(BaseRuntime, ParallelRunner):
206
176
  kind = "local"
207
177
  _is_remote = False
208
178
 
209
- @property
210
- def spec(self) -> LocalFunctionSpec:
211
- return self._spec
212
-
213
- @spec.setter
214
- def spec(self, spec):
215
- self._spec = self._verify_dict(spec, "spec", LocalFunctionSpec)
216
-
217
179
  def to_job(self, image=""):
218
180
  struct = self.to_dict()
219
181
  obj = KubejobRuntime.from_dict(struct)
@@ -224,12 +186,12 @@ class LocalRuntime(BaseRuntime, ParallelRunner):
224
186
  def with_source_archive(self, source, workdir=None, handler=None, target_dir=None):
225
187
  """load the code from git/tar/zip archive at runtime or build
226
188
 
227
- :param source: valid path to git, zip, or tar file, e.g.
228
- git://github.com/mlrun/something.git
229
- http://some/url/file.zip
230
- :param handler: default function handler
231
- :param workdir: working dir relative to the archive root or absolute (e.g. './subdir')
232
- :param target_dir: local target dir for repo clone (by default its <current-dir>/code)
189
+ :param source: valid path to git, zip, or tar file, e.g.
190
+ git://github.com/mlrun/something.git
191
+ http://some/url/file.zip
192
+ :param handler: default function handler
193
+ :param workdir: working dir relative to the archive root (e.g. './subdir') or absolute
194
+ :param target_dir: local target dir for repo clone (by default its <current-dir>/code)
233
195
  """
234
196
  self.spec.build.source = source
235
197
  self.spec.build.load_source_on_run = True
@@ -255,6 +217,8 @@ class LocalRuntime(BaseRuntime, ParallelRunner):
255
217
  execution._current_workdir = workdir
256
218
  execution._old_workdir = None
257
219
 
220
+ # _is_run_local is set when the user specifies local=True in run()
221
+ # in this case we don't want to extract the source code and contaminate the user's local dir
258
222
  if self.spec.build.source and not hasattr(self, "_is_run_local"):
259
223
  target_dir = extract_source(
260
224
  self.spec.build.source,
@@ -456,7 +420,7 @@ def exec_from_params(handler, runobj: RunObject, context: MLClientCtx, cwd=None)
456
420
  if runobj.spec.verbose:
457
421
  logger.set_logger_level("DEBUG")
458
422
 
459
- # Prepare the inputs type hints (user may pass type hints as part of the inputs keys):
423
+ # Prepare the inputs type hints (user may pass type hints as part of the input keys):
460
424
  runobj.spec.extract_type_hints_from_inputs()
461
425
  # Read the keyword arguments to pass to the function (combining params and inputs from the run spec):
462
426
  kwargs = get_func_arg(handler, runobj, context)
@@ -471,20 +435,23 @@ def exec_from_params(handler, runobj: RunObject, context: MLClientCtx, cwd=None)
471
435
  if cwd:
472
436
  os.chdir(cwd)
473
437
  # Apply the MLRun handler decorator for parsing inputs using type hints and logging outputs using log hints
474
- # (Expected behavior: inputs are being parsed when they have type hints in code or given by user.
475
- # outputs are logged only if log hints are provided by the user):
476
- val = mlrun.handler(
477
- inputs=(
478
- runobj.spec.inputs_type_hints
479
- if runobj.spec.inputs_type_hints
480
- else True # True will use type hints if provided in user's code.
481
- ),
482
- outputs=(
483
- runobj.spec.returns
484
- if runobj.spec.returns
485
- else None # None will turn off outputs logging.
486
- ),
487
- )(handler)(**kwargs)
438
+ # (Expected behavior: inputs are being parsed when they have type hints in code or given by user. Outputs
439
+ # are logged only if log hints are provided by the user):
440
+ if mlrun.mlconf.packagers.enabled:
441
+ val = mlrun.handler(
442
+ inputs=(
443
+ runobj.spec.inputs_type_hints
444
+ if runobj.spec.inputs_type_hints
445
+ else True # True will use type hints if provided in user's code.
446
+ ),
447
+ outputs=(
448
+ runobj.spec.returns
449
+ if runobj.spec.returns
450
+ else None # None will turn off outputs logging.
451
+ ),
452
+ )(handler)(**kwargs)
453
+ else:
454
+ val = handler(**kwargs)
488
455
  context.set_state("completed", commit=False)
489
456
  except Exception as exc:
490
457
  err = err_to_str(exc)
@@ -511,6 +478,18 @@ def get_func_arg(handler, runobj: RunObject, context: MLClientCtx, is_nuclio=Fal
511
478
  kwargs = {}
512
479
  args = inspect.signature(handler).parameters
513
480
 
481
+ def _get_input_value(input_key: str):
482
+ input_obj = context.get_input(input_key, inputs[input_key])
483
+ # If there is no type hint annotation but there is a default value and its type is string, point the data
484
+ # item to local downloaded file path (`local()` returns the downloaded temp path string):
485
+ if (
486
+ args[input_key].annotation is inspect.Parameter.empty
487
+ and type(args[input_key].default) is str
488
+ ):
489
+ return input_obj.local()
490
+ else:
491
+ return input_obj
492
+
514
493
  for key in args.keys():
515
494
  if key == "context":
516
495
  kwargs[key] = context
@@ -519,9 +498,23 @@ def get_func_arg(handler, runobj: RunObject, context: MLClientCtx, is_nuclio=Fal
519
498
  elif key in params:
520
499
  kwargs[key] = copy(params[key])
521
500
  elif key in inputs:
522
- obj = context.get_input(key, inputs[key])
523
- if type(args[key].default) is str or args[key].annotation == str:
524
- kwargs[key] = obj.local()
525
- else:
526
- kwargs[key] = context.get_input(key, inputs[key])
501
+ kwargs[key] = _get_input_value(key)
502
+
503
+ list_of_params = list(args.values())
504
+ if len(list_of_params) == 0:
505
+ return kwargs
506
+
507
+ # get the last parameter, as **kwargs can only be last in the function's parameters list
508
+ last_param = list_of_params[-1]
509
+ # VAR_KEYWORD meaning : A dict of keyword arguments that aren’t bound to any other parameter.
510
+ # This corresponds to a **kwargs parameter in a Python function definition.
511
+ if last_param.kind == last_param.VAR_KEYWORD:
512
+ # if handler has **kwargs, pass all parameters provided by the user to the handler which were not already set
513
+ # as part of the previous loop which handled all parameters which were explicitly defined in the handler
514
+ for key in params:
515
+ if key not in kwargs:
516
+ kwargs[key] = copy(params[key])
517
+ for key in inputs:
518
+ if key not in kwargs:
519
+ kwargs[key] = _get_input_value(key)
527
520
  return kwargs
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
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.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ from mlrun.execution import MLClientCtx
24
24
  from mlrun.model import RunObject
25
25
  from mlrun.runtimes.kubejob import KubejobRuntime
26
26
  from mlrun.runtimes.pod import KubeResourceSpec
27
- from mlrun.runtimes.utils import RunError
27
+ from mlrun.runtimes.utils import RunError, get_k8s
28
28
  from mlrun.utils import get_in, logger
29
29
 
30
30
 
@@ -60,6 +60,7 @@ class MPIResourceSpec(KubeResourceSpec):
60
60
  tolerations=None,
61
61
  preemption_mode=None,
62
62
  security_context=None,
63
+ clone_target_dir=None,
63
64
  ):
64
65
  super().__init__(
65
66
  command=command,
@@ -88,6 +89,7 @@ class MPIResourceSpec(KubeResourceSpec):
88
89
  tolerations=tolerations,
89
90
  preemption_mode=preemption_mode,
90
91
  security_context=security_context,
92
+ clone_target_dir=clone_target_dir,
91
93
  )
92
94
  self.mpi_args = mpi_args or [
93
95
  "-x",
@@ -189,10 +191,9 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
189
191
  def _submit_mpijob(self, job, namespace=None):
190
192
  mpi_group, mpi_version, mpi_plural = self._get_crd_info()
191
193
 
192
- k8s = self._get_k8s()
193
- namespace = k8s.resolve_namespace(namespace)
194
+ namespace = get_k8s().resolve_namespace(namespace)
194
195
  try:
195
- resp = k8s.crdapi.create_namespaced_custom_object(
196
+ resp = get_k8s().crdapi.create_namespaced_custom_object(
196
197
  mpi_group,
197
198
  mpi_version,
198
199
  namespace=namespace,
@@ -208,7 +209,7 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
208
209
 
209
210
  def delete_job(self, name, namespace=None):
210
211
  mpi_group, mpi_version, mpi_plural = self._get_crd_info()
211
- k8s = self._get_k8s()
212
+ k8s = get_k8s()
212
213
  namespace = k8s.resolve_namespace(namespace)
213
214
  try:
214
215
  # delete the mpi job
@@ -223,11 +224,10 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
223
224
 
224
225
  def list_jobs(self, namespace=None, selector="", show=True):
225
226
  mpi_group, mpi_version, mpi_plural = self._get_crd_info()
226
- k8s = self._get_k8s()
227
- namespace = k8s.resolve_namespace(namespace)
227
+ namespace = get_k8s().resolve_namespace(namespace)
228
228
  items = []
229
229
  try:
230
- resp = k8s.crdapi.list_namespaced_custom_object(
230
+ resp = get_k8s().crdapi.list_namespaced_custom_object(
231
231
  mpi_group,
232
232
  mpi_version,
233
233
  namespace,
@@ -247,10 +247,9 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
247
247
 
248
248
  def get_job(self, name, namespace=None):
249
249
  mpi_group, mpi_version, mpi_plural = self._get_crd_info()
250
- k8s = self._get_k8s()
251
- namespace = k8s.resolve_namespace(namespace)
250
+ namespace = get_k8s().resolve_namespace(namespace)
252
251
  try:
253
- resp = k8s.crdapi.get_namespaced_custom_object(
252
+ resp = get_k8s().crdapi.get_namespaced_custom_object(
254
253
  mpi_group, mpi_version, namespace, mpi_plural, name
255
254
  )
256
255
  except client.exceptions.ApiException as exc:
@@ -259,12 +258,11 @@ class AbstractMPIJobRuntime(KubejobRuntime, abc.ABC):
259
258
  return resp
260
259
 
261
260
  def get_pods(self, name=None, namespace=None, launcher=False):
262
- k8s = self._get_k8s()
263
- namespace = k8s.resolve_namespace(namespace)
261
+ namespace = get_k8s().resolve_namespace(namespace)
264
262
 
265
263
  selector = self._generate_pods_selector(name, launcher)
266
264
 
267
- pods = k8s.list_pods(selector=selector, namespace=namespace)
265
+ pods = get_k8s().list_pods(selector=selector, namespace=namespace)
268
266
  if pods:
269
267
  return {p.metadata.name: p.status.phase for p in pods}
270
268
 
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -62,6 +62,7 @@ class MPIV1ResourceSpec(MPIResourceSpec):
62
62
  tolerations=None,
63
63
  preemption_mode=None,
64
64
  security_context=None,
65
+ clone_target_dir=None,
65
66
  ):
66
67
  super().__init__(
67
68
  command=command,
@@ -91,6 +92,7 @@ class MPIV1ResourceSpec(MPIResourceSpec):
91
92
  tolerations=tolerations,
92
93
  preemption_mode=preemption_mode,
93
94
  security_context=security_context,
95
+ clone_target_dir=clone_target_dir,
94
96
  )
95
97
  self.clean_pod_policy = clean_pod_policy or MPIJobV1CleanPodPolicies.default()
96
98