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
@@ -0,0 +1,298 @@
1
+ # Copyright 2023 Iguazio
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
+ #
15
+ import builtins
16
+ import importlib
17
+ import itertools
18
+ import re
19
+ import sys
20
+ import typing
21
+
22
+ from mlrun.errors import MLRunInvalidArgumentError
23
+ from mlrun.utils import logger
24
+
25
+
26
+ class TypeHintUtils:
27
+ """
28
+ Static class for utilities functions to process type hints.
29
+ """
30
+
31
+ @staticmethod
32
+ def is_typing_type(type_hint: type) -> bool:
33
+ """
34
+ Check whether a given type is a type hint from one of the modules `typing` and `types`. The function will return
35
+ True for generic type aliases also, meaning Python 3.9's new hinting feature that includes hinting like
36
+ `list[int]` instead of `typing.List[int]`.
37
+
38
+ :param type_hint: The type to check.
39
+
40
+ :return: True if the type hint from `typing` / `types` and False otherwise.
41
+ """
42
+ # A type hint should be one of the based typing classes, meaning it will have "typing" as its module. Some
43
+ # typing classes are considered a type (like `TypeVar`) so we check their type as well. The only case "types"
44
+ # will be a module is for generic aliases like `list[int]`.
45
+ return (type_hint.__module__ == "typing") or (
46
+ type(type_hint).__module__ in ["typing", "types"]
47
+ )
48
+
49
+ @staticmethod
50
+ def parse_type_hint(type_hint: typing.Union[type, str]) -> type:
51
+ """
52
+ Parse a given type hint from string to its actual hinted type class object. The string must be one of the
53
+ following:
54
+
55
+ * Python builtin type - for example: `tuple`, `list`, `set`, `dict` and `bytearray`.
56
+ * Full module import path. An alias (if `import pandas as pd is used`, the type hint cannot be `pd.DataFrame`)
57
+ is not allowed.
58
+
59
+ The type class on its own (like `DataFrame`) cannot be used as the scope of this function is not the same as the
60
+ handler itself, hence modules and objects that were imported in the handler's scope are not available. This is
61
+ the same reason import aliases cannot be used as well.
62
+
63
+ If the provided type hint is not a string, it will simply be returned as is.
64
+
65
+ :param type_hint: The type hint to parse.
66
+
67
+ :return: The hinted type.
68
+
69
+ :raise MLRunInvalidArgumentError: In case the type hint is not following the 2 options mentioned above.
70
+ """
71
+ if not isinstance(type_hint, str):
72
+ return type_hint
73
+
74
+ # Validate the type hint is a valid module path:
75
+ if not bool(
76
+ re.fullmatch(
77
+ r"([a-zA-Z_][a-zA-Z0-9_]*\.)*[a-zA-Z_][a-zA-Z0-9_]*", type_hint
78
+ )
79
+ ):
80
+ raise MLRunInvalidArgumentError(
81
+ f"Invalid type hint. An input type hint must be a valid python class name or its module import path. "
82
+ f"For example: 'list', 'pandas.DataFrame', 'numpy.ndarray', 'sklearn.linear_model.LinearRegression'. "
83
+ f"Type hint given: '{type_hint}'."
84
+ )
85
+
86
+ # Look for a builtin type (rest of the builtin types like `int`, `str`, `float` should be treated as results,
87
+ # hence not given as an input to an MLRun function, but as a parameter):
88
+ builtin_types = {
89
+ builtin_name: builtin_type
90
+ for builtin_name, builtin_type in builtins.__dict__.items()
91
+ if isinstance(builtin_type, type)
92
+ }
93
+ if type_hint in builtin_types:
94
+ return builtin_types[type_hint]
95
+
96
+ # If it's not a builtin, its should have a full module path, meaning at least one '.' to separate the module and
97
+ # the class. If it doesn't, we will try to get the class from the main module:
98
+ if "." not in type_hint:
99
+ logger.warn(
100
+ f"The type hint string given '{type_hint}' is not a `builtins` python type. MLRun will try to look for "
101
+ f"it in the `__main__` module instead."
102
+ )
103
+ try:
104
+ return TypeHintUtils.parse_type_hint(type_hint=f"__main__.{type_hint}")
105
+ except MLRunInvalidArgumentError:
106
+ raise MLRunInvalidArgumentError(
107
+ f"MLRun tried to get the type hint '{type_hint}' but it can't as it is not a valid builtin Python "
108
+ f"type (one of `list`, `dict`, `str`, `int`, etc.) nor a locally declared type (from the "
109
+ f"`__main__` module). Pay attention using only the type as string is not allowed as the handler's "
110
+ f"scope is different than MLRun's. To properly give a type hint as string, please specify the full "
111
+ f"module path without aliases. For example: do not use `DataFrame` or `pd.DataFrame`, use "
112
+ f"`pandas.DataFrame`."
113
+ )
114
+
115
+ # Import the module to receive the hinted type:
116
+ try:
117
+ # Get the module path and the type class (If we'll wish to support inner classes, the `rsplit` won't work):
118
+ module_path, type_hint = type_hint.rsplit(".", 1)
119
+ # Replace alias if needed (alias assumed to be imported already, hence we look in globals):
120
+ # For example:
121
+ # If in handler scope there was `import A.B.C as abc` and user gave a type hint "abc.Something" then:
122
+ # `module_path[0]` will be equal to "abc". Then, because it is an alias, it will appear in the globals, so
123
+ # we'll replace the alias with the full module name in order to import the module.
124
+ module_path = module_path.split(".")
125
+ if module_path[0] in globals():
126
+ module_path[0] = globals()[module_path[0]].__name__
127
+ module_path = ".".join(module_path)
128
+ # Import the module:
129
+ module = importlib.import_module(module_path)
130
+ # Get the class type from the module:
131
+ type_hint = getattr(module, type_hint)
132
+ except ModuleNotFoundError as module_not_found_error:
133
+ # May be raised from `importlib.import_module` in case the module does not exist.
134
+ raise MLRunInvalidArgumentError(
135
+ f"MLRun tried to get the type hint '{type_hint}' but the module '{module_path}' cannot be imported. "
136
+ f"Keep in mind that using alias in the module path (meaning: import module as alias) is not allowed. "
137
+ f"If the module path is correct, please make sure the module package is installed in the python "
138
+ f"interpreter."
139
+ ) from module_not_found_error
140
+ except AttributeError as attribute_error:
141
+ # May be raised from `getattr(module, type_hint)` in case the class type cannot be imported directly from
142
+ # the imported module.
143
+ raise MLRunInvalidArgumentError(
144
+ f"MLRun tried to get the type hint '{type_hint}' from the module '{module.__name__}' but it seems it "
145
+ f"doesn't exist. Make sure the class can be imported from the module with the exact module path you "
146
+ f"passed. Notice inner classes (a class inside of a class) are not supported."
147
+ ) from attribute_error
148
+
149
+ return type_hint
150
+
151
+ @staticmethod
152
+ def is_matching(
153
+ object_type: type,
154
+ type_hint: typing.Union[type, typing.Set[type]],
155
+ include_subclasses: bool = True,
156
+ reduce_type_hint: bool = True,
157
+ ) -> bool:
158
+ """
159
+ Check if the given object type match the given hint.
160
+
161
+ :param object_type: The object type to match with the type hint.
162
+ :param type_hint: The hint to match with. Can be given as a set resulted from a reduced hint.
163
+ :param include_subclasses: Whether to mark a subclass as valid match. Default to True.
164
+ :param reduce_type_hint: Whether to reduce the type hint to match with its reduced hints.
165
+
166
+ :return: True if the object type match the type hint and False otherwise.
167
+ """
168
+ # Wrap in a set if provided a single type hint:
169
+ type_hint = {type_hint} if not isinstance(type_hint, set) else type_hint
170
+
171
+ # Try to match the object type to one of the hints:
172
+ while len(type_hint) > 0:
173
+ for hint in type_hint:
174
+ # Subclass check can be made only on actual object types (not typing module types):
175
+ if (
176
+ not TypeHintUtils.is_typing_type(type_hint=object_type)
177
+ and not TypeHintUtils.is_typing_type(type_hint=hint)
178
+ and include_subclasses
179
+ and issubclass(object_type, hint)
180
+ ):
181
+ return True
182
+ if object_type == hint:
183
+ return True
184
+ # See if needed to reduce, if not end on first iteration:
185
+ if not reduce_type_hint:
186
+ break
187
+ type_hint = TypeHintUtils.reduce_type_hint(type_hint=type_hint)
188
+ return False
189
+
190
+ @staticmethod
191
+ def reduce_type_hint(
192
+ type_hint: typing.Union[type, typing.Set[type]],
193
+ ) -> typing.Set[type]:
194
+ """
195
+ Reduce a type hint (or a set of type hints) using the `_reduce_type_hint` function.
196
+
197
+ :param type_hint: The type hint to reduce.
198
+
199
+ :return: The reduced type hints set or an empty set if the type hint could not be reduced.
200
+ """
201
+ # Wrap in a set if provided a single type hint:
202
+ type_hints = {type_hint} if not isinstance(type_hint, set) else type_hint
203
+
204
+ # Iterate over the type hints and reduce each one:
205
+ return set(
206
+ itertools.chain(
207
+ *[
208
+ TypeHintUtils._reduce_type_hint(type_hint=type_hint)
209
+ for type_hint in type_hints
210
+ ]
211
+ )
212
+ )
213
+
214
+ @staticmethod
215
+ def _reduce_type_hint(type_hint: type) -> typing.List[type]:
216
+ """
217
+ Reduce a type hint. If the type hint is a `typing` module, it will be reduced to its original hinted types. For
218
+ example: `typing.Union[int, float, typing.List[int]]` will return `[int, float, List[int]]` and
219
+ `typing.List[int]` will return `[list]`. Regular type hints - Python object types cannot be reduced as they are
220
+ already a core type.
221
+
222
+ If a type hint cannot be reduced, an empty list will be returned.
223
+
224
+ :param type_hint: The type hint to reduce.
225
+
226
+ :return: The reduced type hint as list of hinted types or an empty list if the type hint could not be reduced.
227
+ """
228
+ # TODO: Remove when we'll no longer support Python 3.7:
229
+ if sys.version_info[1] < 8:
230
+ return []
231
+
232
+ # If it's not a typing type (meaning it's an actual object type) then we can't reduce it further:
233
+ if not TypeHintUtils.is_typing_type(type_hint=type_hint):
234
+ return []
235
+
236
+ # If it's a type var, take its constraints (e.g. A = TypeVar("A", int, str) meaning an object of type A should
237
+ # be an integer or a string). If it doesn't have constraints, return an empty list:
238
+ if isinstance(type_hint, typing.TypeVar):
239
+ if len(type_hint.__constraints__) == 0:
240
+ return []
241
+ return list(type_hint.__constraints__)
242
+
243
+ # If it's a forward reference, we will try to import the reference:
244
+ if isinstance(type_hint, typing.ForwardRef):
245
+ try:
246
+ # ForwardRef is initialized with the string type it represents and optionally a module path, so we
247
+ # construct a full module path and try to parse it:
248
+ arg = type_hint.__forward_arg__
249
+ if type_hint.__forward_module__:
250
+ arg = f"{type_hint.__forward_module__}.{arg}"
251
+ return [TypeHintUtils.parse_type_hint(type_hint=arg)]
252
+ except MLRunInvalidArgumentError: # May be raised from `TypeHintUtils.parse_type_hint`
253
+ logger.warn(
254
+ f"Could not reduce the type hint '{type_hint}' as it is a forward reference to a class without "
255
+ f"it's full module path. To enable importing forward references, please provide the full module "
256
+ f"path to them. For example: use `ForwardRef('pandas.DataFrame')` instead of "
257
+ f"`ForwardRef('DataFrame')`."
258
+ )
259
+ return []
260
+
261
+ # Get the origin of the typing type. An origin is the subscripted typing type (origin of Union[str, int] is
262
+ # Union). The origin can be one of Callable, Tuple, Union, Literal, Final, ClassVar, Annotated or the actual
263
+ # type alias (e.g. origin of List[int] is list):
264
+ origin = typing.get_origin(type_hint)
265
+
266
+ # If the typing type has no origin (e.g. None is returned), we cannot reduce it, so we return an empty list:
267
+ if origin is None:
268
+ return []
269
+
270
+ # If the origin is a type of one of `builtins`, `contextlib` or `collections` (for example: List's origin is
271
+ # list) then we can be sure there is nothing to reduce as it's a regular type:
272
+ if not TypeHintUtils.is_typing_type(type_hint=origin):
273
+ return [origin]
274
+
275
+ # Get the type's subscriptions - arguments, in order to reduce it to them (we know for sure there are arguments,
276
+ # otherwise origin would have been None):
277
+ args = typing.get_args(type_hint)
278
+
279
+ # Return the reduced type as its arguments according to the origin:
280
+ if origin is typing.Callable:
281
+ # A callable cannot be reduced to its arguments, so we'll return the origin - Callable:
282
+ return [typing.Callable]
283
+ if origin is typing.Literal:
284
+ # Literal arguments are not types, but values. So we'll take the types of the values as the reduced type:
285
+ return [type(arg) for arg in args]
286
+ if origin is typing.Union:
287
+ # A union is reduced to its arguments:
288
+ return list(args)
289
+ if origin is typing.Annotated:
290
+ # Annotated is used to describe (add metadata to) a type, so we take the first argument (the type the
291
+ # metadata is being added to):
292
+ return [args[0]]
293
+ if origin is typing.Final or origin is typing.ClassVar:
294
+ # Both Final and ClassVar takes only one argument - the type:
295
+ return [args[0]]
296
+
297
+ # For Generic types we return an empty list:
298
+ return []
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -326,7 +326,6 @@ def v3io_to_vol(name, remote="~/", access_key="", user="", secret=None):
326
326
  if secret:
327
327
  secret = {"name": secret}
328
328
 
329
- # vol = client.V1Volume(name=name, flex_volume=client.V1FlexVolumeSource('v3io/fuse', options=opts))
330
329
  vol = {
331
330
  "flexVolume": client.V1FlexVolumeSource(
332
331
  "v3io/fuse", options=opts, secret_ref=secret
@@ -403,6 +402,37 @@ class OutputStream:
403
402
  )
404
403
 
405
404
 
405
+ class HTTPOutputStream:
406
+ """HTTP output source that usually used for CE mode and debugging process"""
407
+
408
+ def __init__(self, stream_path: str):
409
+ self._stream_path = stream_path
410
+
411
+ def push(self, data):
412
+ def dump_record(rec):
413
+ if isinstance(rec, bytes):
414
+ return rec
415
+
416
+ if not isinstance(rec, str):
417
+ rec = dict_to_json(rec)
418
+
419
+ return rec.encode("UTF-8")
420
+
421
+ if not isinstance(data, list):
422
+ data = [data]
423
+
424
+ for record in data:
425
+
426
+ # Convert the new record to the required format
427
+ serialized_record = dump_record(record)
428
+ response = requests.post(self._stream_path, data=serialized_record)
429
+ if not response:
430
+ raise mlrun.errors.MLRunInvalidArgumentError(
431
+ f"API call failed push a new record through {self._stream_path}"
432
+ f"status {response.status_code}: {response.reason}"
433
+ )
434
+
435
+
406
436
  class KafkaOutputStream:
407
437
  def __init__(
408
438
  self,
@@ -650,6 +680,8 @@ def parse_path(url, suffix="/"):
650
680
  )
651
681
  endpoint = f"{prefix}://{parsed_url.netloc}"
652
682
  else:
683
+ # no netloc is mainly when using v3io (v3io:///) and expecting the url to be resolved automatically from env or
684
+ # config
653
685
  endpoint = None
654
686
  return endpoint, parsed_url.path.strip("/") + suffix
655
687
 
mlrun/platforms/other.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.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -70,8 +70,9 @@ def run_function(
70
70
  selector: str = None,
71
71
  project_object=None,
72
72
  auto_build: bool = None,
73
- schedule: Union[str, mlrun.api.schemas.ScheduleCronTrigger] = None,
73
+ schedule: Union[str, mlrun.common.schemas.ScheduleCronTrigger] = None,
74
74
  artifact_path: str = None,
75
+ notifications: List[mlrun.model.Notification] = None,
75
76
  returns: Optional[List[Union[str, Dict[str, str]]]] = None,
76
77
  ) -> Union[mlrun.model.RunObject, kfp.dsl.ContainerOp]:
77
78
  """Run a local or remote task as part of a local/kubeflow pipeline
@@ -91,16 +92,16 @@ def run_function(
91
92
  LABELS = "is_error"
92
93
  MODEL_CLASS = "sklearn.ensemble.RandomForestClassifier"
93
94
  DATA_PATH = "s3://bigdata/data.parquet"
94
- function = mlrun.import_function("hub://auto_trainer")
95
+ function = mlrun.import_function("hub://auto-trainer")
95
96
  run1 = run_function(function, params={"label_columns": LABELS, "model_class": MODEL_CLASS},
96
97
  inputs={"dataset": DATA_PATH})
97
98
 
98
99
  example (use with project)::
99
100
 
100
- # create a project with two functions (local and from marketplace)
101
+ # create a project with two functions (local and from hub)
101
102
  project = mlrun.new_project(project_name, "./proj)
102
103
  project.set_function("mycode.py", "myfunc", image="mlrun/mlrun")
103
- project.set_function("hub://auto_trainer", "train")
104
+ project.set_function("hub://auto-trainer", "train")
104
105
 
105
106
  # run functions (refer to them by name)
106
107
  run1 = run_function("myfunc", params={"x": 7})
@@ -111,7 +112,7 @@ def run_function(
111
112
 
112
113
  @dsl.pipeline(name="test pipeline", description="test")
113
114
  def my_pipe(url=""):
114
- run1 = run_function("loaddata", params={"url": url})
115
+ run1 = run_function("loaddata", params={"url": url}, outputs=["data"])
115
116
  run2 = run_function("train", params={"label_columns": LABELS, "model_class": MODEL_CLASS},
116
117
  inputs={"dataset": run1.outputs["data"]})
117
118
 
@@ -137,12 +138,13 @@ def run_function(
137
138
  :param verbose: add verbose prints/logs
138
139
  :param project_object: override the project object to use, will default to the project set in the runtime context.
139
140
  :param auto_build: when set to True and the function require build it will be built on the first
140
- function run, use only if you dont plan on changing the build config between runs
141
+ function run, use only if you do not plan on changing the build config between runs
141
142
  :param schedule: ScheduleCronTrigger class instance or a standard crontab expression string
142
143
  (which will be converted to the class using its `from_crontab` constructor),
143
144
  see this link for help:
144
145
  https://apscheduler.readthedocs.io/en/3.x/modules/triggers/cron.html#module-apscheduler.triggers.cron
145
146
  :param artifact_path: path to store artifacts, when running in a workflow this will be set automatically
147
+ :param notifications: list of notifications to push when the run is completed
146
148
  :param returns: List of log hints - configurations for how to log the returning values from the handler's
147
149
  run (as artifacts or results). The list's length must be equal to the amount of returning
148
150
  objects. A log hint may be given as:
@@ -198,6 +200,7 @@ def run_function(
198
200
  or (project.artifact_path if project else None),
199
201
  auto_build=auto_build,
200
202
  schedule=schedule,
203
+ notifications=notifications,
201
204
  )
202
205
  if run_result:
203
206
  run_result._notified = False
@@ -233,6 +236,7 @@ def build_function(
233
236
  commands: list = None,
234
237
  secret_name=None,
235
238
  requirements: Union[str, List[str]] = None,
239
+ requirements_file: str = None,
236
240
  mlrun_version_specifier=None,
237
241
  builder_env: dict = None,
238
242
  project_object=None,
@@ -247,7 +251,8 @@ def build_function(
247
251
  :param base_image: base image name/path (commands and source code will be added to it)
248
252
  :param commands: list of docker build (RUN) commands e.g. ['pip install pandas']
249
253
  :param secret_name: k8s secret for accessing the docker registry
250
- :param requirements: list of python packages or pip requirements file path, defaults to None
254
+ :param requirements: list of python packages, defaults to None
255
+ :param requirements_file: pip requirements file path, defaults to None
251
256
  :param mlrun_version_specifier: which mlrun package version to include (if not current)
252
257
  :param builder_env: Kaniko builder pod env vars dict (for config/credentials)
253
258
  e.g. builder_env={"GIT_TOKEN": token}, does not work yet in KFP
@@ -266,7 +271,7 @@ def build_function(
266
271
  if overwrite_build_params:
267
272
  function.spec.build.commands = None
268
273
  if requirements:
269
- function.with_requirements(requirements)
274
+ function.with_requirements(requirements, requirements_file)
270
275
  if commands:
271
276
  function.with_commands(commands)
272
277
  return function.deploy_step(
@@ -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.
@@ -27,7 +27,7 @@ from kfp import dsl
27
27
  from kfp.compiler import compiler
28
28
 
29
29
  import mlrun
30
- import mlrun.api.schemas
30
+ import mlrun.common.schemas
31
31
  import mlrun.utils.notifications
32
32
  from mlrun.errors import err_to_str
33
33
  from mlrun.utils import (
@@ -79,7 +79,7 @@ class WorkflowSpec(mlrun.model.ModelObj):
79
79
  # TODO: deprecated, remove in 1.5.0
80
80
  ttl=None,
81
81
  args_schema: dict = None,
82
- schedule: typing.Union[str, mlrun.api.schemas.ScheduleCronTrigger] = None,
82
+ schedule: typing.Union[str, mlrun.common.schemas.ScheduleCronTrigger] = None,
83
83
  cleanup_ttl: int = None,
84
84
  ):
85
85
  if ttl:
@@ -116,7 +116,13 @@ class WorkflowSpec(mlrun.model.ModelObj):
116
116
  self._tmp_path = workflow_path = workflow_fh.name
117
117
  else:
118
118
  workflow_path = self.path or ""
119
- if context and not workflow_path.startswith("/"):
119
+ if (
120
+ context
121
+ and not workflow_path.startswith("/")
122
+ # since the user may provide a path the includes the context,
123
+ # we need to make sure we don't add it twice
124
+ and not workflow_path.startswith(context)
125
+ ):
120
126
  workflow_path = os.path.join(context, workflow_path)
121
127
  return workflow_path
122
128
 
@@ -279,7 +285,7 @@ def _enrich_kfp_pod_security_context(kfp_pod_template, function):
279
285
  if (
280
286
  mlrun.runtimes.RuntimeKinds.is_local_runtime(function.kind)
281
287
  or mlrun.mlconf.function.spec.security_context.enrichment_mode
282
- == mlrun.api.schemas.SecurityContextEnrichmentModes.disabled.value
288
+ == mlrun.common.schemas.SecurityContextEnrichmentModes.disabled.value
283
289
  ):
284
290
  return
285
291
 
@@ -405,7 +411,7 @@ def enrich_function_object(
405
411
  f.spec.build.source = project.spec.source
406
412
  f.spec.build.load_source_on_run = project.spec.load_source_on_run
407
413
  f.spec.workdir = project.spec.workdir or project.spec.subpath
408
- f.verify_base_image()
414
+ f.prepare_image_for_deploy()
409
415
 
410
416
  if project.spec.default_requirements:
411
417
  f.with_requirements(project.spec.default_requirements)
@@ -705,7 +711,7 @@ class _LocalRunner(_PipelineRunner):
705
711
  trace = traceback.format_exc()
706
712
  logger.error(trace)
707
713
  project.notifiers.push(
708
- f"Workflow {workflow_id} run failed!, error: {e}\n{trace}", "error"
714
+ f":x: Workflow {workflow_id} run failed!, error: {e}\n{trace}", "error"
709
715
  )
710
716
  state = mlrun.run.RunStatuses.failed
711
717
  mlrun.run.wait_for_runs_completion(pipeline_context.runs_map.values())
@@ -755,6 +761,7 @@ class _RemoteRunner(_PipelineRunner):
755
761
  artifact_path: str,
756
762
  workflow_handler: str,
757
763
  namespace: str,
764
+ subpath: str,
758
765
  ) -> typing.Tuple[mlrun.runtimes.RemoteRuntime, "mlrun.RunObject"]:
759
766
  """
760
767
  Helper function for creating the runspec of the load and run function.
@@ -767,6 +774,7 @@ class _RemoteRunner(_PipelineRunner):
767
774
  :param artifact_path: path to store artifacts
768
775
  :param workflow_handler: workflow function handler (for running workflow function directly)
769
776
  :param namespace: kubernetes namespace if other than default
777
+ :param subpath: project subpath (within the archive)
770
778
  :return:
771
779
  """
772
780
  # Creating the load project and workflow running function:
@@ -792,6 +800,7 @@ class _RemoteRunner(_PipelineRunner):
792
800
  "engine": workflow_spec.engine,
793
801
  "local": workflow_spec.run_local,
794
802
  "schedule": workflow_spec.schedule,
803
+ "subpath": subpath,
795
804
  },
796
805
  handler="mlrun.projects.load_and_run",
797
806
  ),
@@ -826,8 +835,11 @@ class _RemoteRunner(_PipelineRunner):
826
835
  )
827
836
  if "://" not in current_source:
828
837
  raise mlrun.errors.MLRunInvalidArgumentError(
829
- f"remote workflows can only be performed by a project with remote source,"
830
- f" the given source '{current_source}' is not remote"
838
+ f"Remote workflows can only be performed by a project with remote source (e.g git:// or http://),"
839
+ f" but the specified source '{current_source}' is not remote. "
840
+ f"Either put your code in Git, or archive it and then set a source to it."
841
+ f" For more details, read"
842
+ f" https://docs.mlrun.org/en/latest/concepts/scheduled-jobs.html#scheduling-a-workflow"
831
843
  )
832
844
 
833
845
  # Creating the load project and workflow running function:
@@ -840,6 +852,7 @@ class _RemoteRunner(_PipelineRunner):
840
852
  artifact_path=artifact_path,
841
853
  workflow_handler=workflow_handler,
842
854
  namespace=namespace,
855
+ subpath=project.spec.subpath,
843
856
  )
844
857
 
845
858
  # The returned engine for this runner is the engine of the workflow.
@@ -874,7 +887,8 @@ class _RemoteRunner(_PipelineRunner):
874
887
  trace = traceback.format_exc()
875
888
  logger.error(trace)
876
889
  project.notifiers.push(
877
- f"Workflow {workflow_name} run failed!, error: {e}\n{trace}", "error"
890
+ f":x: Workflow {workflow_name} run failed!, error: {e}\n{trace}",
891
+ "error",
878
892
  )
879
893
  state = mlrun.run.RunStatuses.failed
880
894
  return _PipelineRunStatus(
@@ -928,7 +942,11 @@ def create_pipeline(project, pipeline, functions, secrets=None, handler=None):
928
942
  if not handler and hasattr(mod, "pipeline"):
929
943
  handler = "pipeline"
930
944
  if not handler or not hasattr(mod, handler):
931
- raise ValueError(f"pipeline function ({handler or 'pipeline'}) not found")
945
+ raise ValueError(
946
+ f"'workflow_handler' is not defined. "
947
+ f"Either provide it as set_workflow argument, or include a function named"
948
+ f" '{handler or 'pipeline'}' in your workflow .py file."
949
+ )
932
950
 
933
951
  return getattr(mod, handler)
934
952
 
@@ -967,7 +985,7 @@ def load_and_run(
967
985
  ttl: int = None,
968
986
  engine: str = None,
969
987
  local: bool = None,
970
- schedule: typing.Union[str, mlrun.api.schemas.ScheduleCronTrigger] = None,
988
+ schedule: typing.Union[str, mlrun.common.schemas.ScheduleCronTrigger] = None,
971
989
  cleanup_ttl: int = None,
972
990
  ):
973
991
  """
@@ -1033,7 +1051,7 @@ def load_and_run(
1033
1051
  try:
1034
1052
  notification_pusher.push(
1035
1053
  message=message,
1036
- severity=mlrun.utils.notifications.NotificationSeverity.ERROR,
1054
+ severity=mlrun.common.schemas.NotificationSeverity.ERROR,
1037
1055
  )
1038
1056
 
1039
1057
  except Exception as exc: