mlrun 1.3.3__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.3.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.3.dist-info/RECORD +0 -381
  441. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
  442. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
  443. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
  444. {mlrun-1.3.3.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.
@@ -12,33 +12,32 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  #
15
-
16
-
15
+ import json
17
16
  import os
18
17
  import typing
18
+ import warnings
19
19
 
20
20
  import sqlalchemy.orm
21
21
 
22
22
  import mlrun.api.api.endpoints.functions
23
23
  import mlrun.api.api.utils
24
- import mlrun.api.schemas
25
- import mlrun.api.schemas.model_endpoints
24
+ import mlrun.api.crud.runtimes.nuclio.function
26
25
  import mlrun.api.utils.singletons.k8s
27
26
  import mlrun.artifacts
27
+ import mlrun.common.model_monitoring as model_monitoring_constants
28
+ import mlrun.common.schemas
29
+ import mlrun.common.schemas.model_endpoints
28
30
  import mlrun.config
29
31
  import mlrun.datastore.store_resources
30
32
  import mlrun.errors
31
33
  import mlrun.feature_store
32
- import mlrun.model_monitoring.constants as model_monitoring_constants
33
34
  import mlrun.model_monitoring.helpers
34
- import mlrun.runtimes.function
35
35
  import mlrun.utils.helpers
36
36
  import mlrun.utils.model_monitoring
37
37
  import mlrun.utils.v3io_clients
38
+ from mlrun.model_monitoring.stores import get_model_endpoint_store
38
39
  from mlrun.utils import logger
39
40
 
40
- from .model_endpoint_store import get_model_endpoint_target
41
-
42
41
 
43
42
  class ModelEndpoints:
44
43
  """Provide different methods for handling model endpoints such as listing, writing and deleting"""
@@ -47,12 +46,17 @@ class ModelEndpoints:
47
46
  self,
48
47
  db_session: sqlalchemy.orm.Session,
49
48
  access_key: str,
50
- model_endpoint: mlrun.api.schemas.ModelEndpoint,
51
- auth_info: mlrun.api.schemas.AuthInfo = mlrun.api.schemas.AuthInfo(),
52
- ) -> mlrun.api.schemas.ModelEndpoint:
53
- # TODO: deprecated, remove in 1.5.0.
49
+ model_endpoint: mlrun.common.schemas.ModelEndpoint,
50
+ auth_info: mlrun.common.schemas.AuthInfo = mlrun.common.schemas.AuthInfo(),
51
+ ) -> mlrun.common.schemas.ModelEndpoint:
52
+ # TODO: deprecated in 1.3.0, remove in 1.5.0.
53
+ warnings.warn(
54
+ "This is deprecated in 1.3.0, and will be removed in 1.5.0."
55
+ "Please use create_model_endpoint() for create or patch_model_endpoint() for update",
56
+ FutureWarning,
57
+ )
54
58
  """
55
- Either create or updates the record of a given ModelEndpoint object.
59
+ Either create or updates the record of a given `ModelEndpoint` object.
56
60
  Leaving here for backwards compatibility, remove in 1.5.0.
57
61
 
58
62
  :param db_session: A session that manages the current dialog with the database
@@ -60,7 +64,7 @@ class ModelEndpoints:
60
64
  :param model_endpoint: Model endpoint object to update
61
65
  :param auth_info: The auth info of the request
62
66
 
63
- :return: Model endpoint object.
67
+ :return: `ModelEndpoint` object.
64
68
  """
65
69
 
66
70
  return self.create_model_endpoint(
@@ -70,16 +74,16 @@ class ModelEndpoints:
70
74
  def create_model_endpoint(
71
75
  self,
72
76
  db_session: sqlalchemy.orm.Session,
73
- model_endpoint: mlrun.api.schemas.ModelEndpoint,
74
- ) -> mlrun.api.schemas.ModelEndpoint:
77
+ model_endpoint: mlrun.common.schemas.ModelEndpoint,
78
+ ) -> mlrun.common.schemas.ModelEndpoint:
75
79
  """
76
80
  Creates model endpoint record in DB. The DB target type is defined under
77
- mlrun.config.model_endpoint_monitoring.store_type (KV by default).
81
+ `mlrun.config.model_endpoint_monitoring.store_type` (V3IO-NOSQL by default).
78
82
 
79
83
  :param db_session: A session that manages the current dialog with the database.
80
84
  :param model_endpoint: Model endpoint object to update.
81
85
 
82
- :return: Model endpoint object.
86
+ :return: `ModelEndpoint` object.
83
87
  """
84
88
 
85
89
  if model_endpoint.spec.model_uri or model_endpoint.status.feature_stats:
@@ -107,23 +111,22 @@ class ModelEndpoints:
107
111
  if not model_endpoint.status.feature_stats and hasattr(
108
112
  model_obj, "feature_stats"
109
113
  ):
110
- model_endpoint.status.feature_stats = model_obj.feature_stats
111
-
114
+ model_endpoint.status.feature_stats = model_obj.spec.feature_stats
112
115
  # Get labels from model object if not found in model endpoint object
113
- if not model_endpoint.spec.label_names and hasattr(model_obj, "outputs"):
116
+ if not model_endpoint.spec.label_names and model_obj.spec.outputs:
114
117
  model_label_names = [
115
- self._clean_feature_name(f.name) for f in model_obj.outputs
118
+ self._clean_feature_name(f.name) for f in model_obj.spec.outputs
116
119
  ]
117
120
  model_endpoint.spec.label_names = model_label_names
118
121
 
119
122
  # Get algorithm from model object if not found in model endpoint object
120
- if not model_endpoint.spec.algorithm and hasattr(model_obj, "algorithm"):
121
- model_endpoint.spec.algorithm = model_obj.algorithm
123
+ if not model_endpoint.spec.algorithm and model_obj.spec.algorithm:
124
+ model_endpoint.spec.algorithm = model_obj.spec.algorithm
122
125
 
123
126
  # Create monitoring feature set if monitoring found in model endpoint object
124
127
  if (
125
128
  model_endpoint.spec.monitoring_mode
126
- == mlrun.api.schemas.ModelMonitoringMode.enabled.value
129
+ == mlrun.common.model_monitoring.ModelMonitoringMode.enabled.value
127
130
  ):
128
131
  monitoring_feature_set = self.create_monitoring_feature_set(
129
132
  model_endpoint, model_obj, db_session, run_db
@@ -158,18 +161,18 @@ class ModelEndpoints:
158
161
  logger.info("Creating model endpoint", endpoint_id=model_endpoint.metadata.uid)
159
162
 
160
163
  # Write the new model endpoint
161
- model_endpoint_target = get_model_endpoint_target(
164
+ model_endpoint_store = get_model_endpoint_store(
162
165
  project=model_endpoint.metadata.project,
163
166
  )
164
- model_endpoint_target.write_model_endpoint(endpoint=model_endpoint)
167
+ model_endpoint_store.write_model_endpoint(endpoint=model_endpoint.flat_dict())
165
168
 
166
169
  logger.info("Model endpoint created", endpoint_id=model_endpoint.metadata.uid)
167
170
 
168
171
  return model_endpoint
169
172
 
170
- @staticmethod
171
173
  def create_monitoring_feature_set(
172
- model_endpoint: mlrun.api.schemas.ModelEndpoint,
174
+ self,
175
+ model_endpoint: mlrun.common.schemas.ModelEndpoint,
173
176
  model_obj: mlrun.artifacts.ModelArtifact,
174
177
  db_session: sqlalchemy.orm.Session,
175
178
  run_db: mlrun.db.sqldb.SQLDB,
@@ -195,29 +198,29 @@ class ModelEndpoints:
195
198
 
196
199
  feature_set = mlrun.feature_store.FeatureSet(
197
200
  f"monitoring-{serving_function_name}-{model_name}",
198
- entities=["endpoint_id"],
199
- timestamp_key="timestamp",
201
+ entities=[model_monitoring_constants.EventFieldType.ENDPOINT_ID],
202
+ timestamp_key=model_monitoring_constants.EventFieldType.TIMESTAMP,
200
203
  description=f"Monitoring feature set for endpoint: {model_endpoint.spec.model}",
201
204
  )
202
205
  feature_set.metadata.project = model_endpoint.metadata.project
203
206
 
204
207
  feature_set.metadata.labels = {
205
- "endpoint_id": model_endpoint.metadata.uid,
206
- "model_class": model_endpoint.spec.model_class,
208
+ model_monitoring_constants.EventFieldType.ENDPOINT_ID: model_endpoint.metadata.uid,
209
+ model_monitoring_constants.EventFieldType.MODEL_CLASS: model_endpoint.spec.model_class,
207
210
  }
208
211
 
209
212
  # Add features to the feature set according to the model object
210
- if model_obj.inputs.values():
211
- for feature in model_obj.inputs.values():
213
+ if model_obj.spec.inputs:
214
+ for feature in model_obj.spec.inputs:
212
215
  feature_set.add_feature(
213
216
  mlrun.feature_store.Feature(
214
217
  name=feature.name, value_type=feature.value_type
215
218
  )
216
219
  )
217
220
  # Check if features can be found within the feature vector
218
- elif model_obj.feature_vector:
221
+ elif model_obj.spec.feature_vector:
219
222
  _, name, _, tag, _ = mlrun.utils.helpers.parse_artifact_uri(
220
- model_obj.feature_vector
223
+ model_obj.spec.feature_vector
221
224
  )
222
225
  fv = run_db.get_feature_vector(
223
226
  name=name, project=model_endpoint.metadata.project, tag=tag
@@ -236,16 +239,22 @@ class ModelEndpoints:
236
239
 
237
240
  # Define parquet target for this feature set
238
241
  parquet_path = (
239
- f"v3io:///projects/{model_endpoint.metadata.project}"
240
- f"/model-endpoints/parquet/key={model_endpoint.metadata.uid}"
242
+ self._get_monitoring_parquet_path(
243
+ db_session=db_session, project=model_endpoint.metadata.project
244
+ )
245
+ + f"/key={model_endpoint.metadata.uid}"
246
+ )
247
+
248
+ parquet_target = mlrun.datastore.targets.ParquetTarget(
249
+ model_monitoring_constants.FileTargetKind.PARQUET, parquet_path
241
250
  )
242
- parquet_target = mlrun.datastore.targets.ParquetTarget("parquet", parquet_path)
243
251
  driver = mlrun.datastore.targets.get_target_driver(parquet_target, feature_set)
244
- driver.update_resource_status("created")
252
+
245
253
  feature_set.set_targets(
246
254
  [mlrun.datastore.targets.ParquetTarget(path=parquet_path)],
247
255
  with_defaults=False,
248
256
  )
257
+ driver.update_resource_status("created")
249
258
 
250
259
  # Save the new feature set
251
260
  feature_set._override_run_db(db_session)
@@ -258,10 +267,39 @@ class ModelEndpoints:
258
267
 
259
268
  return feature_set
260
269
 
270
+ @staticmethod
271
+ def _get_monitoring_parquet_path(
272
+ db_session: sqlalchemy.orm.Session, project: str
273
+ ) -> str:
274
+ """Getting model monitoring parquet target for the current project. The parquet target path is based on the
275
+ project artifact path. If project artifact path is not defined, the parquet target path will be based on MLRun
276
+ artifact path.
277
+
278
+ :param db_session: A session that manages the current dialog with the database. Will be used in this function
279
+ to get the project record from DB.
280
+ :param project: Project name.
281
+
282
+ :return: Monitoring parquet target path.
283
+ """
284
+
285
+ # Get the artifact path from the project record that was stored in the DB
286
+ project_obj = mlrun.api.crud.projects.Projects().get_project(
287
+ session=db_session, name=project
288
+ )
289
+ artifact_path = project_obj.spec.artifact_path
290
+ # Generate monitoring parquet path value
291
+ parquet_path = mlrun.mlconf.get_model_monitoring_file_target_path(
292
+ project=project,
293
+ kind=model_monitoring_constants.FileTargetKind.PARQUET,
294
+ target="offline",
295
+ artifact_path=artifact_path,
296
+ )
297
+ return parquet_path
298
+
261
299
  @staticmethod
262
300
  def _validate_length_features_and_labels(model_endpoint):
263
301
  """
264
- Validate that the length of feature_stats is equal to the length of feature_names and label_names
302
+ Validate that the length of feature_stats is equal to the length of `feature_names` and `label_names`
265
303
 
266
304
  :param model_endpoint: An object representing the model endpoint.
267
305
  """
@@ -288,8 +326,8 @@ class ModelEndpoints:
288
326
  self, model_endpoint
289
327
  ) -> typing.Tuple[typing.Dict, typing.List]:
290
328
  """
291
- Create a clean matching version of feature names for both feature_stats and feature_names. Please note that
292
- label names exist only in feature_stats and label_names.
329
+ Create a clean matching version of feature names for both `feature_stats` and `feature_names`. Please note that
330
+ label names exist only in `feature_stats` and `label_names`.
293
331
 
294
332
  :param model_endpoint: An object representing the model endpoint.
295
333
  :return: A tuple of:
@@ -312,36 +350,42 @@ class ModelEndpoints:
312
350
  clean_feature_names.append(clean_name)
313
351
  return clean_feature_stats, clean_feature_names
314
352
 
315
- @staticmethod
316
353
  def patch_model_endpoint(
354
+ self,
317
355
  project: str,
318
356
  endpoint_id: str,
319
357
  attributes: dict,
320
- ) -> mlrun.api.schemas.ModelEndpoint:
358
+ ) -> mlrun.common.schemas.ModelEndpoint:
321
359
  """
322
360
  Update a model endpoint record with a given attributes.
323
361
 
324
362
  :param project: The name of the project.
325
363
  :param endpoint_id: The unique id of the model endpoint.
326
364
  :param attributes: Dictionary of attributes that will be used for update the model endpoint. Note that the keys
327
- of the attributes dictionary should exist in the KV table. More details about the model
365
+ of the attributes dictionary should exist in the DB table. More details about the model
328
366
  endpoint available attributes can be found under
329
- :py:class:`~mlrun.api.schemas.ModelEndpoint`.
367
+ :py:class:`~mlrun.common.schemas.ModelEndpoint`.
330
368
 
331
- :return: A patched ModelEndpoint object.
369
+ :return: A patched `ModelEndpoint` object.
332
370
  """
333
371
 
334
- model_endpoint_target = get_model_endpoint_target(
372
+ # Generate a model endpoint store object and apply the update process
373
+ model_endpoint_store = get_model_endpoint_store(
335
374
  project=project,
336
375
  )
337
- model_endpoint_target.update_model_endpoint(
376
+ model_endpoint_store.update_model_endpoint(
338
377
  endpoint_id=endpoint_id, attributes=attributes
339
378
  )
340
379
 
341
- return model_endpoint_target.get_model_endpoint(
342
- endpoint_id=endpoint_id, start="now-1h", end="now"
380
+ logger.info("Model endpoint table updated", endpoint_id=endpoint_id)
381
+
382
+ # Get the patched model endpoint record
383
+ model_endpoint_record = model_endpoint_store.get_model_endpoint(
384
+ endpoint_id=endpoint_id,
343
385
  )
344
386
 
387
+ return self._convert_into_model_endpoint_object(endpoint=model_endpoint_record)
388
+
345
389
  @staticmethod
346
390
  def delete_model_endpoint(
347
391
  project: str,
@@ -353,59 +397,83 @@ class ModelEndpoints:
353
397
  :param project: The name of the project.
354
398
  :param endpoint_id: The id of the endpoint.
355
399
  """
356
- model_endpoint_target = get_model_endpoint_target(
400
+ model_endpoint_store = get_model_endpoint_store(
357
401
  project=project,
358
402
  )
359
- model_endpoint_target.delete_model_endpoint(endpoint_id=endpoint_id)
360
403
 
361
- @staticmethod
404
+ model_endpoint_store.delete_model_endpoint(endpoint_id=endpoint_id)
405
+
406
+ logger.info("Model endpoint table cleared", endpoint_id=endpoint_id)
407
+
362
408
  def get_model_endpoint(
363
- auth_info: mlrun.api.schemas.AuthInfo,
409
+ self,
410
+ auth_info: mlrun.common.schemas.AuthInfo,
364
411
  project: str,
365
412
  endpoint_id: str,
366
413
  metrics: typing.List[str] = None,
367
414
  start: str = "now-1h",
368
415
  end: str = "now",
369
416
  feature_analysis: bool = False,
370
- ) -> mlrun.api.schemas.ModelEndpoint:
417
+ ) -> mlrun.common.schemas.ModelEndpoint:
371
418
  """Get a single model endpoint object. You can apply different time series metrics that will be added to the
372
419
  result.
373
420
 
374
- :param auth_info: The auth info of the request
375
- :param project: The name of the project
376
- :param endpoint_id: The unique id of the model endpoint.
377
- :param metrics: A list of metrics to return for the model endpoint. There are pre-defined metrics for
378
- model endpoints such as predictions_per_second and latency_avg_5m but also custom
379
- metrics defined by the user. Please note that these metrics are stored in the time
380
- series DB and the results will be appeared under model_endpoint.spec.metrics.
381
- :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
382
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
383
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` =
384
- days), or 0 for the earliest time.
385
- :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
386
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
387
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` =
388
- days), or 0 for the earliest time.
389
- :param feature_analysis: When True, the base feature statistics and current feature statistics will be added to
390
- the output of the resulting object.
391
-
392
- :return: A ModelEndpoint object.
421
+ :param auth_info: The auth info of the request
422
+ :param project: The name of the project
423
+ :param endpoint_id: The unique id of the model endpoint.
424
+ :param metrics: A list of metrics to return for the model endpoint. There are pre-defined
425
+ metrics for model endpoints such as predictions_per_second and
426
+ latency_avg_5m but also custom metrics defined by the user. Please note that
427
+ these metrics are stored in the time series DB and the results will be
428
+ appeared under `model_endpoint.spec.metrics`.
429
+ :param start: The start time of the metrics. Can be represented by a string containing an
430
+ RFC 3339 time, a Unix timestamp in milliseconds, a relative time (`'now'` or
431
+ `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or
432
+ 0 for the earliest time.
433
+ :param end: The end time of the metrics. Can be represented by a string containing an
434
+ RFC 3339 time, a Unix timestamp in milliseconds, a relative time (`'now'` or
435
+ `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or
436
+ 0 for the earliest time.
437
+ :param feature_analysis: When True, the base feature statistics and current feature statistics will
438
+ be added to the output of the resulting object.
439
+
440
+ :return: A `ModelEndpoint` object.
393
441
  """
394
442
 
395
- model_endpoint_target = get_model_endpoint_target(
443
+ logger.info(
444
+ "Getting model endpoint record from DB",
445
+ endpoint_id=endpoint_id,
446
+ )
447
+
448
+ # Generate a model endpoint store object and get the model endpoint record as a dictionary
449
+ model_endpoint_store = get_model_endpoint_store(
396
450
  project=project, access_key=auth_info.data_session
397
451
  )
398
- return model_endpoint_target.get_model_endpoint(
452
+
453
+ model_endpoint_record = model_endpoint_store.get_model_endpoint(
399
454
  endpoint_id=endpoint_id,
400
- metrics=metrics,
401
- start=start,
402
- end=end,
403
- feature_analysis=feature_analysis,
404
455
  )
405
456
 
406
- @staticmethod
457
+ # Convert to `ModelEndpoint` object
458
+ model_endpoint_object = self._convert_into_model_endpoint_object(
459
+ endpoint=model_endpoint_record, feature_analysis=feature_analysis
460
+ )
461
+
462
+ # If time metrics were provided, retrieve the results from the time series DB
463
+ if metrics:
464
+ self._add_real_time_metrics(
465
+ model_endpoint_store=model_endpoint_store,
466
+ model_endpoint_object=model_endpoint_object,
467
+ metrics=metrics,
468
+ start=start,
469
+ end=end,
470
+ )
471
+
472
+ return model_endpoint_object
473
+
407
474
  def list_model_endpoints(
408
- auth_info: mlrun.api.schemas.AuthInfo,
475
+ self,
476
+ auth_info: mlrun.common.schemas.AuthInfo,
409
477
  project: str,
410
478
  model: str = None,
411
479
  function: str = None,
@@ -415,10 +483,11 @@ class ModelEndpoints:
415
483
  end: str = "now",
416
484
  top_level: bool = False,
417
485
  uids: typing.List[str] = None,
418
- ) -> mlrun.api.schemas.model_endpoints.ModelEndpointList:
486
+ ) -> mlrun.common.schemas.ModelEndpointList:
419
487
  """
420
- Returns a list of ModelEndpointState objects. Each object represents the current state of a model endpoint.
421
- This functions supports filtering by the following parameters:
488
+ Returns a list of `ModelEndpoint` objects, wrapped in `ModelEndpointList` object. Each `ModelEndpoint`
489
+ object represents the current state of a model endpoint. This functions supports filtering by the following
490
+ parameters:
422
491
  1) model
423
492
  2) function
424
493
  3) labels
@@ -435,22 +504,22 @@ class ModelEndpoints:
435
504
  :param model: The name of the model to filter by.
436
505
  :param function: The name of the function to filter by.
437
506
  :param labels: A list of labels to filter by. Label filters work by either filtering a specific value of a
438
- label (i.e. list("key==value")) or by looking for the existence of a given key (i.e. "key").
507
+ label (i.e. list("key=value")) or by looking for the existence of a given key (i.e. "key").
439
508
  :param metrics: A list of metrics to return for each endpoint. There are pre-defined metrics for model
440
- endpoints such as predictions_per_second and latency_avg_5m but also custom metrics defined
441
- by the user. Please note that these metrics are stored in the time series DB and the results
442
- will be appeared under model_endpoint.spec.metrics of each endpoint.
509
+ endpoints such as `predictions_per_second` and `latency_avg_5m` but also custom metrics
510
+ defined by the user. Please note that these metrics are stored in the time series DB and the
511
+ results will be appeared under model_endpoint.spec.metrics of each endpoint.
443
512
  :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339 time,
444
513
  a Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where `m`
445
514
  = minutes, `h` = hours, and `'d'` = days), or 0 for the earliest time.
446
515
  :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339 time,
447
516
  a Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where `m`
448
517
  = minutes, `h` = hours, and `'d'` = days), or 0 for the earliest time.
449
- :param top_level: If True will return only routers and endpoint that are NOT children of any router.
450
- :param uids: Will return ModelEndpointList of endpoints with uid in uids.
518
+ :param top_level: If True, return only routers and endpoints that are NOT children of any router.
519
+ :param uids: List of model endpoint unique ids to include in the result.
451
520
 
452
- :return: An object of ModelEndpointList which is literally a list of model endpoints along with some metadata.
453
- To get a standard list of model endpoints use ModelEndpointList.endpoints.
521
+ :return: An object of `ModelEndpointList` which is literally a list of model endpoints along with some metadata.
522
+ To get a standard list of model endpoints use `ModelEndpointList.endpoints`.
454
523
  """
455
524
 
456
525
  logger.info(
@@ -466,39 +535,181 @@ class ModelEndpoints:
466
535
  uids=uids,
467
536
  )
468
537
 
469
- endpoint_target = get_model_endpoint_target(
538
+ # Initialize an empty model endpoints list
539
+ endpoint_list = mlrun.common.schemas.model_endpoints.ModelEndpointList(
540
+ endpoints=[]
541
+ )
542
+
543
+ # Generate a model endpoint store object and get a list of model endpoint dictionaries
544
+ endpoint_store = get_model_endpoint_store(
470
545
  access_key=auth_info.data_session, project=project
471
546
  )
472
547
 
473
- # Initialize an empty model endpoints list
474
- endpoint_list = mlrun.api.schemas.model_endpoints.ModelEndpointList(
475
- endpoints=[]
548
+ endpoint_dictionary_list = endpoint_store.list_model_endpoints(
549
+ function=function,
550
+ model=model,
551
+ labels=labels,
552
+ top_level=top_level,
553
+ uids=uids,
476
554
  )
477
555
 
478
- # If list of model endpoint ids was not provided, retrieve it from the DB
479
- if uids is None:
480
- uids = endpoint_target.list_model_endpoints(
481
- function=function, model=model, labels=labels, top_level=top_level
482
- )
556
+ for endpoint_dict in endpoint_dictionary_list:
483
557
 
484
- # Add each relevant model endpoint to the model endpoints list
485
- for endpoint_id in uids:
486
- endpoint = endpoint_target.get_model_endpoint(
487
- metrics=metrics,
488
- endpoint_id=endpoint_id,
489
- start=start,
490
- end=end,
558
+ # Convert to `ModelEndpoint` object
559
+ endpoint_obj = self._convert_into_model_endpoint_object(
560
+ endpoint=endpoint_dict
491
561
  )
492
- endpoint_list.endpoints.append(endpoint)
562
+
563
+ # If time metrics were provided, retrieve the results from the time series DB
564
+ if metrics:
565
+ self._add_real_time_metrics(
566
+ model_endpoint_store=endpoint_store,
567
+ model_endpoint_object=endpoint_obj,
568
+ metrics=metrics,
569
+ start=start,
570
+ end=end,
571
+ )
572
+
573
+ # Add the `ModelEndpoint` object into the model endpoints list
574
+ endpoint_list.endpoints.append(endpoint_obj)
493
575
 
494
576
  return endpoint_list
495
577
 
578
+ @staticmethod
579
+ def _add_real_time_metrics(
580
+ model_endpoint_store: mlrun.model_monitoring.stores.ModelEndpointStore,
581
+ model_endpoint_object: mlrun.common.schemas.ModelEndpoint,
582
+ metrics: typing.List[str] = None,
583
+ start: str = "now-1h",
584
+ end: str = "now",
585
+ ) -> mlrun.common.schemas.ModelEndpoint:
586
+ """Add real time metrics from the time series DB to a provided `ModelEndpoint` object. The real time metrics
587
+ will be stored under `ModelEndpoint.status.metrics.real_time`
588
+
589
+ :param model_endpoint_store: `ModelEndpointStore` object that will be used for communicating with the database
590
+ and querying the required metrics.
591
+ :param model_endpoint_object: `ModelEndpoint` object that will be filled with the relevant
592
+ real time metrics.
593
+ :param metrics: A list of metrics to return for each endpoint. There are pre-defined metrics for
594
+ model endpoints such as `predictions_per_second` and `latency_avg_5m` but also
595
+ custom metrics defined by the user. Please note that these metrics are stored in
596
+ the time series DB and the results will be appeared under
597
+ model_endpoint.spec.metrics of each endpoint.
598
+ :param start: The start time of the metrics. Can be represented by a string containing an RFC
599
+ 3339 time, a Unix timestamp in milliseconds, a relative time (`'now'` or
600
+ `'now-[0-9]+[mhd]'`, where `m`= minutes, `h` = hours, and `'d'` = days), or 0
601
+ for the earliest time.
602
+ :param end: The end time of the metrics. Can be represented by a string containing an RFC
603
+ 3339 time, a Unix timestamp in milliseconds, a relative time (`'now'` or
604
+ `'now-[0-9]+[mhd]'`, where `m`= minutes, `h` = hours, and `'d'` = days), or 0
605
+ for the earliest time.
606
+
607
+ """
608
+ if model_endpoint_object.status.metrics is None:
609
+ model_endpoint_object.status.metrics = {}
610
+
611
+ endpoint_metrics = model_endpoint_store.get_endpoint_real_time_metrics(
612
+ endpoint_id=model_endpoint_object.metadata.uid,
613
+ start=start,
614
+ end=end,
615
+ metrics=metrics,
616
+ )
617
+ if endpoint_metrics:
618
+ model_endpoint_object.status.metrics[
619
+ model_monitoring_constants.EventKeyMetrics.REAL_TIME
620
+ ] = endpoint_metrics
621
+ return model_endpoint_object
622
+
623
+ def _convert_into_model_endpoint_object(
624
+ self, endpoint: typing.Dict[str, typing.Any], feature_analysis: bool = False
625
+ ) -> mlrun.common.schemas.ModelEndpoint:
626
+ """
627
+ Create a `ModelEndpoint` object according to a provided model endpoint dictionary.
628
+
629
+ :param endpoint: Dictinoary that represents a DB record of a model endpoint which need to be converted
630
+ into a valid `ModelEndpoint` object.
631
+ :param feature_analysis: When True, the base feature statistics and current feature statistics will be added to
632
+ the output of the resulting object.
633
+
634
+ :return: A `ModelEndpoint` object.
635
+ """
636
+
637
+ # Convert into `ModelEndpoint` object
638
+ endpoint_obj = mlrun.common.schemas.ModelEndpoint().from_flat_dict(endpoint)
639
+
640
+ # If feature analysis was applied, add feature stats and current stats to the model endpoint result
641
+ if feature_analysis and endpoint_obj.spec.feature_names:
642
+
643
+ endpoint_features = self.get_endpoint_features(
644
+ feature_names=endpoint_obj.spec.feature_names,
645
+ feature_stats=endpoint_obj.status.feature_stats,
646
+ current_stats=endpoint_obj.status.current_stats,
647
+ )
648
+ if endpoint_features:
649
+ endpoint_obj.status.features = endpoint_features
650
+ # Add the latest drift measures results (calculated by the model monitoring batch)
651
+ drift_measures = self._json_loads_if_not_none(
652
+ endpoint.get(
653
+ model_monitoring_constants.EventFieldType.DRIFT_MEASURES
654
+ )
655
+ )
656
+ endpoint_obj.status.drift_measures = drift_measures
657
+
658
+ return endpoint_obj
659
+
660
+ @staticmethod
661
+ def get_endpoint_features(
662
+ feature_names: typing.List[str],
663
+ feature_stats: dict = None,
664
+ current_stats: dict = None,
665
+ ) -> typing.List[mlrun.common.schemas.Features]:
666
+ """
667
+ Getting a new list of features that exist in feature_names along with their expected (feature_stats) and
668
+ actual (current_stats) stats. The expected stats were calculated during the creation of the model endpoint,
669
+ usually based on the data from the Model Artifact. The actual stats are based on the results from the latest
670
+ model monitoring batch job.
671
+
672
+ param feature_names: List of feature names.
673
+ param feature_stats: Dictionary of feature stats that were stored during the creation of the model endpoint
674
+ object.
675
+ param current_stats: Dictionary of the latest stats that were stored during the last run of the model monitoring
676
+ batch job.
677
+
678
+ return: List of feature objects. Each feature has a name, weight, expected values, and actual values. More info
679
+ can be found under `mlrun.common.schemas.Features`.
680
+ """
681
+
682
+ # Initialize feature and current stats dictionaries
683
+ safe_feature_stats = feature_stats or {}
684
+ safe_current_stats = current_stats or {}
685
+
686
+ # Create feature object and add it to a general features list
687
+ features = []
688
+ for name in feature_names:
689
+ if feature_stats is not None and name not in feature_stats:
690
+ logger.warn("Feature missing from 'feature_stats'", name=name)
691
+ if current_stats is not None and name not in current_stats:
692
+ logger.warn("Feature missing from 'current_stats'", name=name)
693
+ f = mlrun.common.schemas.Features.new(
694
+ name, safe_feature_stats.get(name), safe_current_stats.get(name)
695
+ )
696
+ features.append(f)
697
+ return features
698
+
699
+ @staticmethod
700
+ def _json_loads_if_not_none(field: typing.Any) -> typing.Any:
701
+ return (
702
+ json.loads(field)
703
+ if field and field != "null" and field is not None
704
+ else None
705
+ )
706
+
496
707
  def deploy_monitoring_functions(
497
708
  self,
498
709
  project: str,
499
710
  model_monitoring_access_key: str,
500
711
  db_session: sqlalchemy.orm.Session,
501
- auth_info: mlrun.api.schemas.AuthInfo,
712
+ auth_info: mlrun.common.schemas.AuthInfo,
502
713
  tracking_policy: mlrun.utils.model_monitoring.TrackingPolicy,
503
714
  ):
504
715
  """
@@ -526,7 +737,7 @@ class ModelEndpoints:
526
737
  )
527
738
 
528
739
  def verify_project_has_no_model_endpoints(self, project_name: str):
529
- auth_info = mlrun.api.schemas.AuthInfo(
740
+ auth_info = mlrun.common.schemas.AuthInfo(
530
741
  data_session=os.getenv("V3IO_ACCESS_KEY")
531
742
  )
532
743
 
@@ -539,13 +750,14 @@ class ModelEndpoints:
539
750
  f"Project {project_name} can not be deleted since related resources found: model endpoints"
540
751
  )
541
752
 
542
- def delete_model_endpoints_resources(self, project_name: str):
753
+ @staticmethod
754
+ def delete_model_endpoints_resources(project_name: str):
543
755
  """
544
756
  Delete all model endpoints resources.
545
757
 
546
758
  :param project_name: The name of the project.
547
759
  """
548
- auth_info = mlrun.api.schemas.AuthInfo(
760
+ auth_info = mlrun.common.schemas.AuthInfo(
549
761
  data_session=os.getenv("V3IO_ACCESS_KEY")
550
762
  )
551
763
 
@@ -554,19 +766,21 @@ class ModelEndpoints:
554
766
  if not mlrun.mlconf.igz_version or not mlrun.mlconf.v3io_api:
555
767
  return
556
768
 
557
- endpoints = self.list_model_endpoints(auth_info, project_name)
558
-
559
- endpoint_target = get_model_endpoint_target(
769
+ # Generate a model endpoint store object and get a list of model endpoint dictionaries
770
+ endpoint_store = get_model_endpoint_store(
560
771
  access_key=auth_info.data_session, project=project_name
561
772
  )
562
- endpoint_target.delete_model_endpoints_resources(endpoints)
773
+ endpoints = endpoint_store.list_model_endpoints()
774
+
775
+ # Delete model endpoints resources from databases using the model endpoint store object
776
+ endpoint_store.delete_model_endpoints_resources(endpoints)
563
777
 
564
- @staticmethod
565
778
  def deploy_model_monitoring_stream_processing(
779
+ self,
566
780
  project: str,
567
781
  model_monitoring_access_key: str,
568
782
  db_session: sqlalchemy.orm.Session,
569
- auth_info: mlrun.api.schemas.AuthInfo,
783
+ auth_info: mlrun.common.schemas.AuthInfo,
570
784
  tracking_policy: mlrun.utils.model_monitoring.TrackingPolicy,
571
785
  ):
572
786
  """
@@ -587,7 +801,7 @@ class ModelEndpoints:
587
801
  )
588
802
  try:
589
803
  # validate that the model monitoring stream has not yet been deployed
590
- mlrun.runtimes.function.get_nuclio_deploy_status(
804
+ mlrun.api.crud.runtimes.nuclio.function.get_nuclio_deploy_status(
591
805
  name="model-monitoring-stream",
592
806
  project=project,
593
807
  tag="",
@@ -603,8 +817,17 @@ class ModelEndpoints:
603
817
  "Deploying model monitoring stream processing function", project=project
604
818
  )
605
819
 
820
+ # Get parquet target value for model monitoring stream function
821
+ parquet_target = self._get_monitoring_parquet_path(
822
+ db_session=db_session, project=project
823
+ )
824
+
606
825
  fn = mlrun.model_monitoring.helpers.initial_model_monitoring_stream_processing_function(
607
- project, model_monitoring_access_key, db_session, tracking_policy
826
+ project=project,
827
+ model_monitoring_access_key=model_monitoring_access_key,
828
+ tracking_policy=tracking_policy,
829
+ auth_info=auth_info,
830
+ parquet_target=parquet_target,
608
831
  )
609
832
 
610
833
  mlrun.api.api.endpoints.functions._build_function(
@@ -616,7 +839,7 @@ class ModelEndpoints:
616
839
  project: str,
617
840
  model_monitoring_access_key: str,
618
841
  db_session: sqlalchemy.orm.Session,
619
- auth_info: mlrun.api.schemas.AuthInfo,
842
+ auth_info: mlrun.common.schemas.AuthInfo,
620
843
  tracking_policy: mlrun.utils.model_monitoring.TrackingPolicy,
621
844
  ):
622
845
  """
@@ -700,7 +923,7 @@ class ModelEndpoints:
700
923
  return feature_name.replace(" ", "_").replace("(", "").replace(")", "")
701
924
 
702
925
  @staticmethod
703
- def get_access_key(auth_info: mlrun.api.schemas.AuthInfo):
926
+ def get_access_key(auth_info: mlrun.common.schemas.AuthInfo):
704
927
  """
705
928
  Getting access key from the current data session. This method is usually used to verify that the session
706
929
  is valid and contains an access key.
@@ -739,7 +962,7 @@ class ModelEndpoints:
739
962
 
740
963
  @staticmethod
741
964
  def _convert_to_cron_string(
742
- cron_trigger: mlrun.api.schemas.schedule.ScheduleCronTrigger,
965
+ cron_trigger: mlrun.common.schemas.schedule.ScheduleCronTrigger,
743
966
  ):
744
967
  """Converting the batch interval `ScheduleCronTrigger` into a cron trigger expression"""
745
968
  return "{} {} {} * *".format(