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
@@ -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.
@@ -13,97 +13,16 @@
13
13
  # limitations under the License.
14
14
  #
15
15
 
16
- import enum
17
- import hashlib
18
- from dataclasses import dataclass
19
- from typing import Optional, Union
16
+ import json
17
+ import warnings
18
+ from typing import Union
20
19
 
21
20
  import mlrun
21
+ import mlrun.common.model_monitoring as model_monitoring_constants
22
22
  import mlrun.model
23
- import mlrun.model_monitoring.constants as model_monitoring_constants
24
23
  import mlrun.platforms.iguazio
25
- import mlrun.utils
26
- from mlrun.api.schemas.schedule import ScheduleCronTrigger
27
-
28
-
29
- @dataclass
30
- class FunctionURI:
31
- project: str
32
- function: str
33
- tag: Optional[str] = None
34
- hash_key: Optional[str] = None
35
-
36
- @classmethod
37
- def from_string(cls, function_uri):
38
- project, uri, tag, hash_key = mlrun.utils.parse_versioned_object_uri(
39
- function_uri
40
- )
41
- return cls(
42
- project=project,
43
- function=uri,
44
- tag=tag or None,
45
- hash_key=hash_key or None,
46
- )
47
-
48
-
49
- @dataclass
50
- class VersionedModel:
51
- model: str
52
- version: Optional[str]
53
-
54
- @classmethod
55
- def from_string(cls, model):
56
- try:
57
- model, version = model.split(":")
58
- except ValueError:
59
- model, version = model, None
60
-
61
- return cls(model, version)
62
-
63
-
64
- @dataclass
65
- class EndpointUID:
66
- project: str
67
- function: str
68
- function_tag: str
69
- function_hash_key: str
70
- model: str
71
- model_version: str
72
- uid: Optional[str] = None
73
-
74
- def __post_init__(self):
75
- function_ref = (
76
- f"{self.function}_{self.function_tag or self.function_hash_key or 'N/A'}"
77
- )
78
- versioned_model = f"{self.model}_{self.model_version or 'N/A'}"
79
- unique_string = f"{self.project}_{function_ref}_{versioned_model}"
80
- self.uid = hashlib.sha1(unique_string.encode("utf-8")).hexdigest()
81
-
82
- def __str__(self):
83
- return self.uid
84
-
85
-
86
- def create_model_endpoint_id(function_uri: str, versioned_model: str):
87
- function_uri = FunctionURI.from_string(function_uri)
88
- versioned_model = VersionedModel.from_string(versioned_model)
89
-
90
- if (
91
- not function_uri.project
92
- or not function_uri.function
93
- or not versioned_model.model
94
- ):
95
- raise ValueError("Both function_uri and versioned_model have to be initialized")
96
-
97
- uid = EndpointUID(
98
- function_uri.project,
99
- function_uri.function,
100
- function_uri.tag,
101
- function_uri.hash_key,
102
- versioned_model.model,
103
- versioned_model.version,
104
- )
105
-
106
- return uid
24
+ from mlrun.common.schemas.schedule import ScheduleCronTrigger
25
+ from mlrun.config import is_running_as_api
107
26
 
108
27
 
109
28
  def parse_model_endpoint_project_prefix(path: str, project_name: str):
@@ -116,29 +35,20 @@ def parse_model_endpoint_store_prefix(store_prefix: str):
116
35
  return endpoint, container, path
117
36
 
118
37
 
119
- def set_project_model_monitoring_credentials(
120
- access_key: str, project: Optional[str] = None
121
- ):
38
+ def set_project_model_monitoring_credentials(access_key: str, project: str = None):
122
39
  """Set the credentials that will be used by the project's model monitoring
123
40
  infrastructure functions.
124
41
  The supplied credentials must have data access
125
-
126
42
  :param access_key: Model Monitoring access key for managing user permissions.
127
43
  :param project: The name of the model monitoring project.
128
44
  """
129
45
  mlrun.get_run_db().create_project_secrets(
130
46
  project=project or mlrun.mlconf.default_project,
131
- provider=mlrun.api.schemas.SecretProviderName.kubernetes,
132
- secrets={"MODEL_MONITORING_ACCESS_KEY": access_key},
47
+ provider=mlrun.common.schemas.SecretProviderName.kubernetes,
48
+ secrets={model_monitoring_constants.ProjectSecretKeys.ACCESS_KEY: access_key},
133
49
  )
134
50
 
135
51
 
136
- class EndpointType(enum.IntEnum):
137
- NODE_EP = 1 # end point that is not a child of a router
138
- ROUTER = 2 # endpoint that is router
139
- LEAF_EP = 3 # end point that is a child of a router
140
-
141
-
142
52
  class TrackingPolicy(mlrun.model.ModelObj):
143
53
  """
144
54
  Modified model monitoring configurations. By using TrackingPolicy, the user can apply his model monitoring
@@ -215,3 +125,125 @@ class TrackingPolicy(mlrun.model.ModelObj):
215
125
  model_monitoring_constants.EventFieldType.DEFAULT_BATCH_INTERVALS
216
126
  ] = self.default_batch_intervals.dict()
217
127
  return struct
128
+
129
+
130
+ def get_connection_string(project: str = None):
131
+ """Get endpoint store connection string from the project secret.
132
+ If wasn't set, take it from the system configurations"""
133
+ if is_running_as_api():
134
+ # Running on API server side
135
+ import mlrun.api.crud.secrets
136
+ import mlrun.common.schemas
137
+
138
+ return (
139
+ mlrun.api.crud.secrets.Secrets().get_project_secret(
140
+ project=project,
141
+ provider=mlrun.common.schemas.secret.SecretProviderName.kubernetes,
142
+ allow_secrets_from_k8s=True,
143
+ secret_key=model_monitoring_constants.ProjectSecretKeys.ENDPOINT_STORE_CONNECTION,
144
+ )
145
+ or mlrun.mlconf.model_endpoint_monitoring.endpoint_store_connection
146
+ )
147
+ else:
148
+ # Running on stream server side
149
+ import mlrun
150
+
151
+ return (
152
+ mlrun.get_secret_or_env(
153
+ model_monitoring_constants.ProjectSecretKeys.ENDPOINT_STORE_CONNECTION
154
+ )
155
+ or mlrun.mlconf.model_endpoint_monitoring.endpoint_store_connection
156
+ )
157
+
158
+
159
+ def get_stream_path(project: str = None):
160
+ # TODO: This function (as well as other methods in this file) includes both client and server side code. We will
161
+ # need to refactor and adjust this file in the future.
162
+ """Get stream path from the project secret. If wasn't set, take it from the system configurations"""
163
+
164
+ if is_running_as_api():
165
+ # Running on API server side
166
+ import mlrun.api.crud.secrets
167
+ import mlrun.common.schemas
168
+
169
+ stream_uri = mlrun.api.crud.secrets.Secrets().get_project_secret(
170
+ project=project,
171
+ provider=mlrun.common.schemas.secret.SecretProviderName.kubernetes,
172
+ allow_secrets_from_k8s=True,
173
+ secret_key=model_monitoring_constants.ProjectSecretKeys.STREAM_PATH,
174
+ ) or mlrun.mlconf.get_model_monitoring_file_target_path(
175
+ project=project,
176
+ kind=model_monitoring_constants.FileTargetKind.STREAM,
177
+ target="online",
178
+ )
179
+
180
+ else:
181
+ import mlrun
182
+
183
+ stream_uri = mlrun.get_secret_or_env(
184
+ model_monitoring_constants.ProjectSecretKeys.STREAM_PATH
185
+ ) or mlrun.mlconf.get_model_monitoring_file_target_path(
186
+ project=project,
187
+ kind=model_monitoring_constants.FileTargetKind.STREAM,
188
+ target="online",
189
+ )
190
+
191
+ if stream_uri.startswith("kafka://"):
192
+ if "?topic" in stream_uri:
193
+ raise mlrun.errors.MLRunInvalidArgumentError(
194
+ "Custom kafka topic is not allowed"
195
+ )
196
+ # Add topic to stream kafka uri
197
+ stream_uri += f"?topic=monitoring_stream_{project}"
198
+
199
+ elif stream_uri.startswith("v3io://") and mlrun.mlconf.is_ce_mode():
200
+ # V3IO is not supported in CE mode, generating a default http stream path
201
+ stream_uri = mlrun.mlconf.model_endpoint_monitoring.default_http_sink
202
+
203
+ return stream_uri
204
+
205
+
206
+ def validate_old_schema_fields(endpoint: dict):
207
+ """
208
+ Replace default null values for `error_count` and `metrics` for users that logged a model endpoint before 1.3.0.
209
+ In addition, this function also validates that the key name of the endpoint unique id is `uid` and not
210
+ `endpoint_id` that has been used before 1.3.0.
211
+
212
+ Leaving here for backwards compatibility which related to the model endpoint schema.
213
+
214
+ :param endpoint: An endpoint flattened dictionary.
215
+ """
216
+ warnings.warn(
217
+ "This will be deprecated in 1.3.0, and will be removed in 1.5.0",
218
+ # TODO: In 1.3.0 do changes in examples & demos In 1.5.0 remove
219
+ FutureWarning,
220
+ )
221
+
222
+ # Validate default value for `error_count`
223
+ # For backwards compatibility reasons, we validate that the model endpoint includes the `error_count` key
224
+ if (
225
+ model_monitoring_constants.EventFieldType.ERROR_COUNT in endpoint
226
+ and endpoint[model_monitoring_constants.EventFieldType.ERROR_COUNT] == "null"
227
+ ):
228
+ endpoint[model_monitoring_constants.EventFieldType.ERROR_COUNT] = "0"
229
+
230
+ # Validate default value for `metrics`
231
+ # For backwards compatibility reasons, we validate that the model endpoint includes the `metrics` key
232
+ if (
233
+ model_monitoring_constants.EventFieldType.METRICS in endpoint
234
+ and endpoint[model_monitoring_constants.EventFieldType.METRICS] == "null"
235
+ ):
236
+ endpoint[model_monitoring_constants.EventFieldType.METRICS] = json.dumps(
237
+ {
238
+ model_monitoring_constants.EventKeyMetrics.GENERIC: {
239
+ model_monitoring_constants.EventLiveStats.LATENCY_AVG_1H: 0,
240
+ model_monitoring_constants.EventLiveStats.PREDICTIONS_PER_SECOND: 0,
241
+ }
242
+ }
243
+ )
244
+ # Validate key `uid` instead of `endpoint_id`
245
+ # For backwards compatibility reasons, we replace the `endpoint_id` with `uid` which is the updated key name
246
+ if model_monitoring_constants.EventFieldType.ENDPOINT_ID in endpoint:
247
+ endpoint[model_monitoring_constants.EventFieldType.UID] = endpoint[
248
+ model_monitoring_constants.EventFieldType.ENDPOINT_ID
249
+ ]
@@ -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.
@@ -15,7 +15,9 @@
15
15
  import enum
16
16
  import typing
17
17
 
18
- from .base import NotificationBase, NotificationSeverity # noqa
18
+ from mlrun.common.schemas.notification import NotificationKind
19
+
20
+ from .base import NotificationBase
19
21
  from .console import ConsoleNotification
20
22
  from .git import GitNotification
21
23
  from .ipython import IPythonNotification
@@ -23,10 +25,10 @@ from .slack import SlackNotification
23
25
 
24
26
 
25
27
  class NotificationTypes(str, enum.Enum):
26
- console = "console"
27
- git = "git"
28
- ipython = "ipython"
29
- slack = "slack"
28
+ console = NotificationKind.console.value
29
+ git = NotificationKind.git.value
30
+ ipython = NotificationKind.ipython.value
31
+ slack = NotificationKind.slack.value
30
32
 
31
33
  def get_notification(self) -> typing.Type[NotificationBase]:
32
34
  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.
@@ -12,35 +12,36 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- import enum
15
+ import asyncio
16
16
  import typing
17
17
 
18
+ import mlrun.common.schemas
18
19
  import mlrun.lists
19
20
 
20
21
 
21
- class NotificationSeverity(str, enum.Enum):
22
- INFO = "info"
23
- DEBUG = "debug"
24
- VERBOSE = "verbose"
25
- WARNING = "warning"
26
- ERROR = "error"
27
-
28
-
29
22
  class NotificationBase:
30
23
  def __init__(
31
24
  self,
25
+ name: str = None,
32
26
  params: typing.Dict[str, str] = None,
33
27
  ):
28
+ self.name = name
34
29
  self.params = params or {}
35
30
 
36
31
  @property
37
32
  def active(self) -> bool:
38
33
  return True
39
34
 
40
- def send(
35
+ @property
36
+ def is_async(self) -> bool:
37
+ return asyncio.iscoroutinefunction(self.push)
38
+
39
+ def push(
41
40
  self,
42
41
  message: str,
43
- severity: typing.Union[NotificationSeverity, str] = NotificationSeverity.INFO,
42
+ severity: typing.Union[
43
+ mlrun.common.schemas.NotificationSeverity, str
44
+ ] = mlrun.common.schemas.NotificationSeverity.INFO,
44
45
  runs: typing.Union[mlrun.lists.RunList, list] = None,
45
46
  custom_html: str = None,
46
47
  ):
@@ -52,16 +53,21 @@ class NotificationBase:
52
53
  ) -> None:
53
54
  self.params = params or {}
54
55
 
55
- @staticmethod
56
56
  def _get_html(
57
+ self,
57
58
  message: str,
58
- severity: typing.Union[NotificationSeverity, str] = NotificationSeverity.INFO,
59
+ severity: typing.Union[
60
+ mlrun.common.schemas.NotificationSeverity, str
61
+ ] = mlrun.common.schemas.NotificationSeverity.INFO,
59
62
  runs: typing.Union[mlrun.lists.RunList, list] = None,
60
63
  custom_html: str = None,
61
64
  ) -> str:
62
65
  if custom_html:
63
66
  return custom_html
64
67
 
68
+ if self.name:
69
+ message = f"{self.name}: {message}"
70
+
65
71
  if not runs:
66
72
  return f"[{severity}] {message}"
67
73
 
@@ -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.
@@ -16,10 +16,11 @@ import typing
16
16
 
17
17
  import tabulate
18
18
 
19
+ import mlrun.common.schemas
19
20
  import mlrun.lists
20
21
  import mlrun.utils.helpers
21
22
 
22
- from .base import NotificationBase, NotificationSeverity
23
+ from .base import NotificationBase
23
24
 
24
25
 
25
26
  class ConsoleNotification(NotificationBase):
@@ -27,10 +28,12 @@ class ConsoleNotification(NotificationBase):
27
28
  Client only notification for printing run status notifications in console
28
29
  """
29
30
 
30
- def send(
31
+ def push(
31
32
  self,
32
33
  message: str,
33
- severity: typing.Union[NotificationSeverity, str] = NotificationSeverity.INFO,
34
+ severity: typing.Union[
35
+ mlrun.common.schemas.NotificationSeverity, str
36
+ ] = mlrun.common.schemas.NotificationSeverity.INFO,
34
37
  runs: typing.Union[mlrun.lists.RunList, list] = None,
35
38
  custom_html: str = None,
36
39
  ):
@@ -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.
@@ -16,12 +16,13 @@ import json
16
16
  import os
17
17
  import typing
18
18
 
19
- import requests
19
+ import aiohttp
20
20
 
21
+ import mlrun.common.schemas
21
22
  import mlrun.errors
22
23
  import mlrun.lists
23
24
 
24
- from .base import NotificationBase, NotificationSeverity
25
+ from .base import NotificationBase
25
26
 
26
27
 
27
28
  class GitNotification(NotificationBase):
@@ -29,15 +30,18 @@ class GitNotification(NotificationBase):
29
30
  API/Client notification for setting a rich run statuses git issue comment (github/gitlab)
30
31
  """
31
32
 
32
- def send(
33
+ async def push(
33
34
  self,
34
35
  message: str,
35
- severity: typing.Union[NotificationSeverity, str] = NotificationSeverity.INFO,
36
+ severity: typing.Union[
37
+ mlrun.common.schemas.NotificationSeverity, str
38
+ ] = mlrun.common.schemas.NotificationSeverity.INFO,
36
39
  runs: typing.Union[mlrun.lists.RunList, list] = None,
37
40
  custom_html: str = None,
38
41
  ):
39
42
  git_repo = self.params.get("repo", None)
40
43
  git_issue = self.params.get("issue", None)
44
+ git_merge_request = self.params.get("merge_request", None)
41
45
  token = (
42
46
  self.params.get("token", None)
43
47
  or self.params.get("GIT_TOKEN", None)
@@ -45,20 +49,22 @@ class GitNotification(NotificationBase):
45
49
  )
46
50
  server = self.params.get("server", None)
47
51
  gitlab = self.params.get("gitlab", False)
48
- self._pr_comment(
52
+ await self._pr_comment(
49
53
  self._get_html(message, severity, runs, custom_html),
50
54
  git_repo,
51
55
  git_issue,
56
+ merge_request=git_merge_request,
52
57
  token=token,
53
58
  server=server,
54
59
  gitlab=gitlab,
55
60
  )
56
61
 
57
62
  @staticmethod
58
- def _pr_comment(
63
+ async def _pr_comment(
59
64
  message: str,
60
65
  repo: str = None,
61
66
  issue: int = None,
67
+ merge_request: int = None,
62
68
  token: str = None,
63
69
  server: str = None,
64
70
  gitlab: bool = False,
@@ -86,12 +92,19 @@ class GitNotification(NotificationBase):
86
92
  headers = {"PRIVATE-TOKEN": token}
87
93
  repo = repo or os.environ.get("CI_PROJECT_ID")
88
94
  # auto detect GitLab pr id from the environment
89
- issue = issue or os.environ.get("CI_MERGE_REQUEST_IID")
95
+ issue = issue or os.environ.get("CI_ISSUE_IID")
96
+ merge_request = merge_request or os.environ.get("CI_MERGE_REQUEST_IID")
90
97
  # replace slash with url encoded slash for GitLab to accept a repo name with slash
91
98
  repo = repo.replace("/", "%2F")
92
- url = (
93
- f"https://{server}/api/v4/projects/{repo}/merge_requests/{issue}/notes"
94
- )
99
+
100
+ if merge_request:
101
+ url = f"https://{server}/api/v4/projects/{repo}/merge_requests/{merge_request}/notes"
102
+ elif issue:
103
+ url = f"https://{server}/api/v4/projects/{repo}/issues/{issue}/notes"
104
+ else:
105
+ raise mlrun.errors.MLRunInvalidArgumentError(
106
+ "GitLab issue or merge request id not specified"
107
+ )
95
108
  else:
96
109
  server = server or "api.github.com"
97
110
  repo = repo or os.environ.get("GITHUB_REPOSITORY")
@@ -101,19 +114,23 @@ class GitNotification(NotificationBase):
101
114
  with open(os.environ["GITHUB_EVENT_PATH"]) as fp:
102
115
  data = fp.read()
103
116
  event = json.loads(data)
104
- if "issue" not in event:
117
+ if "number" not in event:
105
118
  raise mlrun.errors.MLRunInvalidArgumentError(
106
119
  f"issue not found in github actions event\ndata={data}"
107
120
  )
108
- issue = event["issue"].get("number")
121
+ issue = event["number"]
109
122
  headers = {
110
123
  "Accept": "application/vnd.github.v3+json",
111
124
  "Authorization": f"token {token}",
112
125
  }
113
126
  url = f"https://{server}/repos/{repo}/issues/{issue}/comments"
114
- resp = requests.post(url=url, json={"body": str(message)}, headers=headers)
115
- if not resp.ok:
116
- raise mlrun.errors.MLRunBadRequestError(
117
- "Failed commenting on PR", response=resp.text, status=resp.status_code
118
- )
119
- return resp.json()["id"]
127
+
128
+ async with aiohttp.ClientSession() as session:
129
+ resp = await session.post(url, headers=headers, json={"body": message})
130
+ if not resp.ok:
131
+ resp_text = await resp.text()
132
+ raise mlrun.errors.MLRunBadRequestError(
133
+ f"Failed commenting on PR: {resp_text}"
134
+ )
135
+ data = await resp.json()
136
+ return data.get("id")
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -14,10 +14,11 @@
14
14
 
15
15
  import typing
16
16
 
17
+ import mlrun.common.schemas
17
18
  import mlrun.lists
18
19
  import mlrun.utils.helpers
19
20
 
20
- from .base import NotificationBase, NotificationSeverity
21
+ from .base import NotificationBase
21
22
 
22
23
 
23
24
  class IPythonNotification(NotificationBase):
@@ -27,16 +28,15 @@ class IPythonNotification(NotificationBase):
27
28
 
28
29
  def __init__(
29
30
  self,
31
+ name: str = None,
30
32
  params: typing.Dict[str, str] = None,
31
33
  ):
32
- super().__init__(params)
34
+ super().__init__(name, params)
33
35
  self._ipython = None
34
36
  try:
35
37
  import IPython
36
38
 
37
- ipy = IPython.get_ipython()
38
- # if its IPython terminal ignore (can't show html)
39
- if ipy and "Terminal" not in str(type(ipy)):
39
+ if mlrun.utils.helpers.is_running_in_jupyter_notebook():
40
40
  self._ipython = IPython
41
41
  except ImportError:
42
42
  pass
@@ -45,10 +45,12 @@ class IPythonNotification(NotificationBase):
45
45
  def active(self) -> bool:
46
46
  return self._ipython is not None
47
47
 
48
- def send(
48
+ def push(
49
49
  self,
50
50
  message: str,
51
- severity: typing.Union[NotificationSeverity, str] = NotificationSeverity.INFO,
51
+ severity: typing.Union[
52
+ mlrun.common.schemas.NotificationSeverity, str
53
+ ] = mlrun.common.schemas.NotificationSeverity.INFO,
52
54
  runs: typing.Union[mlrun.lists.RunList, list] = None,
53
55
  custom_html: str = None,
54
56
  ):
@@ -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.
@@ -12,15 +12,15 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- import json
16
15
  import typing
17
16
 
18
- import requests
17
+ import aiohttp
19
18
 
19
+ import mlrun.common.schemas
20
20
  import mlrun.lists
21
21
  import mlrun.utils.helpers
22
22
 
23
- from .base import NotificationBase, NotificationSeverity
23
+ from .base import NotificationBase
24
24
 
25
25
 
26
26
  class SlackNotification(NotificationBase):
@@ -34,10 +34,12 @@ class SlackNotification(NotificationBase):
34
34
  "error": ":x:",
35
35
  }
36
36
 
37
- def send(
37
+ async def push(
38
38
  self,
39
39
  message: str,
40
- severity: typing.Union[NotificationSeverity, str] = NotificationSeverity.INFO,
40
+ severity: typing.Union[
41
+ mlrun.common.schemas.NotificationSeverity, str
42
+ ] = mlrun.common.schemas.NotificationSeverity.INFO,
41
43
  runs: typing.Union[mlrun.lists.RunList, list] = None,
42
44
  custom_html: str = None,
43
45
  ):
@@ -53,17 +55,16 @@ class SlackNotification(NotificationBase):
53
55
 
54
56
  data = self._generate_slack_data(message, severity, runs)
55
57
 
56
- response = requests.post(
57
- webhook,
58
- data=json.dumps(data),
59
- headers={"Content-Type": "application/json"},
60
- )
61
- response.raise_for_status()
58
+ async with aiohttp.ClientSession() as session:
59
+ async with session.post(webhook, json=data) as response:
60
+ response.raise_for_status()
62
61
 
63
62
  def _generate_slack_data(
64
63
  self,
65
64
  message: str,
66
- severity: typing.Union[NotificationSeverity, str] = NotificationSeverity.INFO,
65
+ severity: typing.Union[
66
+ mlrun.common.schemas.NotificationSeverity, str
67
+ ] = mlrun.common.schemas.NotificationSeverity.INFO,
67
68
  runs: typing.Union[mlrun.lists.RunList, list] = None,
68
69
  ) -> dict:
69
70
  data = {
@@ -74,6 +75,10 @@ class SlackNotification(NotificationBase):
74
75
  },
75
76
  ]
76
77
  }
78
+ if self.name:
79
+ data["blocks"].append(
80
+ {"type": "section", "text": self._get_slack_row(self.name)}
81
+ )
77
82
 
78
83
  if not runs:
79
84
  return data