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

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

Potentially problematic release.


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

Files changed (444) hide show
  1. mlrun/__init__.py +3 -3
  2. mlrun/__main__.py +79 -37
  3. mlrun/api/__init__.py +1 -1
  4. mlrun/api/api/__init__.py +1 -1
  5. mlrun/api/api/api.py +4 -4
  6. mlrun/api/api/deps.py +10 -21
  7. mlrun/api/api/endpoints/__init__.py +1 -1
  8. mlrun/api/api/endpoints/artifacts.py +64 -36
  9. mlrun/api/api/endpoints/auth.py +4 -4
  10. mlrun/api/api/endpoints/background_tasks.py +11 -11
  11. mlrun/api/api/endpoints/client_spec.py +5 -5
  12. mlrun/api/api/endpoints/clusterization_spec.py +6 -4
  13. mlrun/api/api/endpoints/feature_store.py +124 -115
  14. mlrun/api/api/endpoints/files.py +22 -14
  15. mlrun/api/api/endpoints/frontend_spec.py +28 -21
  16. mlrun/api/api/endpoints/functions.py +142 -87
  17. mlrun/api/api/endpoints/grafana_proxy.py +89 -442
  18. mlrun/api/api/endpoints/healthz.py +20 -7
  19. mlrun/api/api/endpoints/hub.py +320 -0
  20. mlrun/api/api/endpoints/internal/__init__.py +1 -1
  21. mlrun/api/api/endpoints/internal/config.py +1 -1
  22. mlrun/api/api/endpoints/internal/memory_reports.py +9 -9
  23. mlrun/api/api/endpoints/logs.py +11 -11
  24. mlrun/api/api/endpoints/model_endpoints.py +74 -70
  25. mlrun/api/api/endpoints/operations.py +13 -9
  26. mlrun/api/api/endpoints/pipelines.py +93 -88
  27. mlrun/api/api/endpoints/projects.py +35 -35
  28. mlrun/api/api/endpoints/runs.py +69 -27
  29. mlrun/api/api/endpoints/runtime_resources.py +28 -28
  30. mlrun/api/api/endpoints/schedules.py +98 -41
  31. mlrun/api/api/endpoints/secrets.py +37 -32
  32. mlrun/api/api/endpoints/submit.py +12 -12
  33. mlrun/api/api/endpoints/tags.py +20 -22
  34. mlrun/api/api/utils.py +251 -42
  35. mlrun/api/constants.py +1 -1
  36. mlrun/api/crud/__init__.py +18 -15
  37. mlrun/api/crud/artifacts.py +10 -10
  38. mlrun/api/crud/client_spec.py +4 -4
  39. mlrun/api/crud/clusterization_spec.py +3 -3
  40. mlrun/api/crud/feature_store.py +54 -46
  41. mlrun/api/crud/functions.py +3 -3
  42. mlrun/api/crud/hub.py +312 -0
  43. mlrun/api/crud/logs.py +11 -9
  44. mlrun/api/crud/model_monitoring/__init__.py +3 -3
  45. mlrun/api/crud/model_monitoring/grafana.py +435 -0
  46. mlrun/api/crud/model_monitoring/model_endpoints.py +352 -129
  47. mlrun/api/crud/notifications.py +149 -0
  48. mlrun/api/crud/pipelines.py +67 -52
  49. mlrun/api/crud/projects.py +51 -23
  50. mlrun/api/crud/runs.py +7 -5
  51. mlrun/api/crud/runtime_resources.py +13 -13
  52. mlrun/api/{db/filedb → crud/runtimes}/__init__.py +1 -1
  53. mlrun/api/crud/runtimes/nuclio/__init__.py +14 -0
  54. mlrun/api/crud/runtimes/nuclio/function.py +505 -0
  55. mlrun/api/crud/runtimes/nuclio/helpers.py +310 -0
  56. mlrun/api/crud/secrets.py +88 -46
  57. mlrun/api/crud/tags.py +5 -5
  58. mlrun/api/db/__init__.py +1 -1
  59. mlrun/api/db/base.py +102 -54
  60. mlrun/api/db/init_db.py +2 -3
  61. mlrun/api/db/session.py +4 -12
  62. mlrun/api/db/sqldb/__init__.py +1 -1
  63. mlrun/api/db/sqldb/db.py +439 -196
  64. mlrun/api/db/sqldb/helpers.py +1 -1
  65. mlrun/api/db/sqldb/models/__init__.py +3 -3
  66. mlrun/api/db/sqldb/models/models_mysql.py +82 -64
  67. mlrun/api/db/sqldb/models/models_sqlite.py +76 -64
  68. mlrun/api/db/sqldb/session.py +27 -20
  69. mlrun/api/initial_data.py +82 -24
  70. mlrun/api/launcher.py +196 -0
  71. mlrun/api/main.py +91 -22
  72. mlrun/api/middlewares.py +6 -5
  73. mlrun/api/migrations_mysql/env.py +1 -1
  74. mlrun/api/migrations_mysql/versions/28383af526f3_market_place_to_hub.py +40 -0
  75. mlrun/api/migrations_mysql/versions/32bae1b0e29c_increase_timestamp_fields_precision.py +1 -1
  76. mlrun/api/migrations_mysql/versions/4903aef6a91d_tag_foreign_key_and_cascades.py +1 -1
  77. mlrun/api/migrations_mysql/versions/5f1351c88a19_adding_background_tasks_table.py +1 -1
  78. mlrun/api/migrations_mysql/versions/88e656800d6a_add_requested_logs_column_and_index_to_.py +1 -1
  79. mlrun/api/migrations_mysql/versions/9d16de5f03a7_adding_data_versions_table.py +1 -1
  80. mlrun/api/migrations_mysql/versions/b86f5b53f3d7_adding_name_and_updated_to_runs_table.py +1 -1
  81. mlrun/api/migrations_mysql/versions/c4af40b0bf61_init.py +1 -1
  82. mlrun/api/migrations_mysql/versions/c905d15bd91d_notifications.py +72 -0
  83. mlrun/api/migrations_mysql/versions/ee041e8fdaa0_adding_next_run_time_column_to_schedule_.py +1 -1
  84. mlrun/api/migrations_sqlite/env.py +1 -1
  85. mlrun/api/migrations_sqlite/versions/11f8dd2dc9fe_init.py +1 -1
  86. mlrun/api/migrations_sqlite/versions/1c954f8cb32d_schedule_last_run_uri.py +1 -1
  87. mlrun/api/migrations_sqlite/versions/2b6d23c715aa_adding_feature_sets.py +1 -1
  88. mlrun/api/migrations_sqlite/versions/4acd9430b093_market_place_to_hub.py +77 -0
  89. mlrun/api/migrations_sqlite/versions/6401142f2d7c_adding_next_run_time_column_to_schedule_.py +1 -1
  90. mlrun/api/migrations_sqlite/versions/64d90a1a69bc_adding_background_tasks_table.py +1 -1
  91. mlrun/api/migrations_sqlite/versions/803438ecd005_add_requested_logs_column_to_runs.py +1 -1
  92. mlrun/api/migrations_sqlite/versions/863114f0c659_refactoring_feature_set.py +1 -1
  93. mlrun/api/migrations_sqlite/versions/959ae00528ad_notifications.py +63 -0
  94. mlrun/api/migrations_sqlite/versions/accf9fc83d38_adding_data_versions_table.py +1 -1
  95. mlrun/api/migrations_sqlite/versions/b68e8e897a28_schedule_labels.py +1 -1
  96. mlrun/api/migrations_sqlite/versions/bcd0c1f9720c_adding_project_labels.py +1 -1
  97. mlrun/api/migrations_sqlite/versions/cf21882f938e_schedule_id.py +1 -1
  98. mlrun/api/migrations_sqlite/versions/d781f58f607f_tag_object_name_string.py +1 -1
  99. mlrun/api/migrations_sqlite/versions/deac06871ace_adding_marketplace_sources_table.py +1 -1
  100. mlrun/api/migrations_sqlite/versions/e1dd5983c06b_schedule_concurrency_limit.py +1 -1
  101. mlrun/api/migrations_sqlite/versions/e5594ed3ab53_adding_name_and_updated_to_runs_table.py +1 -1
  102. mlrun/api/migrations_sqlite/versions/f4249b4ba6fa_adding_feature_vectors.py +1 -1
  103. mlrun/api/migrations_sqlite/versions/f7b5a1a03629_adding_feature_labels.py +1 -1
  104. mlrun/api/schemas/__init__.py +216 -138
  105. mlrun/api/utils/__init__.py +1 -1
  106. mlrun/api/utils/asyncio.py +1 -1
  107. mlrun/api/utils/auth/__init__.py +1 -1
  108. mlrun/api/utils/auth/providers/__init__.py +1 -1
  109. mlrun/api/utils/auth/providers/base.py +7 -7
  110. mlrun/api/utils/auth/providers/nop.py +6 -7
  111. mlrun/api/utils/auth/providers/opa.py +17 -17
  112. mlrun/api/utils/auth/verifier.py +36 -34
  113. mlrun/api/utils/background_tasks.py +24 -24
  114. mlrun/{builder.py → api/utils/builder.py} +216 -123
  115. mlrun/api/utils/clients/__init__.py +1 -1
  116. mlrun/api/utils/clients/chief.py +19 -4
  117. mlrun/api/utils/clients/iguazio.py +106 -60
  118. mlrun/api/utils/clients/log_collector.py +1 -1
  119. mlrun/api/utils/clients/nuclio.py +23 -23
  120. mlrun/api/utils/clients/protocols/grpc.py +2 -2
  121. mlrun/api/utils/db/__init__.py +1 -1
  122. mlrun/api/utils/db/alembic.py +1 -1
  123. mlrun/api/utils/db/backup.py +1 -1
  124. mlrun/api/utils/db/mysql.py +24 -25
  125. mlrun/api/utils/db/sql_collation.py +1 -1
  126. mlrun/api/utils/db/sqlite_migration.py +2 -2
  127. mlrun/api/utils/events/__init__.py +14 -0
  128. mlrun/api/utils/events/base.py +57 -0
  129. mlrun/api/utils/events/events_factory.py +41 -0
  130. mlrun/api/utils/events/iguazio.py +217 -0
  131. mlrun/api/utils/events/nop.py +55 -0
  132. mlrun/api/utils/helpers.py +16 -13
  133. mlrun/api/utils/memory_reports.py +1 -1
  134. mlrun/api/utils/periodic.py +6 -3
  135. mlrun/api/utils/projects/__init__.py +1 -1
  136. mlrun/api/utils/projects/follower.py +33 -33
  137. mlrun/api/utils/projects/leader.py +36 -34
  138. mlrun/api/utils/projects/member.py +27 -27
  139. mlrun/api/utils/projects/remotes/__init__.py +1 -1
  140. mlrun/api/utils/projects/remotes/follower.py +13 -13
  141. mlrun/api/utils/projects/remotes/leader.py +10 -10
  142. mlrun/api/utils/projects/remotes/nop_follower.py +27 -21
  143. mlrun/api/utils/projects/remotes/nop_leader.py +17 -16
  144. mlrun/api/utils/scheduler.py +140 -51
  145. mlrun/api/utils/singletons/__init__.py +1 -1
  146. mlrun/api/utils/singletons/db.py +9 -15
  147. mlrun/api/utils/singletons/k8s.py +677 -5
  148. mlrun/api/utils/singletons/logs_dir.py +1 -1
  149. mlrun/api/utils/singletons/project_member.py +1 -1
  150. mlrun/api/utils/singletons/scheduler.py +1 -1
  151. mlrun/artifacts/__init__.py +2 -2
  152. mlrun/artifacts/base.py +8 -2
  153. mlrun/artifacts/dataset.py +5 -3
  154. mlrun/artifacts/manager.py +7 -1
  155. mlrun/artifacts/model.py +15 -4
  156. mlrun/artifacts/plots.py +1 -1
  157. mlrun/common/__init__.py +1 -1
  158. mlrun/common/constants.py +15 -0
  159. mlrun/common/model_monitoring.py +209 -0
  160. mlrun/common/schemas/__init__.py +167 -0
  161. mlrun/{api → common}/schemas/artifact.py +13 -14
  162. mlrun/{api → common}/schemas/auth.py +10 -8
  163. mlrun/{api → common}/schemas/background_task.py +3 -3
  164. mlrun/{api → common}/schemas/client_spec.py +1 -1
  165. mlrun/{api → common}/schemas/clusterization_spec.py +3 -3
  166. mlrun/{api → common}/schemas/constants.py +21 -8
  167. mlrun/common/schemas/events.py +36 -0
  168. mlrun/{api → common}/schemas/feature_store.py +2 -1
  169. mlrun/{api → common}/schemas/frontend_spec.py +7 -6
  170. mlrun/{api → common}/schemas/function.py +5 -5
  171. mlrun/{api → common}/schemas/http.py +3 -3
  172. mlrun/common/schemas/hub.py +134 -0
  173. mlrun/{api → common}/schemas/k8s.py +3 -3
  174. mlrun/{api → common}/schemas/memory_reports.py +1 -1
  175. mlrun/common/schemas/model_endpoints.py +342 -0
  176. mlrun/common/schemas/notification.py +57 -0
  177. mlrun/{api → common}/schemas/object.py +6 -6
  178. mlrun/{api → common}/schemas/pipeline.py +3 -3
  179. mlrun/{api → common}/schemas/project.py +6 -5
  180. mlrun/common/schemas/regex.py +24 -0
  181. mlrun/common/schemas/runs.py +30 -0
  182. mlrun/{api → common}/schemas/runtime_resource.py +3 -3
  183. mlrun/{api → common}/schemas/schedule.py +19 -7
  184. mlrun/{api → common}/schemas/secret.py +3 -3
  185. mlrun/{api → common}/schemas/tag.py +2 -2
  186. mlrun/common/types.py +25 -0
  187. mlrun/config.py +152 -20
  188. mlrun/data_types/__init__.py +7 -2
  189. mlrun/data_types/data_types.py +4 -2
  190. mlrun/data_types/infer.py +1 -1
  191. mlrun/data_types/spark.py +10 -3
  192. mlrun/datastore/__init__.py +10 -3
  193. mlrun/datastore/azure_blob.py +1 -1
  194. mlrun/datastore/base.py +185 -53
  195. mlrun/datastore/datastore.py +1 -1
  196. mlrun/datastore/filestore.py +1 -1
  197. mlrun/datastore/google_cloud_storage.py +1 -1
  198. mlrun/datastore/inmem.py +4 -1
  199. mlrun/datastore/redis.py +1 -1
  200. mlrun/datastore/s3.py +1 -1
  201. mlrun/datastore/sources.py +192 -70
  202. mlrun/datastore/spark_udf.py +44 -0
  203. mlrun/datastore/store_resources.py +4 -4
  204. mlrun/datastore/targets.py +115 -45
  205. mlrun/datastore/utils.py +127 -5
  206. mlrun/datastore/v3io.py +1 -1
  207. mlrun/datastore/wasbfs/__init__.py +1 -1
  208. mlrun/datastore/wasbfs/fs.py +1 -1
  209. mlrun/db/__init__.py +7 -5
  210. mlrun/db/base.py +112 -68
  211. mlrun/db/httpdb.py +445 -277
  212. mlrun/db/nopdb.py +491 -0
  213. mlrun/db/sqldb.py +112 -65
  214. mlrun/errors.py +6 -1
  215. mlrun/execution.py +44 -22
  216. mlrun/feature_store/__init__.py +1 -1
  217. mlrun/feature_store/api.py +143 -95
  218. mlrun/feature_store/common.py +16 -20
  219. mlrun/feature_store/feature_set.py +42 -12
  220. mlrun/feature_store/feature_vector.py +32 -21
  221. mlrun/feature_store/ingestion.py +9 -12
  222. mlrun/feature_store/retrieval/__init__.py +3 -2
  223. mlrun/feature_store/retrieval/base.py +388 -66
  224. mlrun/feature_store/retrieval/dask_merger.py +63 -151
  225. mlrun/feature_store/retrieval/job.py +30 -12
  226. mlrun/feature_store/retrieval/local_merger.py +40 -133
  227. mlrun/feature_store/retrieval/spark_merger.py +129 -127
  228. mlrun/feature_store/retrieval/storey_merger.py +173 -0
  229. mlrun/feature_store/steps.py +132 -15
  230. mlrun/features.py +8 -3
  231. mlrun/frameworks/__init__.py +1 -1
  232. mlrun/frameworks/_common/__init__.py +1 -1
  233. mlrun/frameworks/_common/artifacts_library.py +1 -1
  234. mlrun/frameworks/_common/mlrun_interface.py +1 -1
  235. mlrun/frameworks/_common/model_handler.py +1 -1
  236. mlrun/frameworks/_common/plan.py +1 -1
  237. mlrun/frameworks/_common/producer.py +1 -1
  238. mlrun/frameworks/_common/utils.py +1 -1
  239. mlrun/frameworks/_dl_common/__init__.py +1 -1
  240. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -1
  241. mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
  242. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +1 -1
  243. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +1 -1
  244. mlrun/frameworks/_dl_common/model_handler.py +1 -1
  245. mlrun/frameworks/_dl_common/utils.py +1 -1
  246. mlrun/frameworks/_ml_common/__init__.py +1 -1
  247. mlrun/frameworks/_ml_common/artifacts_library.py +1 -1
  248. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -1
  249. mlrun/frameworks/_ml_common/loggers/logger.py +1 -1
  250. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
  251. mlrun/frameworks/_ml_common/model_handler.py +1 -1
  252. mlrun/frameworks/_ml_common/pkl_model_server.py +13 -1
  253. mlrun/frameworks/_ml_common/plan.py +1 -1
  254. mlrun/frameworks/_ml_common/plans/__init__.py +1 -1
  255. mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +1 -6
  256. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +1 -1
  257. mlrun/frameworks/_ml_common/plans/dataset_plan.py +1 -1
  258. mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +1 -1
  259. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +1 -1
  260. mlrun/frameworks/_ml_common/producer.py +1 -1
  261. mlrun/frameworks/_ml_common/utils.py +1 -1
  262. mlrun/frameworks/auto_mlrun/__init__.py +1 -1
  263. mlrun/frameworks/auto_mlrun/auto_mlrun.py +1 -1
  264. mlrun/frameworks/huggingface/__init__.py +1 -1
  265. mlrun/frameworks/huggingface/model_server.py +1 -1
  266. mlrun/frameworks/lgbm/__init__.py +1 -1
  267. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -1
  268. mlrun/frameworks/lgbm/callbacks/callback.py +1 -1
  269. mlrun/frameworks/lgbm/callbacks/logging_callback.py +1 -1
  270. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +1 -1
  271. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -1
  272. mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -1
  273. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +1 -1
  274. mlrun/frameworks/lgbm/mlrun_interfaces/model_mlrun_interface.py +1 -1
  275. mlrun/frameworks/lgbm/model_handler.py +1 -1
  276. mlrun/frameworks/lgbm/model_server.py +1 -1
  277. mlrun/frameworks/lgbm/utils.py +1 -1
  278. mlrun/frameworks/onnx/__init__.py +1 -1
  279. mlrun/frameworks/onnx/dataset.py +1 -1
  280. mlrun/frameworks/onnx/mlrun_interface.py +1 -1
  281. mlrun/frameworks/onnx/model_handler.py +1 -1
  282. mlrun/frameworks/onnx/model_server.py +1 -1
  283. mlrun/frameworks/parallel_coordinates.py +1 -1
  284. mlrun/frameworks/pytorch/__init__.py +1 -1
  285. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -1
  286. mlrun/frameworks/pytorch/callbacks/callback.py +1 -1
  287. mlrun/frameworks/pytorch/callbacks/logging_callback.py +1 -1
  288. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +1 -1
  289. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +1 -1
  290. mlrun/frameworks/pytorch/callbacks_handler.py +1 -1
  291. mlrun/frameworks/pytorch/mlrun_interface.py +1 -1
  292. mlrun/frameworks/pytorch/model_handler.py +1 -1
  293. mlrun/frameworks/pytorch/model_server.py +1 -1
  294. mlrun/frameworks/pytorch/utils.py +1 -1
  295. mlrun/frameworks/sklearn/__init__.py +1 -1
  296. mlrun/frameworks/sklearn/estimator.py +1 -1
  297. mlrun/frameworks/sklearn/metric.py +1 -1
  298. mlrun/frameworks/sklearn/metrics_library.py +1 -1
  299. mlrun/frameworks/sklearn/mlrun_interface.py +1 -1
  300. mlrun/frameworks/sklearn/model_handler.py +1 -1
  301. mlrun/frameworks/sklearn/utils.py +1 -1
  302. mlrun/frameworks/tf_keras/__init__.py +1 -1
  303. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -1
  304. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  305. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +1 -1
  306. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +1 -1
  307. mlrun/frameworks/tf_keras/mlrun_interface.py +1 -1
  308. mlrun/frameworks/tf_keras/model_handler.py +1 -1
  309. mlrun/frameworks/tf_keras/model_server.py +1 -1
  310. mlrun/frameworks/tf_keras/utils.py +1 -1
  311. mlrun/frameworks/xgboost/__init__.py +1 -1
  312. mlrun/frameworks/xgboost/mlrun_interface.py +1 -1
  313. mlrun/frameworks/xgboost/model_handler.py +1 -1
  314. mlrun/frameworks/xgboost/utils.py +1 -1
  315. mlrun/k8s_utils.py +14 -765
  316. mlrun/kfpops.py +14 -17
  317. mlrun/launcher/__init__.py +13 -0
  318. mlrun/launcher/base.py +406 -0
  319. mlrun/launcher/client.py +159 -0
  320. mlrun/launcher/factory.py +50 -0
  321. mlrun/launcher/local.py +276 -0
  322. mlrun/launcher/remote.py +178 -0
  323. mlrun/lists.py +10 -2
  324. mlrun/mlutils/__init__.py +1 -1
  325. mlrun/mlutils/data.py +1 -1
  326. mlrun/mlutils/models.py +1 -1
  327. mlrun/mlutils/plots.py +1 -1
  328. mlrun/model.py +252 -14
  329. mlrun/model_monitoring/__init__.py +41 -0
  330. mlrun/model_monitoring/features_drift_table.py +1 -1
  331. mlrun/model_monitoring/helpers.py +123 -38
  332. mlrun/model_monitoring/model_endpoint.py +144 -0
  333. mlrun/model_monitoring/model_monitoring_batch.py +310 -259
  334. mlrun/model_monitoring/stores/__init__.py +106 -0
  335. mlrun/model_monitoring/stores/kv_model_endpoint_store.py +448 -0
  336. mlrun/model_monitoring/stores/model_endpoint_store.py +147 -0
  337. mlrun/model_monitoring/stores/models/__init__.py +23 -0
  338. mlrun/model_monitoring/stores/models/base.py +18 -0
  339. mlrun/model_monitoring/stores/models/mysql.py +100 -0
  340. mlrun/model_monitoring/stores/models/sqlite.py +98 -0
  341. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +370 -0
  342. mlrun/model_monitoring/stream_processing_fs.py +239 -271
  343. mlrun/package/__init__.py +163 -0
  344. mlrun/package/context_handler.py +325 -0
  345. mlrun/package/errors.py +47 -0
  346. mlrun/package/packager.py +298 -0
  347. mlrun/{runtimes/package → package/packagers}/__init__.py +3 -1
  348. mlrun/package/packagers/default_packager.py +422 -0
  349. mlrun/package/packagers/numpy_packagers.py +612 -0
  350. mlrun/package/packagers/pandas_packagers.py +968 -0
  351. mlrun/package/packagers/python_standard_library_packagers.py +616 -0
  352. mlrun/package/packagers_manager.py +786 -0
  353. mlrun/package/utils/__init__.py +53 -0
  354. mlrun/package/utils/_archiver.py +226 -0
  355. mlrun/package/utils/_formatter.py +211 -0
  356. mlrun/package/utils/_pickler.py +234 -0
  357. mlrun/package/utils/_supported_format.py +71 -0
  358. mlrun/package/utils/log_hint_utils.py +93 -0
  359. mlrun/package/utils/type_hint_utils.py +298 -0
  360. mlrun/platforms/__init__.py +1 -1
  361. mlrun/platforms/iguazio.py +34 -2
  362. mlrun/platforms/other.py +1 -1
  363. mlrun/projects/__init__.py +1 -1
  364. mlrun/projects/operations.py +14 -9
  365. mlrun/projects/pipelines.py +31 -13
  366. mlrun/projects/project.py +762 -238
  367. mlrun/render.py +49 -19
  368. mlrun/run.py +57 -326
  369. mlrun/runtimes/__init__.py +3 -9
  370. mlrun/runtimes/base.py +247 -784
  371. mlrun/runtimes/constants.py +1 -1
  372. mlrun/runtimes/daskjob.py +45 -41
  373. mlrun/runtimes/funcdoc.py +43 -7
  374. mlrun/runtimes/function.py +66 -656
  375. mlrun/runtimes/function_reference.py +1 -1
  376. mlrun/runtimes/generators.py +1 -1
  377. mlrun/runtimes/kubejob.py +99 -116
  378. mlrun/runtimes/local.py +59 -66
  379. mlrun/runtimes/mpijob/__init__.py +1 -1
  380. mlrun/runtimes/mpijob/abstract.py +13 -15
  381. mlrun/runtimes/mpijob/v1.py +3 -1
  382. mlrun/runtimes/mpijob/v1alpha1.py +1 -1
  383. mlrun/runtimes/nuclio.py +1 -1
  384. mlrun/runtimes/pod.py +51 -26
  385. mlrun/runtimes/remotesparkjob.py +3 -1
  386. mlrun/runtimes/serving.py +12 -4
  387. mlrun/runtimes/sparkjob/__init__.py +1 -2
  388. mlrun/runtimes/sparkjob/abstract.py +44 -31
  389. mlrun/runtimes/sparkjob/spark3job.py +11 -9
  390. mlrun/runtimes/utils.py +61 -42
  391. mlrun/secrets.py +16 -18
  392. mlrun/serving/__init__.py +3 -2
  393. mlrun/serving/merger.py +1 -1
  394. mlrun/serving/remote.py +1 -1
  395. mlrun/serving/routers.py +39 -42
  396. mlrun/serving/server.py +23 -13
  397. mlrun/serving/serving_wrapper.py +1 -1
  398. mlrun/serving/states.py +172 -39
  399. mlrun/serving/utils.py +1 -1
  400. mlrun/serving/v1_serving.py +1 -1
  401. mlrun/serving/v2_serving.py +29 -21
  402. mlrun/utils/__init__.py +1 -2
  403. mlrun/utils/async_http.py +8 -1
  404. mlrun/utils/azure_vault.py +1 -1
  405. mlrun/utils/clones.py +2 -2
  406. mlrun/utils/condition_evaluator.py +65 -0
  407. mlrun/utils/db.py +52 -0
  408. mlrun/utils/helpers.py +188 -13
  409. mlrun/utils/http.py +89 -54
  410. mlrun/utils/logger.py +48 -8
  411. mlrun/utils/model_monitoring.py +132 -100
  412. mlrun/utils/notifications/__init__.py +1 -1
  413. mlrun/utils/notifications/notification/__init__.py +8 -6
  414. mlrun/utils/notifications/notification/base.py +20 -14
  415. mlrun/utils/notifications/notification/console.py +7 -4
  416. mlrun/utils/notifications/notification/git.py +36 -19
  417. mlrun/utils/notifications/notification/ipython.py +10 -8
  418. mlrun/utils/notifications/notification/slack.py +18 -13
  419. mlrun/utils/notifications/notification_pusher.py +377 -56
  420. mlrun/utils/regex.py +6 -1
  421. mlrun/utils/singleton.py +1 -1
  422. mlrun/utils/v3io_clients.py +1 -1
  423. mlrun/utils/vault.py +270 -269
  424. mlrun/utils/version/__init__.py +1 -1
  425. mlrun/utils/version/version.json +2 -2
  426. mlrun/utils/version/version.py +1 -1
  427. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/METADATA +16 -10
  428. mlrun-1.4.0.dist-info/RECORD +434 -0
  429. mlrun/api/api/endpoints/marketplace.py +0 -257
  430. mlrun/api/crud/marketplace.py +0 -221
  431. mlrun/api/crud/model_monitoring/model_endpoint_store.py +0 -847
  432. mlrun/api/db/filedb/db.py +0 -518
  433. mlrun/api/schemas/marketplace.py +0 -128
  434. mlrun/api/schemas/model_endpoints.py +0 -185
  435. mlrun/db/filedb.py +0 -891
  436. mlrun/feature_store/retrieval/online.py +0 -92
  437. mlrun/model_monitoring/constants.py +0 -67
  438. mlrun/runtimes/package/context_handler.py +0 -711
  439. mlrun/runtimes/sparkjob/spark2job.py +0 -59
  440. mlrun-1.3.3rc1.dist-info/RECORD +0 -381
  441. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
  442. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
  443. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
  444. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
mlrun/serving/states.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.
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- __all__ = ["TaskStep", "RouterStep", "RootFlowStep"]
15
+ __all__ = ["TaskStep", "RouterStep", "RootFlowStep", "ErrorStep"]
16
16
 
17
17
  import os
18
18
  import pathlib
@@ -28,7 +28,7 @@ from ..errors import MLRunInvalidArgumentError, err_to_str
28
28
  from ..model import ModelObj, ObjectDict
29
29
  from ..platforms.iguazio import parse_path
30
30
  from ..utils import get_class, get_function
31
- from .utils import _extract_input_data, _update_result_body
31
+ from .utils import StepToDict, _extract_input_data, _update_result_body
32
32
 
33
33
  callable_prefix = "_"
34
34
  path_splitter = "/"
@@ -49,6 +49,7 @@ class StepKinds:
49
49
  queue = "queue"
50
50
  choice = "choice"
51
51
  root = "root"
52
+ error_step = "error_step"
52
53
 
53
54
 
54
55
  _task_step_fields = [
@@ -134,11 +135,82 @@ class BaseStep(ModelObj):
134
135
  self.after.append(name)
135
136
  return self
136
137
 
137
- def error_handler(self, step_name: str = None):
138
- """set error handler step (on failure/raise of this step)"""
139
- if not step_name:
140
- raise MLRunInvalidArgumentError("Must specify step_name")
141
- self.on_error = step_name
138
+ def error_handler(
139
+ self,
140
+ name: str = None,
141
+ class_name=None,
142
+ handler=None,
143
+ before=None,
144
+ function=None,
145
+ full_event: bool = None,
146
+ input_path: str = None,
147
+ result_path: str = None,
148
+ **class_args,
149
+ ):
150
+ """set error handler on a step or the entire graph (to be executed on failure/raise)
151
+
152
+ When setting the error_handler on the graph object, the graph completes after the error handler execution.
153
+
154
+ example:
155
+ in the below example, an 'error_catcher' step is set as the error_handler of the 'raise' step:
156
+ in case of error/raise in 'raise' step, the handle_error will be run. after that,
157
+ the 'echo' step will be run.
158
+ graph = function.set_topology('flow', engine='async')
159
+ graph.to(name='raise', handler='raising_step')\
160
+ .error_handler(name='error_catcher', handler='handle_error', full_event=True, before='echo')
161
+ graph.add_step(name="echo", handler='echo', after="raise").respond()
162
+
163
+ :param name: unique name (and path) for the error handler step, default is class name
164
+ :param class_name: class name or step object to build the step from
165
+ the error handler step is derived from task step (ie no router/queue functionally)
166
+ :param handler: class/function handler to invoke on run/event
167
+ :param before: string or list of next step(s) names that will run after this step.
168
+ the `before` param must not specify upstream steps as it will cause a loop.
169
+ if `before` is not specified, the graph will complete after the error handler execution.
170
+ :param function: function this step should run in
171
+ :param full_event: this step accepts the full event (not just the body)
172
+ :param input_path: selects the key/path in the event to use as input to the step
173
+ this requires that the event body will behave like a dict, for example:
174
+ event: {"data": {"a": 5, "b": 7}}, input_path="data.b" means the step will
175
+ receive 7 as input
176
+ :param result_path: selects the key/path in the event to write the results to
177
+ this requires that the event body will behave like a dict, for example:
178
+ event: {"x": 5} , result_path="y" means the output of the step will be written
179
+ to event["y"] resulting in {"x": 5, "y": <result>}
180
+ :param class_args: class init arguments
181
+
182
+ """
183
+ if not (class_name or handler):
184
+ raise MLRunInvalidArgumentError("class_name or handler must be provided")
185
+ if isinstance(self, RootFlowStep) and before:
186
+ raise MLRunInvalidArgumentError(
187
+ "`before` arg can't be specified for graph error handler"
188
+ )
189
+
190
+ name = get_name(name, class_name)
191
+ step = ErrorStep(
192
+ class_name,
193
+ class_args,
194
+ handler,
195
+ name=name,
196
+ function=function,
197
+ full_event=full_event,
198
+ input_path=input_path,
199
+ result_path=result_path,
200
+ )
201
+ self.on_error = name
202
+ before = [before] if isinstance(before, str) else before
203
+ step.before = before or []
204
+ step.base_step = self.name
205
+ if hasattr(self, "_parent") and self._parent:
206
+ # when self is a step
207
+ step = self._parent._steps.update(name, step)
208
+ step.set_parent(self._parent)
209
+ else:
210
+ # when self is the graph
211
+ step = self._steps.update(name, step)
212
+ step.set_parent(self)
213
+
142
214
  return self
143
215
 
144
216
  def init_object(self, context, namespace, mode="sync", reset=False, **extra_kwargs):
@@ -186,10 +258,11 @@ class BaseStep(ModelObj):
186
258
 
187
259
  def _call_error_handler(self, event, err, **kwargs):
188
260
  """call the error handler if exist"""
189
- if self._on_error_handler:
190
- event.error = err_to_str(err)
191
- event.origin_state = self.fullname
192
- return self._on_error_handler(event)
261
+ if not event.error:
262
+ event.error = {}
263
+ event.error[self.name] = err_to_str(err)
264
+ event.origin_state = self.fullname
265
+ return self._on_error_handler(event)
193
266
 
194
267
  def path_to_step(self, path: str):
195
268
  """return step object from step relative/fullname"""
@@ -206,7 +279,7 @@ class BaseStep(ModelObj):
206
279
 
207
280
  def to(
208
281
  self,
209
- class_name: Union[str, type] = None,
282
+ class_name: Union[str, StepToDict] = None,
210
283
  name: str = None,
211
284
  handler: str = None,
212
285
  graph_shape: str = None,
@@ -218,11 +291,12 @@ class BaseStep(ModelObj):
218
291
  ):
219
292
  """add a step right after this step and return the new step
220
293
 
221
- example, a 4 step pipeline ending with a stream:
222
- graph.to('URLDownloader')\
223
- .to('ToParagraphs')\
224
- .to(name='to_json', handler='json.dumps')\
225
- .to('>>', 'to_v3io', path=stream_path)\
294
+ example:
295
+ a 4-step pipeline ending with a stream:
296
+ graph.to('URLDownloader')\
297
+ .to('ToParagraphs')\
298
+ .to(name='to_json', handler='json.dumps')\
299
+ .to('>>', 'to_v3io', path=stream_path)\
226
300
 
227
301
  :param class_name: class name or step object to build the step from
228
302
  for router steps the class name should start with '*'
@@ -233,7 +307,7 @@ class BaseStep(ModelObj):
233
307
  :param function: function this step should run in
234
308
  :param full_event: this step accepts the full event (not just body)
235
309
  :param input_path: selects the key/path in the event to use as input to the step
236
- this require that the event body will behave like a dict, example:
310
+ this requires that the event body will behave like a dict, example:
237
311
  event: {"data": {"a": 5, "b": 7}}, input_path="data.b" means the step will
238
312
  receive 7 as input
239
313
  :param result_path: selects the key/path in the event to write the results to
@@ -327,6 +401,7 @@ class TaskStep(BaseStep):
327
401
  args = signature(self._handler).parameters
328
402
  if args and "context" in list(args.keys()):
329
403
  self._inject_context = True
404
+ self._set_error_handler()
330
405
  return
331
406
 
332
407
  self._class_object, self.class_name = self.get_step_class_object(
@@ -464,14 +539,23 @@ class TaskStep(BaseStep):
464
539
  )
465
540
  event.body = _update_result_body(self.result_path, event.body, result)
466
541
  except Exception as exc:
467
- self._log_error(event, exc)
468
- handled = self._call_error_handler(event, exc)
469
- if not handled:
542
+ if self._on_error_handler:
543
+ self._log_error(event, exc)
544
+ result = self._call_error_handler(event, exc)
545
+ event.body = _update_result_body(self.result_path, event.body, result)
546
+ else:
470
547
  raise exc
471
- event.terminated = True
472
548
  return event
473
549
 
474
550
 
551
+ class ErrorStep(TaskStep):
552
+ """error execution step, runs a class or handler"""
553
+
554
+ kind = "error_step"
555
+ _dict_fields = _task_step_fields + ["before", "base_step"]
556
+ _default_class = ""
557
+
558
+
475
559
  class RouterStep(TaskStep):
476
560
  """router step, implement routing logic for running child routes"""
477
561
 
@@ -824,6 +908,7 @@ class FlowStep(BaseStep):
824
908
  def init_object(self, context, namespace, mode="sync", reset=False, **extra_kwargs):
825
909
  """initialize graph objects and classes"""
826
910
  self.context = context
911
+ self._insert_all_error_handlers()
827
912
  self.check_and_process_graph()
828
913
 
829
914
  for step in self._steps.values():
@@ -866,7 +951,11 @@ class FlowStep(BaseStep):
866
951
 
867
952
  responders = []
868
953
  for step in self._steps.values():
869
- if hasattr(step, "responder") and step.responder:
954
+ if (
955
+ hasattr(step, "responder")
956
+ and step.responder
957
+ and step.kind != "error_step"
958
+ ):
870
959
  responders.append(step.name)
871
960
  if step.on_error and step.on_error in start_steps:
872
961
  start_steps.remove(step.on_error)
@@ -979,6 +1068,10 @@ class FlowStep(BaseStep):
979
1068
  # never set a step as its own error handler
980
1069
  if step != error_step:
981
1070
  step.async_object.set_recovery_step(error_step.async_object)
1071
+ for next_step in error_step.next or []:
1072
+ next_state = self[next_step]
1073
+ if next_state.async_object and error_step.async_object:
1074
+ error_step.async_object.to(next_state.async_object)
982
1075
 
983
1076
  self._controller = source.run()
984
1077
 
@@ -1059,15 +1152,22 @@ class FlowStep(BaseStep):
1059
1152
  try:
1060
1153
  event = next_obj.run(event, *args, **kwargs)
1061
1154
  except Exception as exc:
1062
- self._log_error(event, exc, failed_step=next_obj.name)
1063
- handled = self._call_error_handler(event, exc)
1064
- if not handled:
1155
+ if self._on_error_handler:
1156
+ self._log_error(event, exc, failed_step=next_obj.name)
1157
+ event.body = self._call_error_handler(event, exc)
1158
+ event.terminated = True
1159
+ return event
1160
+ else:
1065
1161
  raise exc
1066
- event.terminated = True
1067
- return event
1068
1162
 
1069
1163
  if hasattr(event, "terminated") and event.terminated:
1070
1164
  return event
1165
+ if (
1166
+ hasattr(event, "error")
1167
+ and isinstance(event.error, dict)
1168
+ and next_obj.name in event.error
1169
+ ):
1170
+ next_obj = self._steps[next_obj.on_error]
1071
1171
  next = next_obj.next
1072
1172
  if next and len(next) > 1:
1073
1173
  raise GraphError(
@@ -1103,6 +1203,33 @@ class FlowStep(BaseStep):
1103
1203
  **kw,
1104
1204
  )
1105
1205
 
1206
+ def _insert_all_error_handlers(self):
1207
+ """
1208
+ insert all error steps to the graph
1209
+ run after deployment
1210
+ """
1211
+ for name, step in self._steps.items():
1212
+ if step.kind == "error_step":
1213
+ self._insert_error_step(name, step)
1214
+
1215
+ def _insert_error_step(self, name, step):
1216
+ """
1217
+ insert error step to the graph
1218
+ run after deployment
1219
+ """
1220
+ if not step.before and not any(
1221
+ [step.name in other_step.after for other_step in self._steps.values()]
1222
+ ):
1223
+ step.responder = True
1224
+ return
1225
+
1226
+ for step_name in step.before:
1227
+ if step_name not in self._steps.keys():
1228
+ raise MLRunInvalidArgumentError(
1229
+ f"cant set before, there is no step named {step_name}"
1230
+ )
1231
+ self[step_name].after_step(name)
1232
+
1106
1233
 
1107
1234
  class RootFlowStep(FlowStep):
1108
1235
  """root flow step"""
@@ -1116,6 +1243,7 @@ classes_map = {
1116
1243
  "router": RouterStep,
1117
1244
  "flow": FlowStep,
1118
1245
  "queue": QueueStep,
1246
+ "error_step": ErrorStep,
1119
1247
  }
1120
1248
 
1121
1249
 
@@ -1155,15 +1283,8 @@ def _add_graphviz_flow(
1155
1283
  _add_graphviz_router(sg, child)
1156
1284
  else:
1157
1285
  graph.node(child.fullname, label=child.name, shape=child.get_shape())
1158
- after = child.after or []
1159
- for item in after:
1160
- previous_object = step[item]
1161
- kw = (
1162
- {"ltail": "cluster_" + previous_object.fullname}
1163
- if previous_object.kind == StepKinds.router
1164
- else {}
1165
- )
1166
- graph.edge(previous_object.fullname, child.fullname, **kw)
1286
+ _add_edges(child.after or [], step, graph, child)
1287
+ _add_edges(getattr(child, "before", []), step, graph, child, after=False)
1167
1288
  if child.on_error:
1168
1289
  graph.edge(child.fullname, child.on_error, style="dashed")
1169
1290
 
@@ -1183,6 +1304,18 @@ def _add_graphviz_flow(
1183
1304
  graph.edge(last_step, target.fullname)
1184
1305
 
1185
1306
 
1307
+ def _add_edges(items, step, graph, child, after=True):
1308
+ for item in items:
1309
+ next_or_prev_object = step[item]
1310
+ kw = {}
1311
+ if next_or_prev_object.kind == StepKinds.router:
1312
+ kw["ltail"] = f"cluster_{next_or_prev_object.fullname}"
1313
+ if after:
1314
+ graph.edge(next_or_prev_object.fullname, child.fullname, **kw)
1315
+ else:
1316
+ graph.edge(child.fullname, next_or_prev_object.fullname, **kw)
1317
+
1318
+
1186
1319
  def _generate_graphviz(
1187
1320
  step,
1188
1321
  renderer,
@@ -1355,7 +1488,7 @@ def _init_async_objects(context, steps):
1355
1488
  endpoint, stream_path = parse_path(step.path)
1356
1489
  stream_path = stream_path.strip("/")
1357
1490
  step._async_object = storey.StreamTarget(
1358
- storey.V3ioDriver(endpoint),
1491
+ storey.V3ioDriver(endpoint or config.v3io_api),
1359
1492
  stream_path,
1360
1493
  context=context,
1361
1494
  **options,
mlrun/serving/utils.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.
@@ -11,23 +11,18 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
+
14
15
  import threading
15
16
  import time
16
17
  import traceback
17
18
  from typing import Dict, Union
18
19
 
19
20
  import mlrun
20
- from mlrun.api.schemas import (
21
- ModelEndpoint,
22
- ModelEndpointMetadata,
23
- ModelEndpointSpec,
24
- ModelEndpointStatus,
25
- ModelMonitoringMode,
26
- )
21
+ import mlrun.common.model_monitoring
22
+ import mlrun.common.schemas
27
23
  from mlrun.artifacts import ModelArtifact # noqa: F401
28
24
  from mlrun.config import config
29
25
  from mlrun.utils import logger, now_date, parse_versioned_object_uri
30
- from mlrun.utils.model_monitoring import EndpointType
31
26
 
32
27
  from .server import GraphServer
33
28
  from .utils import StepToDict, _extract_input_data, _update_result_body
@@ -265,11 +260,20 @@ class V2ModelServer(StepToDict):
265
260
  # get model health operation
266
261
  setattr(event, "terminated", True)
267
262
  if self.ready:
268
- event.body = self.context.Response()
263
+ # Generate a response, confirming that the model is ready
264
+ event.body = self.context.Response(
265
+ status_code=200,
266
+ body=bytes(
267
+ f"Model {self.name} is ready (event_id = {event_id})",
268
+ encoding="utf-8",
269
+ ),
270
+ )
271
+
269
272
  else:
270
273
  event.body = self.context.Response(
271
274
  status_code=408, body=b"model not ready"
272
275
  )
276
+
273
277
  return event
274
278
 
275
279
  elif op == "" and event.method == "GET":
@@ -404,11 +408,12 @@ class _ModelLogPusher:
404
408
  return base_data
405
409
 
406
410
  def push(self, start, request, resp=None, op=None, error=None):
411
+ start_str = start.isoformat(sep=" ", timespec="microseconds")
407
412
  if error:
408
413
  data = self.base_data()
409
414
  data["request"] = request
410
415
  data["op"] = op
411
- data["when"] = str(start)
416
+ data["when"] = start_str
412
417
  message = str(error)
413
418
  if self.verbose:
414
419
  message = f"{message}\n{traceback.format_exc()}"
@@ -445,7 +450,7 @@ class _ModelLogPusher:
445
450
  data["request"] = request
446
451
  data["op"] = op
447
452
  data["resp"] = resp
448
- data["when"] = str(start)
453
+ data["when"] = start_str
449
454
  data["microsec"] = microsec
450
455
  if getattr(self.model, "metrics", None):
451
456
  data["metrics"] = self.model.metrics
@@ -486,7 +491,7 @@ def _init_endpoint_record(
486
491
  versioned_model_name = f"{model.name}:latest"
487
492
 
488
493
  # Generating model endpoint ID based on function uri and model version
489
- uid = mlrun.utils.model_monitoring.create_model_endpoint_id(
494
+ uid = mlrun.common.model_monitoring.create_model_endpoint_uid(
490
495
  function_uri=graph_server.function_uri, versioned_model=versioned_model_name
491
496
  ).uid
492
497
 
@@ -498,11 +503,11 @@ def _init_endpoint_record(
498
503
  logger.info("Creating a new model endpoint record", endpoint_id=uid)
499
504
 
500
505
  try:
501
- model_endpoint = ModelEndpoint(
502
- metadata=ModelEndpointMetadata(
506
+ model_endpoint = mlrun.common.schemas.ModelEndpoint(
507
+ metadata=mlrun.common.schemas.ModelEndpointMetadata(
503
508
  project=project, labels=model.labels, uid=uid
504
509
  ),
505
- spec=ModelEndpointSpec(
510
+ spec=mlrun.common.schemas.ModelEndpointSpec(
506
511
  function_uri=graph_server.function_uri,
507
512
  model=versioned_model_name,
508
513
  model_class=model.__class__.__name__,
@@ -511,18 +516,21 @@ def _init_endpoint_record(
511
516
  project=project, kind="stream"
512
517
  ),
513
518
  active=True,
514
- monitoring_mode=ModelMonitoringMode.enabled
519
+ monitoring_mode=mlrun.common.model_monitoring.ModelMonitoringMode.enabled
515
520
  if model.context.server.track_models
516
- else ModelMonitoringMode.disabled,
521
+ else mlrun.common.model_monitoring.ModelMonitoringMode.disabled,
522
+ ),
523
+ status=mlrun.common.schemas.ModelEndpointStatus(
524
+ endpoint_type=mlrun.common.model_monitoring.EndpointType.NODE_EP
517
525
  ),
518
- status=ModelEndpointStatus(endpoint_type=EndpointType.NODE_EP),
519
526
  )
520
527
 
521
528
  db = mlrun.get_run_db()
529
+
522
530
  db.create_model_endpoint(
523
531
  project=project,
524
- endpoint_id=model_endpoint.metadata.uid,
525
- model_endpoint=model_endpoint,
532
+ endpoint_id=uid,
533
+ model_endpoint=model_endpoint.dict(),
526
534
  )
527
535
 
528
536
  except Exception as e:
mlrun/utils/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -18,4 +18,3 @@ from .clones import get_git_username_password_from_token # noqa
18
18
  from .helpers import * # noqa
19
19
  from .http import * # noqa
20
20
  from .logger import * # noqa
21
- from .vault import * # noqa
mlrun/utils/async_http.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.
@@ -134,6 +134,13 @@ class _CustomRequestContext(_RequestContext):
134
134
  params = self._params_list[-1]
135
135
 
136
136
  headers = {k: v for k, v in params.headers.items() if v is not None}
137
+
138
+ # enrich user agent
139
+ # will help traceability and debugging
140
+ headers[
141
+ aiohttp.hdrs.USER_AGENT
142
+ ] = f"{aiohttp.http.SERVER_SOFTWARE} mlrun/{config.version}"
143
+
137
144
  response: typing.Optional[
138
145
  aiohttp.ClientResponse
139
146
  ] = await self._request_func(
@@ -1,4 +1,4 @@
1
- # Copyright 2021 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
mlrun/utils/clones.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.
@@ -51,7 +51,7 @@ def get_git_username_password_from_token(token):
51
51
  # Github's access tokens have a known prefix according to their type. See
52
52
  # https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-authentication-to-github#githubs-token-formats
53
53
  # We distinguish new fine-grained access tokens (begin with "github_pat_" from classic tokens.
54
- if token.startswith("github_pat_"):
54
+ if token.startswith("github_pat_") or token.startswith("glpat"):
55
55
  username = "oauth2"
56
56
  password = token
57
57
  else:
@@ -0,0 +1,65 @@
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 multiprocessing
16
+ import typing
17
+
18
+ from mlrun.utils import logger
19
+
20
+
21
+ def evaluate_condition_in_separate_process(
22
+ condition: str, context: typing.Dict[str, typing.Any], timeout: int = 5
23
+ ):
24
+
25
+ if not condition:
26
+ return True
27
+
28
+ receiver, sender = multiprocessing.Pipe()
29
+ p = multiprocessing.Process(
30
+ target=_evaluate_condition_wrapper,
31
+ args=(sender, condition, context),
32
+ )
33
+ p.start()
34
+ if receiver.poll(timeout):
35
+ result = receiver.recv()
36
+ p.join()
37
+ return result
38
+ else:
39
+ p.kill()
40
+ logger.warning(
41
+ f"Condition evaluation timed out after {timeout} seconds. Ignoring condition",
42
+ condition=condition,
43
+ )
44
+ return True
45
+
46
+
47
+ def _evaluate_condition_wrapper(
48
+ connection, condition: str, context: typing.Dict[str, typing.Any]
49
+ ):
50
+ connection.send(_evaluate_condition(condition, context))
51
+ return connection.close()
52
+
53
+
54
+ def _evaluate_condition(condition: str, context: typing.Dict[str, typing.Any]):
55
+
56
+ import jinja2.sandbox
57
+
58
+ jinja_env = jinja2.sandbox.SandboxedEnvironment()
59
+ template = jinja_env.from_string(condition)
60
+ result = template.render(**context)
61
+ if result.lower() in ["0", "no", "n", "f", "false", "off"]:
62
+ return False
63
+
64
+ # if the condition is not a boolean, we ignore the condition
65
+ return True
mlrun/utils/db.py ADDED
@@ -0,0 +1,52 @@
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 pickle
16
+ from datetime import datetime
17
+
18
+ from sqlalchemy.orm import class_mapper
19
+
20
+
21
+ class BaseModel:
22
+ def to_dict(self, exclude=None):
23
+ """
24
+ NOTE - this function (currently) does not handle serializing relationships
25
+ """
26
+ exclude = exclude or []
27
+ mapper = class_mapper(self.__class__)
28
+ columns = [column.key for column in mapper.columns if column.key not in exclude]
29
+ get_key_value = (
30
+ lambda c: (c, getattr(self, c).isoformat())
31
+ if isinstance(getattr(self, c), datetime)
32
+ else (c, getattr(self, c))
33
+ )
34
+ return dict(map(get_key_value, columns))
35
+
36
+
37
+ class HasStruct(BaseModel):
38
+ @property
39
+ def struct(self):
40
+ return pickle.loads(self.body)
41
+
42
+ @struct.setter
43
+ def struct(self, value):
44
+ self.body = pickle.dumps(value)
45
+
46
+ def to_dict(self, exclude=None):
47
+ """
48
+ NOTE - this function (currently) does not handle serializing relationships
49
+ """
50
+ exclude = exclude or []
51
+ exclude.append("body")
52
+ return super().to_dict(exclude)