mlrun 1.3.3rc1__py3-none-any.whl → 1.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mlrun might be problematic. Click here for more details.

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.3rc1.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.3rc1.dist-info/RECORD +0 -381
  441. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
  442. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
  443. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
  444. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
mlrun/kfpops.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.
@@ -18,6 +18,7 @@ import os.path
18
18
  from copy import deepcopy
19
19
  from typing import Dict, List, Union
20
20
 
21
+ import inflection
21
22
  from kfp import dsl
22
23
  from kubernetes import client as k8s_client
23
24
 
@@ -226,7 +227,7 @@ def mlrun_op(
226
227
  :param labels: labels to tag the job/run with ({key:val, ..})
227
228
  :param inputs: dictionary of input objects + optional paths (if path is
228
229
  omitted the path will be the in_path/key.
229
- :param outputs: dictionary of input objects + optional paths (if path is
230
+ :param outputs: dictionary of output objects + optional paths (if path is
230
231
  omitted the path will be the out_path/key.
231
232
  :param in_path: default input path/url (prefix) for inputs
232
233
  :param out_path: default output path/url (prefix) for artifacts
@@ -712,6 +713,14 @@ def generate_kfp_dag_and_resolve_project(run, project=None):
712
713
  record = {
713
714
  k: node[k] for k in ["phase", "startedAt", "finishedAt", "type", "id"]
714
715
  }
716
+
717
+ # snake case
718
+ # align kfp fields to mlrun snake case convention
719
+ # create snake_case for consistency.
720
+ # retain the camelCase for compatibility
721
+ for key in list(record.keys()):
722
+ record[inflection.underscore(key)] = record[key]
723
+
715
724
  record["parent"] = node.get("boundaryID", "")
716
725
  record["name"] = name
717
726
  record["children"] = node.get("children", [])
@@ -747,21 +756,9 @@ def format_summary_from_kfp_run(kfp_run, project=None, session=None):
747
756
  if error:
748
757
  dag[step]["error"] = error
749
758
 
750
- short_run = {"graph": dag}
751
- short_run["run"] = {
752
- k: str(v)
753
- for k, v in kfp_run["run"].items()
754
- if k
755
- in [
756
- "id",
757
- "name",
758
- "status",
759
- "error",
760
- "created_at",
761
- "scheduled_at",
762
- "finished_at",
763
- "description",
764
- ]
759
+ short_run = {
760
+ "graph": dag,
761
+ "run": mlrun.utils.helpers.format_run(kfp_run["run"]),
765
762
  }
766
763
  short_run["run"]["project"] = project
767
764
  short_run["run"]["message"] = message
@@ -0,0 +1,13 @@
1
+ # Copyright 2023 MLRun Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
mlrun/launcher/base.py ADDED
@@ -0,0 +1,406 @@
1
+ # Copyright 2023 MLRun Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import abc
15
+ import ast
16
+ import copy
17
+ import os
18
+ import uuid
19
+ from typing import Any, Callable, Dict, List, Optional, Union
20
+
21
+ import mlrun.common.schemas
22
+ import mlrun.config
23
+ import mlrun.errors
24
+ import mlrun.kfpops
25
+ import mlrun.lists
26
+ import mlrun.model
27
+ import mlrun.runtimes
28
+ from mlrun.utils import logger
29
+
30
+ run_modes = ["pass"]
31
+
32
+
33
+ class BaseLauncher(abc.ABC):
34
+ """
35
+ Abstract class for managing and running functions in different contexts
36
+ This class is designed to encapsulate the logic of running a function in different contexts
37
+ i.e. running a function locally, remotely or in a server
38
+ Each context will have its own implementation of the abstract methods while the common logic resides in this class
39
+ """
40
+
41
+ def save_function(
42
+ self,
43
+ runtime: "mlrun.runtimes.BaseRuntime",
44
+ tag: str = "",
45
+ versioned: bool = False,
46
+ refresh: bool = False,
47
+ ) -> str:
48
+ """
49
+ store the function to the db
50
+ :param runtime: runtime object
51
+ :param tag: function tag to store
52
+ :param versioned: whether we want to version this function object so that it will queryable by its hash key
53
+ :param refresh: refresh function metadata
54
+
55
+ :return: function uri
56
+ """
57
+ db = runtime._get_db()
58
+ if not db:
59
+ raise mlrun.errors.MLRunPreconditionFailedError(
60
+ "Database connection is not configured"
61
+ )
62
+
63
+ if refresh:
64
+ self._refresh_function_metadata(runtime)
65
+
66
+ tag = tag or runtime.metadata.tag
67
+
68
+ obj = runtime.to_dict()
69
+ logger.debug("Saving function", runtime_name=runtime.metadata.name, tag=tag)
70
+ hash_key = db.store_function(
71
+ obj, runtime.metadata.name, runtime.metadata.project, tag, versioned
72
+ )
73
+ hash_key = hash_key if versioned else None
74
+ return "db://" + runtime._function_uri(hash_key=hash_key, tag=tag)
75
+
76
+ @abc.abstractmethod
77
+ def launch(
78
+ self,
79
+ runtime: "mlrun.runtimes.BaseRuntime",
80
+ task: Optional[
81
+ Union["mlrun.run.RunTemplate", "mlrun.run.RunObject", dict]
82
+ ] = None,
83
+ handler: Optional[Union[str, Callable]] = None,
84
+ name: Optional[str] = "",
85
+ project: Optional[str] = "",
86
+ params: Optional[dict] = None,
87
+ inputs: Optional[Dict[str, str]] = None,
88
+ out_path: Optional[str] = "",
89
+ workdir: Optional[str] = "",
90
+ artifact_path: Optional[str] = "",
91
+ watch: Optional[bool] = True,
92
+ schedule: Optional[
93
+ Union[str, mlrun.common.schemas.schedule.ScheduleCronTrigger]
94
+ ] = None,
95
+ hyperparams: Dict[str, list] = None,
96
+ hyper_param_options: Optional[mlrun.model.HyperParamOptions] = None,
97
+ verbose: Optional[bool] = None,
98
+ scrape_metrics: Optional[bool] = None,
99
+ local_code_path: Optional[str] = None,
100
+ auto_build: Optional[bool] = None,
101
+ param_file_secrets: Optional[Dict[str, str]] = None,
102
+ notifications: Optional[List[mlrun.model.Notification]] = None,
103
+ returns: Optional[List[Union[str, Dict[str, str]]]] = None,
104
+ ) -> "mlrun.run.RunObject":
105
+ """run the function from the server/client[local/remote]"""
106
+ pass
107
+
108
+ def _validate_runtime(
109
+ self,
110
+ runtime: "mlrun.runtimes.BaseRuntime",
111
+ run: "mlrun.run.RunObject",
112
+ ):
113
+ mlrun.utils.helpers.verify_dict_items_type(
114
+ "Inputs", run.spec.inputs, [str], [str]
115
+ )
116
+
117
+ if runtime.spec.mode and runtime.spec.mode not in run_modes:
118
+ raise ValueError(f'run mode can only be {",".join(run_modes)}')
119
+
120
+ self._validate_run_params(run.spec.parameters)
121
+ self._validate_output_path(runtime, run)
122
+
123
+ @staticmethod
124
+ def _validate_output_path(
125
+ runtime: "mlrun.runtimes.BaseRuntime",
126
+ run: "mlrun.run.RunObject",
127
+ ):
128
+ if not run.spec.output_path or "://" not in run.spec.output_path:
129
+ message = ""
130
+ if not os.path.isabs(run.spec.output_path):
131
+ message = (
132
+ "artifact/output path is not defined or is local and relative,"
133
+ " artifacts will not be visible in the UI"
134
+ )
135
+ if mlrun.runtimes.RuntimeKinds.requires_absolute_artifacts_path(
136
+ runtime.kind
137
+ ):
138
+ raise mlrun.errors.MLRunPreconditionFailedError(
139
+ "artifact path (`artifact_path`) must be absolute for remote tasks"
140
+ )
141
+ elif (
142
+ hasattr(runtime.spec, "volume_mounts")
143
+ and not runtime.spec.volume_mounts
144
+ ):
145
+ message = (
146
+ "artifact output path is local while no volume mount is specified. "
147
+ "artifacts would not be visible via UI."
148
+ )
149
+ if message:
150
+ logger.warning(message, output_path=run.spec.output_path)
151
+
152
+ def _validate_run_params(self, parameters: Dict[str, Any]):
153
+ for param_name, param_value in parameters.items():
154
+
155
+ if isinstance(param_value, dict):
156
+ # if the parameter is a dict, we might have some nested parameters,
157
+ # in this case we need to verify them as well recursively
158
+ self._validate_run_params(param_value)
159
+
160
+ # verify that integer parameters don't exceed a int64
161
+ if isinstance(param_value, int) and abs(param_value) >= 2**63:
162
+ raise mlrun.errors.MLRunInvalidArgumentError(
163
+ f"parameter {param_name} value {param_value} exceeds int64"
164
+ )
165
+
166
+ @staticmethod
167
+ def _create_run_object(task):
168
+ valid_task_types = (dict, mlrun.run.RunTemplate, mlrun.run.RunObject)
169
+
170
+ if not task:
171
+ # if task passed generate default RunObject
172
+ return mlrun.run.RunObject.from_dict(task)
173
+
174
+ # deepcopy user's task, so we don't modify / enrich the user's object
175
+ task = copy.deepcopy(task)
176
+
177
+ if isinstance(task, str):
178
+ task = ast.literal_eval(task)
179
+
180
+ if not isinstance(task, valid_task_types):
181
+ raise mlrun.errors.MLRunInvalidArgumentError(
182
+ f"Task is not a valid object, type={type(task)}, expected types={valid_task_types}"
183
+ )
184
+
185
+ if isinstance(task, mlrun.run.RunTemplate):
186
+ return mlrun.run.RunObject.from_template(task)
187
+ elif isinstance(task, dict):
188
+ return mlrun.run.RunObject.from_dict(task)
189
+
190
+ # task is already a RunObject
191
+ return task
192
+
193
+ def _enrich_run(
194
+ self,
195
+ runtime,
196
+ run,
197
+ handler=None,
198
+ project_name=None,
199
+ name=None,
200
+ params=None,
201
+ inputs=None,
202
+ returns=None,
203
+ hyperparams=None,
204
+ hyper_param_options=None,
205
+ verbose=None,
206
+ scrape_metrics=None,
207
+ out_path=None,
208
+ artifact_path=None,
209
+ workdir=None,
210
+ notifications: List[mlrun.model.Notification] = None,
211
+ ):
212
+ run.spec.handler = (
213
+ handler or run.spec.handler or runtime.spec.default_handler or ""
214
+ )
215
+ # callable handlers are valid for handler and dask runtimes,
216
+ # for other runtimes we need to convert the handler to a string
217
+ if run.spec.handler and runtime.kind not in ["handler", "dask"]:
218
+ run.spec.handler = run.spec.handler_name
219
+
220
+ def_name = runtime.metadata.name
221
+ if run.spec.handler_name:
222
+ short_name = run.spec.handler_name
223
+ for separator in ["#", "::", "."]:
224
+ # drop paths, module or class name from short name
225
+ if separator in short_name:
226
+ short_name = short_name.split(separator)[-1]
227
+ def_name += "-" + short_name
228
+
229
+ run.metadata.name = mlrun.utils.normalize_name(
230
+ name=name or run.metadata.name or def_name,
231
+ # if name or runspec.metadata.name are set then it means that is user defined name and we want to warn the
232
+ # user that the passed name needs to be set without underscore, if its not user defined but rather enriched
233
+ # from the handler(function) name then we replace the underscore without warning the user.
234
+ # most of the time handlers will have `_` in the handler name (python convention is to separate function
235
+ # words with `_`), therefore we don't want to be noisy when normalizing the run name
236
+ verbose=bool(name or run.metadata.name),
237
+ )
238
+ mlrun.utils.verify_field_regex(
239
+ "run.metadata.name", run.metadata.name, mlrun.utils.regex.run_name
240
+ )
241
+ run.metadata.project = (
242
+ project_name
243
+ or run.metadata.project
244
+ or runtime.metadata.project
245
+ or mlrun.mlconf.default_project
246
+ )
247
+ run.spec.parameters = params or run.spec.parameters
248
+ run.spec.inputs = inputs or run.spec.inputs
249
+ run.spec.returns = returns or run.spec.returns
250
+ run.spec.hyperparams = hyperparams or run.spec.hyperparams
251
+ run.spec.hyper_param_options = (
252
+ hyper_param_options or run.spec.hyper_param_options
253
+ )
254
+ run.spec.verbose = verbose or run.spec.verbose
255
+ if scrape_metrics is None:
256
+ if run.spec.scrape_metrics is None:
257
+ scrape_metrics = mlrun.mlconf.scrape_metrics
258
+ else:
259
+ scrape_metrics = run.spec.scrape_metrics
260
+ run.spec.scrape_metrics = scrape_metrics
261
+ run.spec.input_path = workdir or run.spec.input_path or runtime.spec.workdir
262
+ if runtime.spec.allow_empty_resources:
263
+ run.spec.allow_empty_resources = runtime.spec.allow_empty_resources
264
+
265
+ spec = run.spec
266
+ if spec.secret_sources:
267
+ runtime._secrets = mlrun.secrets.SecretsStore.from_list(spec.secret_sources)
268
+
269
+ # update run metadata (uid, labels) and store in DB
270
+ meta = run.metadata
271
+ meta.uid = meta.uid or uuid.uuid4().hex
272
+
273
+ run.spec.output_path = out_path or artifact_path or run.spec.output_path
274
+
275
+ if not run.spec.output_path:
276
+ if run.metadata.project:
277
+ if (
278
+ mlrun.pipeline_context.project
279
+ and run.metadata.project
280
+ == mlrun.pipeline_context.project.metadata.name
281
+ ):
282
+ run.spec.output_path = (
283
+ mlrun.pipeline_context.project.spec.artifact_path
284
+ or mlrun.pipeline_context.workflow_artifact_path
285
+ )
286
+
287
+ # get_db might be None when no rundb is set on runtime
288
+ if not run.spec.output_path and runtime._get_db():
289
+ try:
290
+ # not passing or loading the DB before the enrichment on purpose, because we want to enrich the
291
+ # spec first as get_db() depends on it
292
+ project = runtime._get_db().get_project(run.metadata.project)
293
+ # this is mainly for tests, so we won't need to mock get_project for so many tests
294
+ # in normal use cases if no project is found we will get an error
295
+ if project:
296
+ run.spec.output_path = project.spec.artifact_path
297
+ except mlrun.errors.MLRunNotFoundError:
298
+ logger.warning(
299
+ f"project {project_name} is not saved in DB yet, "
300
+ f"enriching output path with default artifact path: {mlrun.mlconf.artifact_path}"
301
+ )
302
+
303
+ if not run.spec.output_path:
304
+ run.spec.output_path = mlrun.mlconf.artifact_path
305
+
306
+ if run.spec.output_path:
307
+ run.spec.output_path = run.spec.output_path.replace("{{run.uid}}", meta.uid)
308
+ run.spec.output_path = mlrun.utils.helpers.fill_artifact_path_template(
309
+ run.spec.output_path, run.metadata.project
310
+ )
311
+
312
+ notifications = notifications or run.spec.notifications or []
313
+ mlrun.model.Notification.validate_notification_uniqueness(notifications)
314
+ for notification in notifications:
315
+ notification.validate_notification()
316
+
317
+ run.spec.notifications = notifications
318
+
319
+ return run
320
+
321
+ @staticmethod
322
+ def _run_has_valid_notifications(runobj) -> bool:
323
+ if not runobj.spec.notifications:
324
+ logger.debug(
325
+ "No notifications to push for run", run_uid=runobj.metadata.uid
326
+ )
327
+ return False
328
+
329
+ # TODO: add support for other notifications per run iteration
330
+ if runobj.metadata.iteration and runobj.metadata.iteration > 0:
331
+ logger.debug(
332
+ "Notifications per iteration are not supported, skipping",
333
+ run_uid=runobj.metadata.uid,
334
+ )
335
+ return False
336
+
337
+ return True
338
+
339
+ def _wrap_run_result(
340
+ self,
341
+ runtime: "mlrun.runtimes.BaseRuntime",
342
+ result: dict,
343
+ run: "mlrun.run.RunObject",
344
+ schedule: Optional[mlrun.common.schemas.ScheduleCronTrigger] = None,
345
+ err: Optional[Exception] = None,
346
+ ):
347
+ # if the purpose was to schedule (and not to run) nothing to wrap
348
+ if schedule:
349
+ return
350
+
351
+ if result and runtime.kfp and err is None:
352
+ mlrun.kfpops.write_kfpmeta(result)
353
+
354
+ self._log_track_results(runtime, result, run)
355
+
356
+ if result:
357
+ run = mlrun.run.RunObject.from_dict(result)
358
+ logger.info(
359
+ "Run execution finished",
360
+ status=run.status.state,
361
+ name=run.metadata.name,
362
+ )
363
+ if run.status.state in [
364
+ mlrun.runtimes.base.RunStates.error,
365
+ mlrun.runtimes.base.RunStates.aborted,
366
+ ]:
367
+ if runtime._is_remote and not runtime.is_child:
368
+ logger.error(
369
+ "Run did not finish successfully",
370
+ state=run.status.state,
371
+ status=run.status.to_dict(),
372
+ )
373
+ raise mlrun.runtimes.utils.RunError(run.error)
374
+ return run
375
+
376
+ return None
377
+
378
+ @staticmethod
379
+ def _refresh_function_metadata(runtime: "mlrun.runtimes.BaseRuntime"):
380
+ pass
381
+
382
+ @staticmethod
383
+ def prepare_image_for_deploy(runtime: "mlrun.runtimes.BaseRuntime"):
384
+ """Check if the runtime requires to build the image and updates the spec accordingly"""
385
+ pass
386
+
387
+ @staticmethod
388
+ @abc.abstractmethod
389
+ def enrich_runtime(
390
+ runtime: "mlrun.runtimes.base.BaseRuntime",
391
+ project_name: Optional[str] = "",
392
+ ):
393
+ pass
394
+
395
+ @staticmethod
396
+ @abc.abstractmethod
397
+ def _store_function(
398
+ runtime: "mlrun.runtimes.BaseRuntime", run: "mlrun.run.RunObject"
399
+ ):
400
+ pass
401
+
402
+ @staticmethod
403
+ def _log_track_results(
404
+ runtime: "mlrun.runtimes.BaseRuntime", result: dict, run: "mlrun.run.RunObject"
405
+ ):
406
+ pass
@@ -0,0 +1,159 @@
1
+ # Copyright 2023 MLRun Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import abc
15
+ import getpass
16
+ import os
17
+ from typing import Optional
18
+
19
+ import IPython
20
+
21
+ import mlrun.errors
22
+ import mlrun.launcher.base
23
+ import mlrun.lists
24
+ import mlrun.model
25
+ import mlrun.runtimes
26
+ from mlrun.utils import logger
27
+
28
+
29
+ class ClientBaseLauncher(mlrun.launcher.base.BaseLauncher, abc.ABC):
30
+ """
31
+ Abstract class for common code between client launchers
32
+ """
33
+
34
+ @staticmethod
35
+ def enrich_runtime(
36
+ runtime: "mlrun.runtimes.base.BaseRuntime", project_name: Optional[str] = ""
37
+ ):
38
+ runtime.try_auto_mount_based_on_config()
39
+ runtime._fill_credentials()
40
+
41
+ @staticmethod
42
+ def prepare_image_for_deploy(runtime: "mlrun.runtimes.BaseRuntime"):
43
+ """
44
+ Check if the runtime requires to build the image.
45
+ If build is needed, set the image as the base_image for the build.
46
+ If image is not given set the default one.
47
+ """
48
+ if runtime.kind in mlrun.runtimes.RuntimeKinds.nuclio_runtimes():
49
+ return
50
+
51
+ build = runtime.spec.build
52
+ require_build = (
53
+ build.commands
54
+ or build.requirements
55
+ or (build.source and not build.load_source_on_run)
56
+ )
57
+ image = runtime.spec.image
58
+ # we allow users to not set an image, in that case we'll use the default
59
+ if (
60
+ not image
61
+ and runtime.kind in mlrun.mlconf.function_defaults.image_by_kind.to_dict()
62
+ ):
63
+ image = mlrun.mlconf.function_defaults.image_by_kind.to_dict()[runtime.kind]
64
+
65
+ # TODO: need a better way to decide whether a function requires a build
66
+ if require_build and image and not runtime.spec.build.base_image:
67
+ # when the function require build use the image as the base_image for the build
68
+ runtime.spec.build.base_image = image
69
+ runtime.spec.image = ""
70
+
71
+ @staticmethod
72
+ def _store_function(
73
+ runtime: "mlrun.runtimes.BaseRuntime", run: "mlrun.run.RunObject"
74
+ ):
75
+ run.metadata.labels["kind"] = runtime.kind
76
+ if "owner" not in run.metadata.labels:
77
+ run.metadata.labels["owner"] = (
78
+ os.environ.get("V3IO_USERNAME") or getpass.getuser()
79
+ )
80
+ if run.spec.output_path:
81
+ run.spec.output_path = run.spec.output_path.replace(
82
+ "{{run.user}}", run.metadata.labels["owner"]
83
+ )
84
+ db = runtime._get_db()
85
+ if db and runtime.kind != "handler":
86
+ struct = runtime.to_dict()
87
+ hash_key = db.store_function(
88
+ struct, runtime.metadata.name, runtime.metadata.project, versioned=True
89
+ )
90
+ run.spec.function = runtime._function_uri(hash_key=hash_key)
91
+
92
+ @staticmethod
93
+ def _refresh_function_metadata(runtime: "mlrun.runtimes.BaseRuntime"):
94
+ try:
95
+ meta = runtime.metadata
96
+ db = runtime._get_db()
97
+ db_func = db.get_function(meta.name, meta.project, meta.tag)
98
+ if db_func and "status" in db_func:
99
+ runtime.status = db_func["status"]
100
+ if (
101
+ runtime.status.state
102
+ and runtime.status.state == "ready"
103
+ and runtime.kind
104
+ # We don't want to override the nuclio image here because the build happens in nuclio
105
+ # TODO: have a better way to check if nuclio function deploy started
106
+ and not hasattr(runtime.status, "nuclio_name")
107
+ ):
108
+ runtime.spec.image = mlrun.utils.get_in(
109
+ db_func, "spec.image", runtime.spec.image
110
+ )
111
+ except mlrun.errors.MLRunNotFoundError:
112
+ pass
113
+
114
+ @staticmethod
115
+ def _log_track_results(
116
+ runtime: "mlrun.runtimes.BaseRuntime", result: dict, run: "mlrun.run.RunObject"
117
+ ):
118
+ """
119
+ log commands to track results
120
+ in jupyter, displays a table widget with the result
121
+ else, logs CLI commands to track results and a link to the results in UI
122
+
123
+ :param: runtime: runtime object
124
+ :param result: run result dict
125
+ :param run: run object
126
+ """
127
+ uid = run.metadata.uid
128
+ project = run.metadata.project
129
+
130
+ # show ipython/jupyter result table widget
131
+ results_tbl = mlrun.lists.RunList()
132
+ if result:
133
+ results_tbl.append(result)
134
+ else:
135
+ logger.info("no returned result (job may still be in progress)")
136
+ results_tbl.append(run.to_dict())
137
+
138
+ if mlrun.utils.is_ipython and mlrun.config.config.ipython_widget:
139
+ results_tbl.show()
140
+ print()
141
+ ui_url = mlrun.utils.get_ui_url(project, uid)
142
+ if ui_url:
143
+ ui_url = f' or <a href="{ui_url}" target="_blank">click here</a> to open in UI'
144
+ IPython.display.display(
145
+ IPython.display.HTML(
146
+ f"<b> > to track results use the .show() or .logs() methods {ui_url}</b>"
147
+ )
148
+ )
149
+ elif not runtime.is_child:
150
+ # TODO: Log sdk commands to track results instead of CLI commands
151
+ project_flag = f"-p {project}" if project else ""
152
+ info_cmd = f"mlrun get run {uid} {project_flag}"
153
+ logs_cmd = f"mlrun logs {uid} {project_flag}"
154
+ logger.info(
155
+ "To track results use the CLI", info_cmd=info_cmd, logs_cmd=logs_cmd
156
+ )
157
+ ui_url = mlrun.utils.get_ui_url(project, uid)
158
+ if ui_url:
159
+ logger.info("Or click for UI", ui_url=ui_url)
@@ -0,0 +1,50 @@
1
+ # Copyright 2023 MLRun Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import mlrun.config
15
+ import mlrun.errors
16
+ import mlrun.launcher.base
17
+ import mlrun.launcher.local
18
+ import mlrun.launcher.remote
19
+
20
+
21
+ class LauncherFactory(object):
22
+ @staticmethod
23
+ def create_launcher(
24
+ is_remote: bool, local: bool = False
25
+ ) -> mlrun.launcher.base.BaseLauncher:
26
+ """
27
+ Creates the appropriate launcher for the specified run.
28
+ ServerSideLauncher - if running as API.
29
+ ClientRemoteLauncher - if the run is remote and local was not specified.
30
+ ClientLocalLauncher - if the run is not remote or local was specified.
31
+
32
+ :param is_remote: Whether the runtime requires remote execution.
33
+ :param local: Run the function locally vs on the Runtime/Cluster
34
+
35
+ :return: The appropriate launcher for the specified run.
36
+ """
37
+ if mlrun.config.is_running_as_api():
38
+ if local:
39
+ raise mlrun.errors.MLRunInternalServerError(
40
+ "Launch of local run inside the server is not allowed"
41
+ )
42
+
43
+ from mlrun.api.launcher import ServerSideLauncher
44
+
45
+ return ServerSideLauncher()
46
+
47
+ if is_remote and not local:
48
+ return mlrun.launcher.remote.ClientRemoteLauncher()
49
+
50
+ return mlrun.launcher.local.ClientLocalLauncher(local)