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/run.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.
@@ -11,32 +11,27 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- import functools
15
- import importlib
16
14
  import importlib.util as imputil
17
- import inspect
18
15
  import json
19
16
  import os
20
17
  import pathlib
21
- import re
22
18
  import socket
23
19
  import tempfile
24
20
  import time
25
21
  import uuid
26
22
  import warnings
27
23
  from base64 import b64decode
28
- from collections import OrderedDict
29
24
  from copy import deepcopy
30
25
  from os import environ, makedirs, path
31
26
  from pathlib import Path
32
- from typing import Callable, Dict, List, Optional, Tuple, Type, Union
27
+ from typing import Dict, List, Optional, Tuple, Union
33
28
 
34
29
  import nuclio
35
30
  import yaml
36
31
  from deprecated import deprecated
37
32
  from kfp import Client
38
33
 
39
- import mlrun.api.schemas
34
+ import mlrun.common.schemas
40
35
  import mlrun.errors
41
36
  import mlrun.utils.helpers
42
37
  from mlrun.kfpops import format_summary_from_kfp_run, show_kfp_run
@@ -44,6 +39,7 @@ from mlrun.kfpops import format_summary_from_kfp_run, show_kfp_run
44
39
  from .config import config as mlconf
45
40
  from .datastore import store_manager
46
41
  from .db import get_or_set_dburl, get_run_db
42
+ from .errors import MLRunInvalidArgumentError, MLRunTimeoutError
47
43
  from .execution import MLClientCtx
48
44
  from .model import BaseMetadata, RunObject, RunTemplate
49
45
  from .runtimes import (
@@ -57,12 +53,10 @@ from .runtimes import (
57
53
  RemoteSparkRuntime,
58
54
  RuntimeKinds,
59
55
  ServingRuntime,
60
- Spark2Runtime,
61
56
  Spark3Runtime,
62
57
  get_runtime_class,
63
58
  )
64
59
  from .runtimes.funcdoc import update_function_entry_points
65
- from .runtimes.package.context_handler import ArtifactType, ContextHandler
66
60
  from .runtimes.serving import serving_subkind
67
61
  from .runtimes.utils import add_code_metadata, global_context
68
62
  from .utils import (
@@ -112,6 +106,12 @@ class RunStatuses(object):
112
106
  ]
113
107
 
114
108
 
109
+ # TODO: remove in 1.6.0
110
+ @deprecated(
111
+ version="1.4.0",
112
+ reason="'run_local' will be removed in 1.6.0, use 'function.run(local=True)' instead",
113
+ category=FutureWarning,
114
+ )
115
115
  def run_local(
116
116
  task=None,
117
117
  command="",
@@ -127,6 +127,7 @@ def run_local(
127
127
  artifact_path: str = "",
128
128
  mode: str = None,
129
129
  allow_empty_resources=None,
130
+ notifications: List[mlrun.model.Notification] = None,
130
131
  returns: list = None,
131
132
  ):
132
133
  """Run a task on function/code (.py, .ipynb or .yaml) locally,
@@ -162,6 +163,7 @@ def run_local(
162
163
  (allows to have function which don't depend on having targets,
163
164
  e.g a function which accepts a feature vector uri and generate
164
165
  the offline vector e.g. parquet_ for it if it doesn't exist)
166
+ :param notifications: list of notifications to push when the run is completed
165
167
  :param returns: List of configurations for how to log the returning values from the handler's run (as artifacts or
166
168
  results). The list's length must be equal to the amount of returning objects. A configuration may
167
169
  be given as:
@@ -216,6 +218,7 @@ def run_local(
216
218
  inputs=inputs,
217
219
  returns=returns,
218
220
  artifact_path=artifact_path,
221
+ notifications=notifications,
219
222
  )
220
223
 
221
224
 
@@ -235,7 +238,7 @@ def function_to_module(code="", workdir=None, secrets=None, silent=False):
235
238
  mod.my_job(context, p1=1, p2='x')
236
239
  print(context.to_yaml())
237
240
 
238
- fn = mlrun.import_function('hub://open_archive')
241
+ fn = mlrun.import_function('hub://open-archive')
239
242
  mod = mlrun.function_to_module(fn)
240
243
  data = mlrun.run.get_dataitem("https://fpsignals-public.s3.amazonaws.com/catsndogs.tar.gz")
241
244
  context = mlrun.get_or_create_ctx('myfunc')
@@ -457,7 +460,7 @@ def import_function(url="", secrets=None, db="", project=None, new_name=None):
457
460
 
458
461
  examples::
459
462
 
460
- function = mlrun.import_function("hub://auto_trainer")
463
+ function = mlrun.import_function("hub://auto-trainer")
461
464
  function = mlrun.import_function("./func.yaml")
462
465
  function = mlrun.import_function("https://raw.githubusercontent.com/org/repo/func.yaml")
463
466
 
@@ -549,6 +552,7 @@ def new_function(
549
552
  source: str = None,
550
553
  requirements: Union[str, List[str]] = None,
551
554
  kfp=None,
555
+ requirements_file: str = "",
552
556
  ):
553
557
  """Create a new ML function from base properties
554
558
 
@@ -584,9 +588,13 @@ def new_function(
584
588
  (job, mpijob, ..) the handler can also be specified in the `.run()` command, when not specified
585
589
  the entire file will be executed (as main).
586
590
  for nuclio functions the handler is in the form of module:function, defaults to "main:handler"
587
- :param source: valid path to git, zip, or tar file, e.g. `git://github.com/mlrun/something.git`,
591
+ :param source: valid absolute path or URL to git, zip, or tar file, e.g.
592
+ `git://github.com/mlrun/something.git`,
588
593
  `http://some/url/file.zip`
589
- :param requirements: list of python packages or pip requirements file path, defaults to None
594
+ note path source must exist on the image or exist locally when run is local
595
+ (it is recommended to use 'function.spec.workdir' when source is a filepath instead)
596
+ :param requirements: a list of python packages, defaults to None
597
+ :param requirements_file: path to a python requirements file
590
598
  :param kfp: reserved, flag indicating running within kubeflow pipeline
591
599
 
592
600
  :return: function object
@@ -642,7 +650,7 @@ def new_function(
642
650
  runner.spec.build.source = source
643
651
  if handler:
644
652
  if kind == RuntimeKinds.serving:
645
- raise mlrun.errors.MLRunInvalidArgumentError(
653
+ raise MLRunInvalidArgumentError(
646
654
  "cannot set the handler for serving runtime"
647
655
  )
648
656
  elif kind in RuntimeKinds.nuclio_runtimes():
@@ -651,8 +659,13 @@ def new_function(
651
659
  runner.spec.default_handler = handler
652
660
 
653
661
  if requirements:
654
- runner.with_requirements(requirements)
655
- runner.verify_base_image()
662
+ runner.with_requirements(
663
+ requirements,
664
+ requirements_file=requirements_file,
665
+ prepare_image_for_deploy=False,
666
+ )
667
+
668
+ runner.prepare_image_for_deploy()
656
669
  return runner
657
670
 
658
671
 
@@ -692,6 +705,7 @@ def code_to_function(
692
705
  labels: Dict[str, str] = None,
693
706
  with_doc: bool = True,
694
707
  ignored_tags=None,
708
+ requirements_file: str = "",
695
709
  ) -> Union[
696
710
  MpiRuntimeV1Alpha1,
697
711
  MpiRuntimeV1,
@@ -700,7 +714,6 @@ def code_to_function(
700
714
  DaskCluster,
701
715
  KubejobRuntime,
702
716
  LocalRuntime,
703
- Spark2Runtime,
704
717
  Spark3Runtime,
705
718
  RemoteSparkRuntime,
706
719
  ]:
@@ -729,8 +742,7 @@ def code_to_function(
729
742
  - spark: run distributed Spark job using Spark Kubernetes Operator
730
743
  - remote-spark: run distributed Spark job on remote Spark service
731
744
 
732
- Learn more about function runtimes here:
733
- https://docs.mlrun.org/en/latest/runtimes/functions.html#function-runtimes
745
+ Learn more about {Kinds of function (runtimes)](../concepts/functions-overview.html).
734
746
 
735
747
  :param name: function name, typically best to use hyphen-case
736
748
  :param project: project used to namespace the function, defaults to 'default'
@@ -747,6 +759,8 @@ def code_to_function(
747
759
  defaults to True
748
760
  :param description: short function description, defaults to ''
749
761
  :param requirements: list of python packages or pip requirements file path, defaults to None
762
+ :param requirements: a list of python packages
763
+ :param requirements_file: path to a python requirements file
750
764
  :param categories: list of categories for mlrun Function Hub, defaults to None
751
765
  :param labels: immutable name/value pairs to tag the function with useful metadata, defaults to None
752
766
  :param with_doc: indicates whether to document the function parameters, defaults to True
@@ -793,12 +807,13 @@ def code_to_function(
793
807
 
794
808
  def update_common(fn, spec):
795
809
  fn.spec.image = image or get_in(spec, "spec.image", "")
810
+ fn.spec.filename = filename or get_in(spec, "spec.filename", "")
796
811
  fn.spec.build.base_image = get_in(spec, "spec.build.baseImage")
797
812
  fn.spec.build.commands = get_in(spec, "spec.build.commands")
798
813
  fn.spec.build.secret = get_in(spec, "spec.build.secret")
799
814
 
800
815
  if requirements:
801
- fn.with_requirements(requirements)
816
+ fn.with_requirements(requirements, requirements_file=requirements_file)
802
817
 
803
818
  if embed_code:
804
819
  fn.spec.build.functionSourceCode = get_in(
@@ -920,7 +935,7 @@ def code_to_function(
920
935
 
921
936
  build.image = get_in(spec, "spec.build.image")
922
937
  update_common(r, spec)
923
- r.verify_base_image()
938
+ r.prepare_image_for_deploy()
924
939
 
925
940
  if with_doc:
926
941
  update_function_entry_points(r, code)
@@ -1136,22 +1151,24 @@ def wait_for_pipeline_completion(
1136
1151
  if remote:
1137
1152
  mldb = mlrun.db.get_run_db()
1138
1153
 
1139
- def get_pipeline_if_completed(run_id, namespace=namespace):
1140
- resp = mldb.get_pipeline(run_id, namespace=namespace, project=project)
1141
- status = resp["run"]["status"]
1142
- show_kfp_run(resp, clear_output=True)
1143
- if status not in RunStatuses.stable_statuses():
1144
- # TODO: think of nicer liveness indication and make it re-usable
1145
- # log '.' each retry as a liveness indication
1146
- logger.debug(".")
1154
+ def _wait_for_pipeline_completion():
1155
+ pipeline = mldb.get_pipeline(run_id, namespace=namespace, project=project)
1156
+ pipeline_status = pipeline["run"]["status"]
1157
+ show_kfp_run(pipeline, clear_output=True)
1158
+ if pipeline_status not in RunStatuses.stable_statuses():
1159
+ logger.debug(
1160
+ "Waiting for pipeline completion",
1161
+ run_id=run_id,
1162
+ status=pipeline_status,
1163
+ )
1147
1164
  raise RuntimeError("pipeline run has not completed yet")
1148
1165
 
1149
- return resp
1166
+ return pipeline
1150
1167
 
1151
1168
  if mldb.kind != "http":
1152
1169
  raise ValueError(
1153
- "get pipeline require access to remote api-service"
1154
- ", please set the dbpath url"
1170
+ "get pipeline requires access to remote api-service"
1171
+ ", set the dbpath url"
1155
1172
  )
1156
1173
 
1157
1174
  resp = retry_until_successful(
@@ -1159,9 +1176,7 @@ def wait_for_pipeline_completion(
1159
1176
  timeout,
1160
1177
  logger,
1161
1178
  False,
1162
- get_pipeline_if_completed,
1163
- run_id,
1164
- namespace=namespace,
1179
+ _wait_for_pipeline_completion,
1165
1180
  )
1166
1181
  else:
1167
1182
  client = Client(namespace=namespace)
@@ -1194,8 +1209,8 @@ def get_pipeline(
1194
1209
  run_id,
1195
1210
  namespace=None,
1196
1211
  format_: Union[
1197
- str, mlrun.api.schemas.PipelinesFormat
1198
- ] = mlrun.api.schemas.PipelinesFormat.summary,
1212
+ str, mlrun.common.schemas.PipelinesFormat
1213
+ ] = mlrun.common.schemas.PipelinesFormat.summary,
1199
1214
  project: str = None,
1200
1215
  remote: bool = True,
1201
1216
  ):
@@ -1231,7 +1246,7 @@ def get_pipeline(
1231
1246
  resp = resp.to_dict()
1232
1247
  if (
1233
1248
  not format_
1234
- or format_ == mlrun.api.schemas.PipelinesFormat.summary.value
1249
+ or format_ == mlrun.common.schemas.PipelinesFormat.summary.value
1235
1250
  ):
1236
1251
  resp = format_summary_from_kfp_run(resp)
1237
1252
 
@@ -1247,7 +1262,7 @@ def list_pipelines(
1247
1262
  filter_="",
1248
1263
  namespace=None,
1249
1264
  project="*",
1250
- format_: mlrun.api.schemas.PipelinesFormat = mlrun.api.schemas.PipelinesFormat.metadata_only,
1265
+ format_: mlrun.common.schemas.PipelinesFormat = mlrun.common.schemas.PipelinesFormat.metadata_only,
1251
1266
  ) -> Tuple[int, Optional[int], List[dict]]:
1252
1267
  """List pipelines
1253
1268
 
@@ -1267,7 +1282,7 @@ def list_pipelines(
1267
1282
  :param format_: Control what will be returned (full/metadata_only/name_only)
1268
1283
  """
1269
1284
  if full:
1270
- format_ = mlrun.api.schemas.PipelinesFormat.full
1285
+ format_ = mlrun.common.schemas.PipelinesFormat.full
1271
1286
  run_db = mlrun.db.get_run_db()
1272
1287
  pipelines = run_db.list_pipelines(
1273
1288
  project, namespace, sort_by, page_token, filter_, format_, page_size
@@ -1333,291 +1348,7 @@ def wait_for_runs_completion(runs: list, sleep=3, timeout=0, silent=False):
1333
1348
  if timeout and total_time > timeout:
1334
1349
  if silent:
1335
1350
  break
1336
- raise mlrun.errors.MLRunTimeoutError(
1337
- "some runs did not reach terminal state on time"
1338
- )
1351
+ raise MLRunTimeoutError("some runs did not reach terminal state on time")
1339
1352
  runs = running
1340
1353
 
1341
1354
  return completed
1342
-
1343
-
1344
- def _parse_type_hint(type_hint: Union[Type, str]) -> Type:
1345
- """
1346
- Parse a given type hint from string to its actual hinted type class object. The string must be one of the following:
1347
-
1348
- * Python builtin type - one of ``tuple``, ``list``, ``set``, ``dict`` and ``bytearray``.
1349
- * Full module import path. An alias is not allowed (if ``import pandas as pd`` is used, the type hint cannot be
1350
- ``pd.DataFrame`` but ``pandas.DataFrame``).
1351
-
1352
- The type class on its own (like `DataFrame`) cannot be used as the scope of the decorator is not the same as the
1353
- handler itself, hence modules and objects that were imported in the handler's scope are not available. This is the
1354
- same reason import aliases cannot be used as well.
1355
-
1356
- If the provided type hint is not a string, it will simply be returned as is.
1357
-
1358
- **Notice**: This method should only run on client side as it dependent on user requirements.
1359
-
1360
- :param type_hint: The type hint to parse.
1361
-
1362
- :return: The hinted type.
1363
-
1364
- :raise MLRunInvalidArgumentError: In case the type hint is not following the 2 options mentioned above.
1365
- """
1366
- if not isinstance(type_hint, str):
1367
- return type_hint
1368
-
1369
- # TODO: Remove once Packager is implemented (it will support typing hints)
1370
- # If a typing hint is provided, we return a dummy Union type so the parser will skip the data item:
1371
- if type_hint.startswith("typing."):
1372
- return Union[int, str]
1373
-
1374
- # Validate the type hint is a valid module path:
1375
- if not bool(
1376
- re.fullmatch(r"([a-zA-Z_][a-zA-Z0-9_]*\.)*[a-zA-Z_][a-zA-Z0-9_]*", type_hint)
1377
- ):
1378
- raise mlrun.errors.MLRunInvalidArgumentError(
1379
- f"Invalid type hint. An input type hint must be a valid python class name or its module import path. For "
1380
- f"example: 'list', 'pandas.DataFrame', 'numpy.ndarray', 'sklearn.linear_model.LinearRegression'. Type hint "
1381
- f"given: '{type_hint}'."
1382
- )
1383
-
1384
- # Look for a builtin type (rest of the builtin types like `int`, `str`, `float` should be treated as results, hence
1385
- # not given as an input to an MLRun function, but as a parameter):
1386
- builtin_types = {
1387
- tuple.__name__: tuple,
1388
- list.__name__: list,
1389
- set.__name__: set,
1390
- dict.__name__: dict,
1391
- bytearray.__name__: bytearray,
1392
- }
1393
- if type_hint in builtin_types:
1394
- return builtin_types[type_hint]
1395
-
1396
- # If it's not a builtin, its should have a full module path:
1397
- if "." not in type_hint:
1398
- raise mlrun.errors.MLRunInvalidArgumentError(
1399
- f"MLRun tried to get the type hint '{type_hint}' but it can't as it is not a valid builtin Python type "
1400
- f"(one of {', '.join(list(builtin_types.keys()))}). Pay attention using only the type as string is not "
1401
- f"allowed as the handler's scope is different then MLRun's. To properly give a type hint, please specify "
1402
- f"the full module path. For example: do not use `DataFrame`, use `pandas.DataFrame`."
1403
- )
1404
-
1405
- # Import the module to receive the hinted type:
1406
- try:
1407
- # Get the module path and the type class (If we'll wish to support inner classes, the `rsplit` won't work):
1408
- module_path, type_hint = type_hint.rsplit(".", 1)
1409
- # Replace alias if needed (alias assumed to be imported already, hence we look in globals):
1410
- # For example:
1411
- # If in handler scope there was `import A.B.C as abc` and user gave a type hint "abc.Something" then:
1412
- # `module_path[0]` will be equal to "abc". Then, because it is an alias, it will appear in the globals, so we'll
1413
- # replace the alias with the full module name in order to import the module.
1414
- module_path = module_path.split(".")
1415
- if module_path[0] in globals():
1416
- module_path[0] = globals()[module_path[0]].__name__
1417
- module_path = ".".join(module_path)
1418
- # Import the module:
1419
- module = importlib.import_module(module_path)
1420
- # Get the class type from the module:
1421
- type_hint = getattr(module, type_hint)
1422
- except ModuleNotFoundError as module_not_found_error:
1423
- # May be raised from `importlib.import_module` in case the module does not exist.
1424
- raise mlrun.errors.MLRunInvalidArgumentError(
1425
- f"MLRun tried to get the type hint '{type_hint}' but the module '{module_path}' cannot be imported. "
1426
- f"Keep in mind that using alias in the module path (meaning: import module as alias) is not allowed. "
1427
- f"If the module path is correct, please make sure the module package is installed in the python "
1428
- f"interpreter."
1429
- ) from module_not_found_error
1430
- except AttributeError as attribute_error:
1431
- # May be raised from `getattr(module, type_hint)` in case the class type cannot be imported directly from the
1432
- # imported module.
1433
- raise mlrun.errors.MLRunInvalidArgumentError(
1434
- f"MLRun tried to get the type hint '{type_hint}' from the module '{module.__name__}' but it seems it "
1435
- f"doesn't exist. Make sure the class can be imported from the module with the exact module path you "
1436
- f"passed. Notice inner classes (a class inside of a class) are not supported."
1437
- ) from attribute_error
1438
-
1439
- return type_hint
1440
-
1441
-
1442
- def _parse_log_hint(
1443
- log_hint: Union[Dict[str, str], str, None]
1444
- ) -> Union[Dict[str, str], None]:
1445
- """
1446
- Parse a given log hint from string to a logging configuration dictionary. The string will be read as the artifact
1447
- key ('key' in the dictionary) and if the string have a single colon, the following structure is assumed:
1448
- "<artifact_key> : <artifact_type>". The artifact type must be on of the values of `ArtifactType`'s enum.
1449
-
1450
- If a logging configuration dictionary is received, it will be validated to have a key field and valid artifact type
1451
- value.
1452
-
1453
- None will be returned as None.
1454
-
1455
- :param log_hint: The log hint to parse.
1456
-
1457
- :return: The hinted logging configuration.
1458
-
1459
- :raise MLRunInvalidArgumentError: In case the log hint is not following the string structure, the artifact type is
1460
- not valid or the dictionary is missing the key field.
1461
- """
1462
- # Check for None value:
1463
- if log_hint is None:
1464
- return None
1465
-
1466
- # If the log hint was provided as a string, construct a dictionary out of it:
1467
- if isinstance(log_hint, str):
1468
- # Check if only key is given:
1469
- if ":" not in log_hint:
1470
- log_hint = {"key": log_hint}
1471
- # Check for valid "<key> : <artifact type>" pattern:
1472
- else:
1473
- if log_hint.count(":") > 1:
1474
- raise mlrun.errors.MLRunInvalidArgumentError(
1475
- f"Incorrect log hint pattern. Output keys can have only a single ':' in them to specify the "
1476
- f"desired artifact type the returned value will be logged as: '<artifact_key> : <artifact_type>', "
1477
- f"but given: {log_hint}"
1478
- )
1479
- # Split into key and type:
1480
- key, artifact_type = log_hint.replace(" ", "").split(":")
1481
- log_hint = {"key": key, "artifact_type": artifact_type}
1482
-
1483
- # TODO: Replace with constants keys once mlrun.package is implemented.
1484
- # Validate the log hint dictionary has the mandatory key:
1485
- if "key" not in log_hint:
1486
- raise mlrun.errors.MLRunInvalidArgumentError(
1487
- f"An output log hint dictionary must include the 'key' - the artifact key (it's name). The following "
1488
- f"log hint is missing the key: {log_hint}."
1489
- )
1490
-
1491
- # Validate the artifact type is valid:
1492
- if "artifact_type" in log_hint:
1493
- valid_artifact_types = [t.value for t in ArtifactType.__members__.values()]
1494
- if log_hint["artifact_type"] not in valid_artifact_types:
1495
- raise mlrun.errors.MLRunInvalidArgumentError(
1496
- f"The following artifact type '{log_hint['artifact_type']}' is not a valid `ArtifactType`. "
1497
- f"Please select one of the following: {','.join(valid_artifact_types)}"
1498
- )
1499
-
1500
- return log_hint
1501
-
1502
-
1503
- def handler(
1504
- labels: Dict[str, str] = None,
1505
- outputs: List[Union[str, Dict[str, str]]] = None,
1506
- inputs: Union[bool, Dict[str, Union[str, Type]]] = True,
1507
- ):
1508
- """
1509
- MLRun's handler is a decorator to wrap a function and enable setting labels, automatic `mlrun.DataItem` parsing and
1510
- outputs logging.
1511
-
1512
- :param labels: Labels to add to the run. Expecting a dictionary with the labels names as keys. Default: None.
1513
- :param outputs: Logging configurations for the function's returned values. Expecting a list of tuples and None
1514
- values:
1515
-
1516
- * str - A string in the format of '{key}:{artifact_type}'. If a string was given without ':' it will
1517
- indicate the key and the artifact type will be according to the returned value type. The artifact
1518
- types can be one of: "dataset", "directory", "file", "object", "plot" and "result".
1519
-
1520
- * Dict[str, str] - A dictionary of logging configuration. the key 'key' is mandatory for the logged
1521
- artifact key.
1522
-
1523
- * None - Do not log the output.
1524
-
1525
- The list length must be equal to the total amount of returned values from the function. Default is
1526
- None - meaning no outputs will be logged.
1527
-
1528
- :param inputs: Parsing configurations for the arguments passed as inputs via the `run` method of an MLRun function.
1529
- Can be passed as a boolean value or a dictionary:
1530
-
1531
- * True - Parse all found inputs to the assigned type hint in the function's signature. If there is no
1532
- type hint assigned, the value will remain an `mlrun.DataItem`.
1533
- * False - Do not parse inputs, leaving the inputs as `mlrun.DataItem`.
1534
- * Dict[str, Union[Type, str]] - A dictionary with argument name as key and the expected type to parse
1535
- the `mlrun.DataItem` to. The expected type can be a string as well, idicating the full module path.
1536
-
1537
- **Notice**: Type hints from the `typing` module (e.g. `typing.Optional`, `typing.Union`,
1538
- `typing.List` etc.) are currently not supported but will be in the future.
1539
-
1540
- Default: True.
1541
-
1542
- Example::
1543
-
1544
- import mlrun
1545
-
1546
- @mlrun.handler(outputs=["my_array", None, "my_multiplier"])
1547
- def my_handler(array: np.ndarray, m: int):
1548
- array = array * m
1549
- m += 1
1550
- return array, "I won't be logged", m
1551
-
1552
- >>> mlrun_function = mlrun.code_to_function("my_code.py", kind="job")
1553
- >>> run_object = mlrun_function.run(
1554
- ... handler="my_handler",
1555
- ... inputs={"array": "store://my_array_Artifact"},
1556
- ... params={"m": 2}
1557
- ... )
1558
- >>> run_object.outputs
1559
- {'my_multiplier': 3, 'my_array': 'store://...'}
1560
- """
1561
-
1562
- def decorator(func: Callable):
1563
- def wrapper(*args: tuple, **kwargs: dict):
1564
- nonlocal labels
1565
- nonlocal outputs
1566
- nonlocal inputs
1567
-
1568
- # Set default `inputs` - inspect the full signature and add the user's input on top of it:
1569
- if inputs:
1570
- # Get the available parameters type hints from the function's signature:
1571
- func_signature = inspect.signature(func)
1572
- parameters = OrderedDict(
1573
- {
1574
- parameter.name: parameter.annotation
1575
- for parameter in func_signature.parameters.values()
1576
- }
1577
- )
1578
- # If user input is given, add it on top of the collected defaults (from signature), strings type hints
1579
- # will be parsed to their actual types:
1580
- if isinstance(inputs, dict):
1581
- parameters.update(
1582
- {
1583
- parameter_name: _parse_type_hint(type_hint=type_hint)
1584
- for parameter_name, type_hint in inputs.items()
1585
- }
1586
- )
1587
- inputs = parameters
1588
-
1589
- # Create a context handler and look for a context:
1590
- context_handler = ContextHandler()
1591
- context_handler.look_for_context(args=args, kwargs=kwargs)
1592
-
1593
- # If an MLRun context is found, parse arguments pre-run (kwargs are parsed inplace):
1594
- if context_handler.is_context_available() and inputs:
1595
- args = context_handler.parse_inputs(
1596
- args=args, kwargs=kwargs, type_hints=inputs
1597
- )
1598
-
1599
- # Call the original function and get the returning values:
1600
- func_outputs = func(*args, **kwargs)
1601
-
1602
- # If an MLRun context is found, set the given labels and log the returning values to MLRun via the context:
1603
- if context_handler.is_context_available():
1604
- if labels:
1605
- context_handler.set_labels(labels=labels)
1606
- if outputs:
1607
- context_handler.log_outputs(
1608
- outputs=func_outputs
1609
- if isinstance(func_outputs, tuple)
1610
- else [func_outputs],
1611
- log_hints=[
1612
- _parse_log_hint(log_hint=log_hint) for log_hint in outputs
1613
- ],
1614
- )
1615
- return # Do not return any values as the returning values were logged to MLRun.
1616
- return func_outputs
1617
-
1618
- # Make sure to pass the wrapped function's signature (argument list, type hints and doc strings) to the wrapper:
1619
- wrapper = functools.wraps(func)(wrapper)
1620
-
1621
- return wrapper
1622
-
1623
- return decorator
@@ -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.
@@ -25,8 +25,6 @@ __all__ = [
25
25
  "RemoteSparkRuntime",
26
26
  ]
27
27
 
28
-
29
- from mlrun.runtimes.package.context_handler import ArtifactType, ContextHandler
30
28
  from mlrun.runtimes.utils import (
31
29
  resolve_mpijob_crd_version,
32
30
  resolve_spark_operator_version,
@@ -47,7 +45,7 @@ from .mpijob import ( # noqa
47
45
  from .nuclio import nuclio_init_hook
48
46
  from .remotesparkjob import RemoteSparkRuntime, RemoteSparkRuntimeHandler
49
47
  from .serving import ServingRuntime, new_v2_model_server
50
- from .sparkjob import Spark2Runtime, Spark3Runtime, SparkRuntimeHandler
48
+ from .sparkjob import Spark3Runtime, SparkRuntimeHandler
51
49
 
52
50
  # for legacy imports (MLModelServer moved from here to /serving)
53
51
  from ..serving import MLModelServer, new_v1_model_server # noqa isort: skip
@@ -260,11 +258,7 @@ def get_runtime_class(kind: str):
260
258
  return crd_version_to_runtime[mpijob_crd_version]
261
259
 
262
260
  if kind == RuntimeKinds.spark:
263
- spark_operator_version = resolve_spark_operator_version()
264
- if spark_operator_version == 2:
265
- return Spark2Runtime
266
- elif spark_operator_version == 3:
267
- return Spark3Runtime
261
+ return Spark3Runtime
268
262
 
269
263
  kind_runtime_map = {
270
264
  RuntimeKinds.remote: RemoteRuntime,