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

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

Potentially problematic release.


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

Files changed (444) hide show
  1. mlrun/__init__.py +3 -3
  2. mlrun/__main__.py +79 -37
  3. mlrun/api/__init__.py +1 -1
  4. mlrun/api/api/__init__.py +1 -1
  5. mlrun/api/api/api.py +4 -4
  6. mlrun/api/api/deps.py +10 -21
  7. mlrun/api/api/endpoints/__init__.py +1 -1
  8. mlrun/api/api/endpoints/artifacts.py +64 -36
  9. mlrun/api/api/endpoints/auth.py +4 -4
  10. mlrun/api/api/endpoints/background_tasks.py +11 -11
  11. mlrun/api/api/endpoints/client_spec.py +5 -5
  12. mlrun/api/api/endpoints/clusterization_spec.py +6 -4
  13. mlrun/api/api/endpoints/feature_store.py +124 -115
  14. mlrun/api/api/endpoints/files.py +22 -14
  15. mlrun/api/api/endpoints/frontend_spec.py +28 -21
  16. mlrun/api/api/endpoints/functions.py +142 -87
  17. mlrun/api/api/endpoints/grafana_proxy.py +89 -442
  18. mlrun/api/api/endpoints/healthz.py +20 -7
  19. mlrun/api/api/endpoints/hub.py +320 -0
  20. mlrun/api/api/endpoints/internal/__init__.py +1 -1
  21. mlrun/api/api/endpoints/internal/config.py +1 -1
  22. mlrun/api/api/endpoints/internal/memory_reports.py +9 -9
  23. mlrun/api/api/endpoints/logs.py +11 -11
  24. mlrun/api/api/endpoints/model_endpoints.py +74 -70
  25. mlrun/api/api/endpoints/operations.py +13 -9
  26. mlrun/api/api/endpoints/pipelines.py +93 -88
  27. mlrun/api/api/endpoints/projects.py +35 -35
  28. mlrun/api/api/endpoints/runs.py +69 -27
  29. mlrun/api/api/endpoints/runtime_resources.py +28 -28
  30. mlrun/api/api/endpoints/schedules.py +98 -41
  31. mlrun/api/api/endpoints/secrets.py +37 -32
  32. mlrun/api/api/endpoints/submit.py +12 -12
  33. mlrun/api/api/endpoints/tags.py +20 -22
  34. mlrun/api/api/utils.py +251 -42
  35. mlrun/api/constants.py +1 -1
  36. mlrun/api/crud/__init__.py +18 -15
  37. mlrun/api/crud/artifacts.py +10 -10
  38. mlrun/api/crud/client_spec.py +4 -4
  39. mlrun/api/crud/clusterization_spec.py +3 -3
  40. mlrun/api/crud/feature_store.py +54 -46
  41. mlrun/api/crud/functions.py +3 -3
  42. mlrun/api/crud/hub.py +312 -0
  43. mlrun/api/crud/logs.py +11 -9
  44. mlrun/api/crud/model_monitoring/__init__.py +3 -3
  45. mlrun/api/crud/model_monitoring/grafana.py +435 -0
  46. mlrun/api/crud/model_monitoring/model_endpoints.py +352 -129
  47. mlrun/api/crud/notifications.py +149 -0
  48. mlrun/api/crud/pipelines.py +67 -52
  49. mlrun/api/crud/projects.py +51 -23
  50. mlrun/api/crud/runs.py +7 -5
  51. mlrun/api/crud/runtime_resources.py +13 -13
  52. mlrun/api/{db/filedb → crud/runtimes}/__init__.py +1 -1
  53. mlrun/api/crud/runtimes/nuclio/__init__.py +14 -0
  54. mlrun/api/crud/runtimes/nuclio/function.py +505 -0
  55. mlrun/api/crud/runtimes/nuclio/helpers.py +310 -0
  56. mlrun/api/crud/secrets.py +88 -46
  57. mlrun/api/crud/tags.py +5 -5
  58. mlrun/api/db/__init__.py +1 -1
  59. mlrun/api/db/base.py +102 -54
  60. mlrun/api/db/init_db.py +2 -3
  61. mlrun/api/db/session.py +4 -12
  62. mlrun/api/db/sqldb/__init__.py +1 -1
  63. mlrun/api/db/sqldb/db.py +439 -196
  64. mlrun/api/db/sqldb/helpers.py +1 -1
  65. mlrun/api/db/sqldb/models/__init__.py +3 -3
  66. mlrun/api/db/sqldb/models/models_mysql.py +82 -64
  67. mlrun/api/db/sqldb/models/models_sqlite.py +76 -64
  68. mlrun/api/db/sqldb/session.py +27 -20
  69. mlrun/api/initial_data.py +82 -24
  70. mlrun/api/launcher.py +196 -0
  71. mlrun/api/main.py +91 -22
  72. mlrun/api/middlewares.py +6 -5
  73. mlrun/api/migrations_mysql/env.py +1 -1
  74. mlrun/api/migrations_mysql/versions/28383af526f3_market_place_to_hub.py +40 -0
  75. mlrun/api/migrations_mysql/versions/32bae1b0e29c_increase_timestamp_fields_precision.py +1 -1
  76. mlrun/api/migrations_mysql/versions/4903aef6a91d_tag_foreign_key_and_cascades.py +1 -1
  77. mlrun/api/migrations_mysql/versions/5f1351c88a19_adding_background_tasks_table.py +1 -1
  78. mlrun/api/migrations_mysql/versions/88e656800d6a_add_requested_logs_column_and_index_to_.py +1 -1
  79. mlrun/api/migrations_mysql/versions/9d16de5f03a7_adding_data_versions_table.py +1 -1
  80. mlrun/api/migrations_mysql/versions/b86f5b53f3d7_adding_name_and_updated_to_runs_table.py +1 -1
  81. mlrun/api/migrations_mysql/versions/c4af40b0bf61_init.py +1 -1
  82. mlrun/api/migrations_mysql/versions/c905d15bd91d_notifications.py +72 -0
  83. mlrun/api/migrations_mysql/versions/ee041e8fdaa0_adding_next_run_time_column_to_schedule_.py +1 -1
  84. mlrun/api/migrations_sqlite/env.py +1 -1
  85. mlrun/api/migrations_sqlite/versions/11f8dd2dc9fe_init.py +1 -1
  86. mlrun/api/migrations_sqlite/versions/1c954f8cb32d_schedule_last_run_uri.py +1 -1
  87. mlrun/api/migrations_sqlite/versions/2b6d23c715aa_adding_feature_sets.py +1 -1
  88. mlrun/api/migrations_sqlite/versions/4acd9430b093_market_place_to_hub.py +77 -0
  89. mlrun/api/migrations_sqlite/versions/6401142f2d7c_adding_next_run_time_column_to_schedule_.py +1 -1
  90. mlrun/api/migrations_sqlite/versions/64d90a1a69bc_adding_background_tasks_table.py +1 -1
  91. mlrun/api/migrations_sqlite/versions/803438ecd005_add_requested_logs_column_to_runs.py +1 -1
  92. mlrun/api/migrations_sqlite/versions/863114f0c659_refactoring_feature_set.py +1 -1
  93. mlrun/api/migrations_sqlite/versions/959ae00528ad_notifications.py +63 -0
  94. mlrun/api/migrations_sqlite/versions/accf9fc83d38_adding_data_versions_table.py +1 -1
  95. mlrun/api/migrations_sqlite/versions/b68e8e897a28_schedule_labels.py +1 -1
  96. mlrun/api/migrations_sqlite/versions/bcd0c1f9720c_adding_project_labels.py +1 -1
  97. mlrun/api/migrations_sqlite/versions/cf21882f938e_schedule_id.py +1 -1
  98. mlrun/api/migrations_sqlite/versions/d781f58f607f_tag_object_name_string.py +1 -1
  99. mlrun/api/migrations_sqlite/versions/deac06871ace_adding_marketplace_sources_table.py +1 -1
  100. mlrun/api/migrations_sqlite/versions/e1dd5983c06b_schedule_concurrency_limit.py +1 -1
  101. mlrun/api/migrations_sqlite/versions/e5594ed3ab53_adding_name_and_updated_to_runs_table.py +1 -1
  102. mlrun/api/migrations_sqlite/versions/f4249b4ba6fa_adding_feature_vectors.py +1 -1
  103. mlrun/api/migrations_sqlite/versions/f7b5a1a03629_adding_feature_labels.py +1 -1
  104. mlrun/api/schemas/__init__.py +216 -138
  105. mlrun/api/utils/__init__.py +1 -1
  106. mlrun/api/utils/asyncio.py +1 -1
  107. mlrun/api/utils/auth/__init__.py +1 -1
  108. mlrun/api/utils/auth/providers/__init__.py +1 -1
  109. mlrun/api/utils/auth/providers/base.py +7 -7
  110. mlrun/api/utils/auth/providers/nop.py +6 -7
  111. mlrun/api/utils/auth/providers/opa.py +17 -17
  112. mlrun/api/utils/auth/verifier.py +36 -34
  113. mlrun/api/utils/background_tasks.py +24 -24
  114. mlrun/{builder.py → api/utils/builder.py} +216 -123
  115. mlrun/api/utils/clients/__init__.py +1 -1
  116. mlrun/api/utils/clients/chief.py +19 -4
  117. mlrun/api/utils/clients/iguazio.py +106 -60
  118. mlrun/api/utils/clients/log_collector.py +1 -1
  119. mlrun/api/utils/clients/nuclio.py +23 -23
  120. mlrun/api/utils/clients/protocols/grpc.py +2 -2
  121. mlrun/api/utils/db/__init__.py +1 -1
  122. mlrun/api/utils/db/alembic.py +1 -1
  123. mlrun/api/utils/db/backup.py +1 -1
  124. mlrun/api/utils/db/mysql.py +24 -25
  125. mlrun/api/utils/db/sql_collation.py +1 -1
  126. mlrun/api/utils/db/sqlite_migration.py +2 -2
  127. mlrun/api/utils/events/__init__.py +14 -0
  128. mlrun/api/utils/events/base.py +57 -0
  129. mlrun/api/utils/events/events_factory.py +41 -0
  130. mlrun/api/utils/events/iguazio.py +217 -0
  131. mlrun/api/utils/events/nop.py +55 -0
  132. mlrun/api/utils/helpers.py +16 -13
  133. mlrun/api/utils/memory_reports.py +1 -1
  134. mlrun/api/utils/periodic.py +6 -3
  135. mlrun/api/utils/projects/__init__.py +1 -1
  136. mlrun/api/utils/projects/follower.py +33 -33
  137. mlrun/api/utils/projects/leader.py +36 -34
  138. mlrun/api/utils/projects/member.py +27 -27
  139. mlrun/api/utils/projects/remotes/__init__.py +1 -1
  140. mlrun/api/utils/projects/remotes/follower.py +13 -13
  141. mlrun/api/utils/projects/remotes/leader.py +10 -10
  142. mlrun/api/utils/projects/remotes/nop_follower.py +27 -21
  143. mlrun/api/utils/projects/remotes/nop_leader.py +17 -16
  144. mlrun/api/utils/scheduler.py +140 -51
  145. mlrun/api/utils/singletons/__init__.py +1 -1
  146. mlrun/api/utils/singletons/db.py +9 -15
  147. mlrun/api/utils/singletons/k8s.py +677 -5
  148. mlrun/api/utils/singletons/logs_dir.py +1 -1
  149. mlrun/api/utils/singletons/project_member.py +1 -1
  150. mlrun/api/utils/singletons/scheduler.py +1 -1
  151. mlrun/artifacts/__init__.py +2 -2
  152. mlrun/artifacts/base.py +8 -2
  153. mlrun/artifacts/dataset.py +5 -3
  154. mlrun/artifacts/manager.py +7 -1
  155. mlrun/artifacts/model.py +15 -4
  156. mlrun/artifacts/plots.py +1 -1
  157. mlrun/common/__init__.py +1 -1
  158. mlrun/common/constants.py +15 -0
  159. mlrun/common/model_monitoring.py +209 -0
  160. mlrun/common/schemas/__init__.py +167 -0
  161. mlrun/{api → common}/schemas/artifact.py +13 -14
  162. mlrun/{api → common}/schemas/auth.py +10 -8
  163. mlrun/{api → common}/schemas/background_task.py +3 -3
  164. mlrun/{api → common}/schemas/client_spec.py +1 -1
  165. mlrun/{api → common}/schemas/clusterization_spec.py +3 -3
  166. mlrun/{api → common}/schemas/constants.py +21 -8
  167. mlrun/common/schemas/events.py +36 -0
  168. mlrun/{api → common}/schemas/feature_store.py +2 -1
  169. mlrun/{api → common}/schemas/frontend_spec.py +7 -6
  170. mlrun/{api → common}/schemas/function.py +5 -5
  171. mlrun/{api → common}/schemas/http.py +3 -3
  172. mlrun/common/schemas/hub.py +134 -0
  173. mlrun/{api → common}/schemas/k8s.py +3 -3
  174. mlrun/{api → common}/schemas/memory_reports.py +1 -1
  175. mlrun/common/schemas/model_endpoints.py +342 -0
  176. mlrun/common/schemas/notification.py +57 -0
  177. mlrun/{api → common}/schemas/object.py +6 -6
  178. mlrun/{api → common}/schemas/pipeline.py +3 -3
  179. mlrun/{api → common}/schemas/project.py +6 -5
  180. mlrun/common/schemas/regex.py +24 -0
  181. mlrun/common/schemas/runs.py +30 -0
  182. mlrun/{api → common}/schemas/runtime_resource.py +3 -3
  183. mlrun/{api → common}/schemas/schedule.py +19 -7
  184. mlrun/{api → common}/schemas/secret.py +3 -3
  185. mlrun/{api → common}/schemas/tag.py +2 -2
  186. mlrun/common/types.py +25 -0
  187. mlrun/config.py +152 -20
  188. mlrun/data_types/__init__.py +7 -2
  189. mlrun/data_types/data_types.py +4 -2
  190. mlrun/data_types/infer.py +1 -1
  191. mlrun/data_types/spark.py +10 -3
  192. mlrun/datastore/__init__.py +10 -3
  193. mlrun/datastore/azure_blob.py +1 -1
  194. mlrun/datastore/base.py +185 -53
  195. mlrun/datastore/datastore.py +1 -1
  196. mlrun/datastore/filestore.py +1 -1
  197. mlrun/datastore/google_cloud_storage.py +1 -1
  198. mlrun/datastore/inmem.py +4 -1
  199. mlrun/datastore/redis.py +1 -1
  200. mlrun/datastore/s3.py +1 -1
  201. mlrun/datastore/sources.py +192 -70
  202. mlrun/datastore/spark_udf.py +44 -0
  203. mlrun/datastore/store_resources.py +4 -4
  204. mlrun/datastore/targets.py +115 -45
  205. mlrun/datastore/utils.py +127 -5
  206. mlrun/datastore/v3io.py +1 -1
  207. mlrun/datastore/wasbfs/__init__.py +1 -1
  208. mlrun/datastore/wasbfs/fs.py +1 -1
  209. mlrun/db/__init__.py +7 -5
  210. mlrun/db/base.py +112 -68
  211. mlrun/db/httpdb.py +445 -277
  212. mlrun/db/nopdb.py +491 -0
  213. mlrun/db/sqldb.py +112 -65
  214. mlrun/errors.py +6 -1
  215. mlrun/execution.py +44 -22
  216. mlrun/feature_store/__init__.py +1 -1
  217. mlrun/feature_store/api.py +143 -95
  218. mlrun/feature_store/common.py +16 -20
  219. mlrun/feature_store/feature_set.py +42 -12
  220. mlrun/feature_store/feature_vector.py +32 -21
  221. mlrun/feature_store/ingestion.py +9 -12
  222. mlrun/feature_store/retrieval/__init__.py +3 -2
  223. mlrun/feature_store/retrieval/base.py +388 -66
  224. mlrun/feature_store/retrieval/dask_merger.py +63 -151
  225. mlrun/feature_store/retrieval/job.py +30 -12
  226. mlrun/feature_store/retrieval/local_merger.py +40 -133
  227. mlrun/feature_store/retrieval/spark_merger.py +129 -127
  228. mlrun/feature_store/retrieval/storey_merger.py +173 -0
  229. mlrun/feature_store/steps.py +132 -15
  230. mlrun/features.py +8 -3
  231. mlrun/frameworks/__init__.py +1 -1
  232. mlrun/frameworks/_common/__init__.py +1 -1
  233. mlrun/frameworks/_common/artifacts_library.py +1 -1
  234. mlrun/frameworks/_common/mlrun_interface.py +1 -1
  235. mlrun/frameworks/_common/model_handler.py +1 -1
  236. mlrun/frameworks/_common/plan.py +1 -1
  237. mlrun/frameworks/_common/producer.py +1 -1
  238. mlrun/frameworks/_common/utils.py +1 -1
  239. mlrun/frameworks/_dl_common/__init__.py +1 -1
  240. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -1
  241. mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
  242. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +1 -1
  243. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +1 -1
  244. mlrun/frameworks/_dl_common/model_handler.py +1 -1
  245. mlrun/frameworks/_dl_common/utils.py +1 -1
  246. mlrun/frameworks/_ml_common/__init__.py +1 -1
  247. mlrun/frameworks/_ml_common/artifacts_library.py +1 -1
  248. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -1
  249. mlrun/frameworks/_ml_common/loggers/logger.py +1 -1
  250. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
  251. mlrun/frameworks/_ml_common/model_handler.py +1 -1
  252. mlrun/frameworks/_ml_common/pkl_model_server.py +13 -1
  253. mlrun/frameworks/_ml_common/plan.py +1 -1
  254. mlrun/frameworks/_ml_common/plans/__init__.py +1 -1
  255. mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +1 -6
  256. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +1 -1
  257. mlrun/frameworks/_ml_common/plans/dataset_plan.py +1 -1
  258. mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +1 -1
  259. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +1 -1
  260. mlrun/frameworks/_ml_common/producer.py +1 -1
  261. mlrun/frameworks/_ml_common/utils.py +1 -1
  262. mlrun/frameworks/auto_mlrun/__init__.py +1 -1
  263. mlrun/frameworks/auto_mlrun/auto_mlrun.py +1 -1
  264. mlrun/frameworks/huggingface/__init__.py +1 -1
  265. mlrun/frameworks/huggingface/model_server.py +1 -1
  266. mlrun/frameworks/lgbm/__init__.py +1 -1
  267. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -1
  268. mlrun/frameworks/lgbm/callbacks/callback.py +1 -1
  269. mlrun/frameworks/lgbm/callbacks/logging_callback.py +1 -1
  270. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +1 -1
  271. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -1
  272. mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -1
  273. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +1 -1
  274. mlrun/frameworks/lgbm/mlrun_interfaces/model_mlrun_interface.py +1 -1
  275. mlrun/frameworks/lgbm/model_handler.py +1 -1
  276. mlrun/frameworks/lgbm/model_server.py +1 -1
  277. mlrun/frameworks/lgbm/utils.py +1 -1
  278. mlrun/frameworks/onnx/__init__.py +1 -1
  279. mlrun/frameworks/onnx/dataset.py +1 -1
  280. mlrun/frameworks/onnx/mlrun_interface.py +1 -1
  281. mlrun/frameworks/onnx/model_handler.py +1 -1
  282. mlrun/frameworks/onnx/model_server.py +1 -1
  283. mlrun/frameworks/parallel_coordinates.py +1 -1
  284. mlrun/frameworks/pytorch/__init__.py +1 -1
  285. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -1
  286. mlrun/frameworks/pytorch/callbacks/callback.py +1 -1
  287. mlrun/frameworks/pytorch/callbacks/logging_callback.py +1 -1
  288. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +1 -1
  289. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +1 -1
  290. mlrun/frameworks/pytorch/callbacks_handler.py +1 -1
  291. mlrun/frameworks/pytorch/mlrun_interface.py +1 -1
  292. mlrun/frameworks/pytorch/model_handler.py +1 -1
  293. mlrun/frameworks/pytorch/model_server.py +1 -1
  294. mlrun/frameworks/pytorch/utils.py +1 -1
  295. mlrun/frameworks/sklearn/__init__.py +1 -1
  296. mlrun/frameworks/sklearn/estimator.py +1 -1
  297. mlrun/frameworks/sklearn/metric.py +1 -1
  298. mlrun/frameworks/sklearn/metrics_library.py +1 -1
  299. mlrun/frameworks/sklearn/mlrun_interface.py +1 -1
  300. mlrun/frameworks/sklearn/model_handler.py +1 -1
  301. mlrun/frameworks/sklearn/utils.py +1 -1
  302. mlrun/frameworks/tf_keras/__init__.py +1 -1
  303. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -1
  304. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  305. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +1 -1
  306. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +1 -1
  307. mlrun/frameworks/tf_keras/mlrun_interface.py +1 -1
  308. mlrun/frameworks/tf_keras/model_handler.py +1 -1
  309. mlrun/frameworks/tf_keras/model_server.py +1 -1
  310. mlrun/frameworks/tf_keras/utils.py +1 -1
  311. mlrun/frameworks/xgboost/__init__.py +1 -1
  312. mlrun/frameworks/xgboost/mlrun_interface.py +1 -1
  313. mlrun/frameworks/xgboost/model_handler.py +1 -1
  314. mlrun/frameworks/xgboost/utils.py +1 -1
  315. mlrun/k8s_utils.py +14 -765
  316. mlrun/kfpops.py +14 -17
  317. mlrun/launcher/__init__.py +13 -0
  318. mlrun/launcher/base.py +406 -0
  319. mlrun/launcher/client.py +159 -0
  320. mlrun/launcher/factory.py +50 -0
  321. mlrun/launcher/local.py +276 -0
  322. mlrun/launcher/remote.py +178 -0
  323. mlrun/lists.py +10 -2
  324. mlrun/mlutils/__init__.py +1 -1
  325. mlrun/mlutils/data.py +1 -1
  326. mlrun/mlutils/models.py +1 -1
  327. mlrun/mlutils/plots.py +1 -1
  328. mlrun/model.py +252 -14
  329. mlrun/model_monitoring/__init__.py +41 -0
  330. mlrun/model_monitoring/features_drift_table.py +1 -1
  331. mlrun/model_monitoring/helpers.py +123 -38
  332. mlrun/model_monitoring/model_endpoint.py +144 -0
  333. mlrun/model_monitoring/model_monitoring_batch.py +310 -259
  334. mlrun/model_monitoring/stores/__init__.py +106 -0
  335. mlrun/model_monitoring/stores/kv_model_endpoint_store.py +448 -0
  336. mlrun/model_monitoring/stores/model_endpoint_store.py +147 -0
  337. mlrun/model_monitoring/stores/models/__init__.py +23 -0
  338. mlrun/model_monitoring/stores/models/base.py +18 -0
  339. mlrun/model_monitoring/stores/models/mysql.py +100 -0
  340. mlrun/model_monitoring/stores/models/sqlite.py +98 -0
  341. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +370 -0
  342. mlrun/model_monitoring/stream_processing_fs.py +239 -271
  343. mlrun/package/__init__.py +163 -0
  344. mlrun/package/context_handler.py +325 -0
  345. mlrun/package/errors.py +47 -0
  346. mlrun/package/packager.py +298 -0
  347. mlrun/{runtimes/package → package/packagers}/__init__.py +3 -1
  348. mlrun/package/packagers/default_packager.py +422 -0
  349. mlrun/package/packagers/numpy_packagers.py +612 -0
  350. mlrun/package/packagers/pandas_packagers.py +968 -0
  351. mlrun/package/packagers/python_standard_library_packagers.py +616 -0
  352. mlrun/package/packagers_manager.py +786 -0
  353. mlrun/package/utils/__init__.py +53 -0
  354. mlrun/package/utils/_archiver.py +226 -0
  355. mlrun/package/utils/_formatter.py +211 -0
  356. mlrun/package/utils/_pickler.py +234 -0
  357. mlrun/package/utils/_supported_format.py +71 -0
  358. mlrun/package/utils/log_hint_utils.py +93 -0
  359. mlrun/package/utils/type_hint_utils.py +298 -0
  360. mlrun/platforms/__init__.py +1 -1
  361. mlrun/platforms/iguazio.py +34 -2
  362. mlrun/platforms/other.py +1 -1
  363. mlrun/projects/__init__.py +1 -1
  364. mlrun/projects/operations.py +14 -9
  365. mlrun/projects/pipelines.py +31 -13
  366. mlrun/projects/project.py +762 -238
  367. mlrun/render.py +49 -19
  368. mlrun/run.py +57 -326
  369. mlrun/runtimes/__init__.py +3 -9
  370. mlrun/runtimes/base.py +247 -784
  371. mlrun/runtimes/constants.py +1 -1
  372. mlrun/runtimes/daskjob.py +45 -41
  373. mlrun/runtimes/funcdoc.py +43 -7
  374. mlrun/runtimes/function.py +66 -656
  375. mlrun/runtimes/function_reference.py +1 -1
  376. mlrun/runtimes/generators.py +1 -1
  377. mlrun/runtimes/kubejob.py +99 -116
  378. mlrun/runtimes/local.py +59 -66
  379. mlrun/runtimes/mpijob/__init__.py +1 -1
  380. mlrun/runtimes/mpijob/abstract.py +13 -15
  381. mlrun/runtimes/mpijob/v1.py +3 -1
  382. mlrun/runtimes/mpijob/v1alpha1.py +1 -1
  383. mlrun/runtimes/nuclio.py +1 -1
  384. mlrun/runtimes/pod.py +51 -26
  385. mlrun/runtimes/remotesparkjob.py +3 -1
  386. mlrun/runtimes/serving.py +12 -4
  387. mlrun/runtimes/sparkjob/__init__.py +1 -2
  388. mlrun/runtimes/sparkjob/abstract.py +44 -31
  389. mlrun/runtimes/sparkjob/spark3job.py +11 -9
  390. mlrun/runtimes/utils.py +61 -42
  391. mlrun/secrets.py +16 -18
  392. mlrun/serving/__init__.py +3 -2
  393. mlrun/serving/merger.py +1 -1
  394. mlrun/serving/remote.py +1 -1
  395. mlrun/serving/routers.py +39 -42
  396. mlrun/serving/server.py +23 -13
  397. mlrun/serving/serving_wrapper.py +1 -1
  398. mlrun/serving/states.py +172 -39
  399. mlrun/serving/utils.py +1 -1
  400. mlrun/serving/v1_serving.py +1 -1
  401. mlrun/serving/v2_serving.py +29 -21
  402. mlrun/utils/__init__.py +1 -2
  403. mlrun/utils/async_http.py +8 -1
  404. mlrun/utils/azure_vault.py +1 -1
  405. mlrun/utils/clones.py +2 -2
  406. mlrun/utils/condition_evaluator.py +65 -0
  407. mlrun/utils/db.py +52 -0
  408. mlrun/utils/helpers.py +188 -13
  409. mlrun/utils/http.py +89 -54
  410. mlrun/utils/logger.py +48 -8
  411. mlrun/utils/model_monitoring.py +132 -100
  412. mlrun/utils/notifications/__init__.py +1 -1
  413. mlrun/utils/notifications/notification/__init__.py +8 -6
  414. mlrun/utils/notifications/notification/base.py +20 -14
  415. mlrun/utils/notifications/notification/console.py +7 -4
  416. mlrun/utils/notifications/notification/git.py +36 -19
  417. mlrun/utils/notifications/notification/ipython.py +10 -8
  418. mlrun/utils/notifications/notification/slack.py +18 -13
  419. mlrun/utils/notifications/notification_pusher.py +377 -56
  420. mlrun/utils/regex.py +6 -1
  421. mlrun/utils/singleton.py +1 -1
  422. mlrun/utils/v3io_clients.py +1 -1
  423. mlrun/utils/vault.py +270 -269
  424. mlrun/utils/version/__init__.py +1 -1
  425. mlrun/utils/version/version.json +2 -2
  426. mlrun/utils/version/version.py +1 -1
  427. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/METADATA +16 -10
  428. mlrun-1.4.0.dist-info/RECORD +434 -0
  429. mlrun/api/api/endpoints/marketplace.py +0 -257
  430. mlrun/api/crud/marketplace.py +0 -221
  431. mlrun/api/crud/model_monitoring/model_endpoint_store.py +0 -847
  432. mlrun/api/db/filedb/db.py +0 -518
  433. mlrun/api/schemas/marketplace.py +0 -128
  434. mlrun/api/schemas/model_endpoints.py +0 -185
  435. mlrun/db/filedb.py +0 -891
  436. mlrun/feature_store/retrieval/online.py +0 -92
  437. mlrun/model_monitoring/constants.py +0 -67
  438. mlrun/runtimes/package/context_handler.py +0 -711
  439. mlrun/runtimes/sparkjob/spark2job.py +0 -59
  440. mlrun-1.3.3rc1.dist-info/RECORD +0 -381
  441. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
  442. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
  443. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
  444. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,23 @@
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
+
16
+
17
+ def get_ModelEndpointsTable(connection_string: str = None):
18
+ """Return ModelEndpointsTable based on the provided connection string"""
19
+ if "mysql:" in connection_string:
20
+ from .mysql import ModelEndpointsTable
21
+ else:
22
+ from .sqlite import ModelEndpointsTable
23
+ return ModelEndpointsTable
@@ -0,0 +1,18 @@
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
+
16
+ from sqlalchemy.ext.declarative import declarative_base
17
+
18
+ Base = declarative_base()
@@ -0,0 +1,100 @@
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
+
16
+
17
+ import sqlalchemy.dialects
18
+ from sqlalchemy import Boolean, Column, Integer, String, Text
19
+
20
+ import mlrun.common.model_monitoring as model_monitoring_constants
21
+ from mlrun.utils.db import BaseModel
22
+
23
+ from .base import Base
24
+
25
+
26
+ class ModelEndpointsTable(Base, BaseModel):
27
+ __tablename__ = model_monitoring_constants.EventFieldType.MODEL_ENDPOINTS
28
+
29
+ uid = Column(
30
+ model_monitoring_constants.EventFieldType.UID,
31
+ String(40),
32
+ primary_key=True,
33
+ )
34
+ state = Column(model_monitoring_constants.EventFieldType.STATE, String(10))
35
+ project = Column(model_monitoring_constants.EventFieldType.PROJECT, String(40))
36
+ function_uri = Column(
37
+ model_monitoring_constants.EventFieldType.FUNCTION_URI,
38
+ String(255),
39
+ )
40
+ model = Column(model_monitoring_constants.EventFieldType.MODEL, String(255))
41
+ model_class = Column(
42
+ model_monitoring_constants.EventFieldType.MODEL_CLASS,
43
+ String(255),
44
+ )
45
+ labels = Column(model_monitoring_constants.EventFieldType.LABELS, Text)
46
+ model_uri = Column(model_monitoring_constants.EventFieldType.MODEL_URI, String(255))
47
+ stream_path = Column(model_monitoring_constants.EventFieldType.STREAM_PATH, Text)
48
+ algorithm = Column(
49
+ model_monitoring_constants.EventFieldType.ALGORITHM,
50
+ String(255),
51
+ )
52
+ active = Column(model_monitoring_constants.EventFieldType.ACTIVE, Boolean)
53
+ monitoring_mode = Column(
54
+ model_monitoring_constants.EventFieldType.MONITORING_MODE,
55
+ String(10),
56
+ )
57
+ feature_stats = Column(
58
+ model_monitoring_constants.EventFieldType.FEATURE_STATS, Text
59
+ )
60
+ current_stats = Column(
61
+ model_monitoring_constants.EventFieldType.CURRENT_STATS, Text
62
+ )
63
+ feature_names = Column(
64
+ model_monitoring_constants.EventFieldType.FEATURE_NAMES, Text
65
+ )
66
+ children = Column(model_monitoring_constants.EventFieldType.CHILDREN, Text)
67
+ label_names = Column(model_monitoring_constants.EventFieldType.LABEL_NAMES, Text)
68
+
69
+ endpoint_type = Column(
70
+ model_monitoring_constants.EventFieldType.ENDPOINT_TYPE,
71
+ String(10),
72
+ )
73
+ children_uids = Column(
74
+ model_monitoring_constants.EventFieldType.CHILDREN_UIDS, Text
75
+ )
76
+ drift_measures = Column(
77
+ model_monitoring_constants.EventFieldType.DRIFT_MEASURES, Text
78
+ )
79
+ drift_status = Column(
80
+ model_monitoring_constants.EventFieldType.DRIFT_STATUS,
81
+ String(40),
82
+ )
83
+ monitor_configuration = Column(
84
+ model_monitoring_constants.EventFieldType.MONITOR_CONFIGURATION,
85
+ Text,
86
+ )
87
+ monitoring_feature_set_uri = Column(
88
+ model_monitoring_constants.EventFieldType.FEATURE_SET_URI,
89
+ String(255),
90
+ )
91
+ first_request = Column(
92
+ model_monitoring_constants.EventFieldType.FIRST_REQUEST,
93
+ sqlalchemy.dialects.mysql.TIMESTAMP(fsp=3),
94
+ )
95
+ last_request = Column(
96
+ model_monitoring_constants.EventFieldType.LAST_REQUEST,
97
+ sqlalchemy.dialects.mysql.TIMESTAMP(fsp=3),
98
+ )
99
+ error_count = Column(model_monitoring_constants.EventFieldType.ERROR_COUNT, Integer)
100
+ metrics = Column(model_monitoring_constants.EventFieldType.METRICS, Text)
@@ -0,0 +1,98 @@
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
+
16
+
17
+ from sqlalchemy import TIMESTAMP, Boolean, Column, Integer, String, Text
18
+
19
+ import mlrun.common.model_monitoring as model_monitoring_constants
20
+ from mlrun.utils.db import BaseModel
21
+
22
+ from .base import Base
23
+
24
+
25
+ class ModelEndpointsTable(Base, BaseModel):
26
+ __tablename__ = model_monitoring_constants.EventFieldType.MODEL_ENDPOINTS
27
+
28
+ uid = Column(
29
+ model_monitoring_constants.EventFieldType.UID,
30
+ String(40),
31
+ primary_key=True,
32
+ )
33
+ state = Column(model_monitoring_constants.EventFieldType.STATE, String(10))
34
+ project = Column(model_monitoring_constants.EventFieldType.PROJECT, String(40))
35
+ function_uri = Column(
36
+ model_monitoring_constants.EventFieldType.FUNCTION_URI,
37
+ String(255),
38
+ )
39
+ model = Column(model_monitoring_constants.EventFieldType.MODEL, String(255))
40
+ model_class = Column(
41
+ model_monitoring_constants.EventFieldType.MODEL_CLASS,
42
+ String(255),
43
+ )
44
+ labels = Column(model_monitoring_constants.EventFieldType.LABELS, Text)
45
+ model_uri = Column(model_monitoring_constants.EventFieldType.MODEL_URI, String(255))
46
+ stream_path = Column(model_monitoring_constants.EventFieldType.STREAM_PATH, Text)
47
+ algorithm = Column(
48
+ model_monitoring_constants.EventFieldType.ALGORITHM,
49
+ String(255),
50
+ )
51
+ active = Column(model_monitoring_constants.EventFieldType.ACTIVE, Boolean)
52
+ monitoring_mode = Column(
53
+ model_monitoring_constants.EventFieldType.MONITORING_MODE,
54
+ String(10),
55
+ )
56
+ feature_stats = Column(
57
+ model_monitoring_constants.EventFieldType.FEATURE_STATS, Text
58
+ )
59
+ current_stats = Column(
60
+ model_monitoring_constants.EventFieldType.CURRENT_STATS, Text
61
+ )
62
+ feature_names = Column(
63
+ model_monitoring_constants.EventFieldType.FEATURE_NAMES, Text
64
+ )
65
+ children = Column(model_monitoring_constants.EventFieldType.CHILDREN, Text)
66
+ label_names = Column(model_monitoring_constants.EventFieldType.LABEL_NAMES, Text)
67
+ endpoint_type = Column(
68
+ model_monitoring_constants.EventFieldType.ENDPOINT_TYPE,
69
+ String(10),
70
+ )
71
+ children_uids = Column(
72
+ model_monitoring_constants.EventFieldType.CHILDREN_UIDS, Text
73
+ )
74
+ drift_measures = Column(
75
+ model_monitoring_constants.EventFieldType.DRIFT_MEASURES, Text
76
+ )
77
+ drift_status = Column(
78
+ model_monitoring_constants.EventFieldType.DRIFT_STATUS,
79
+ String(40),
80
+ )
81
+ monitor_configuration = Column(
82
+ model_monitoring_constants.EventFieldType.MONITOR_CONFIGURATION,
83
+ Text,
84
+ )
85
+ monitoring_feature_set_uri = Column(
86
+ model_monitoring_constants.EventFieldType.FEATURE_SET_URI,
87
+ String(255),
88
+ )
89
+ first_request = Column(
90
+ model_monitoring_constants.EventFieldType.FIRST_REQUEST,
91
+ TIMESTAMP,
92
+ )
93
+ last_request = Column(
94
+ model_monitoring_constants.EventFieldType.LAST_REQUEST,
95
+ TIMESTAMP,
96
+ )
97
+ error_count = Column(model_monitoring_constants.EventFieldType.ERROR_COUNT, Integer)
98
+ metrics = Column(model_monitoring_constants.EventFieldType.METRICS, Text)
@@ -0,0 +1,370 @@
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
+
16
+ import json
17
+ import typing
18
+ from datetime import datetime, timezone
19
+
20
+ import pandas as pd
21
+ import sqlalchemy as db
22
+
23
+ import mlrun
24
+ import mlrun.common.model_monitoring as model_monitoring_constants
25
+ import mlrun.model_monitoring.model_endpoint
26
+ import mlrun.utils.model_monitoring
27
+ import mlrun.utils.v3io_clients
28
+ from mlrun.api.db.sqldb.session import create_session, get_engine
29
+ from mlrun.utils import logger
30
+
31
+ from .model_endpoint_store import ModelEndpointStore
32
+ from .models import get_ModelEndpointsTable
33
+ from .models.base import Base
34
+
35
+
36
+ class SQLModelEndpointStore(ModelEndpointStore):
37
+
38
+ """
39
+ Handles the DB operations when the DB target is from type SQL. For the SQL operations, we use SQLAlchemy, a Python
40
+ SQL toolkit that handles the communication with the database. When using SQL for storing the model endpoints
41
+ record, the user needs to provide a valid connection string for the database.
42
+ """
43
+
44
+ _engine = None
45
+
46
+ def __init__(
47
+ self,
48
+ project: str,
49
+ sql_connection_string: str = None,
50
+ ):
51
+ """
52
+ Initialize SQL store target object.
53
+
54
+ :param project: The name of the project.
55
+ :param sql_connection_string: Valid connection string or a path to SQL database with model endpoints table.
56
+ """
57
+
58
+ super().__init__(project=project)
59
+
60
+ self.sql_connection_string = (
61
+ sql_connection_string
62
+ or mlrun.utils.model_monitoring.get_connection_string(project=self.project)
63
+ )
64
+
65
+ self.table_name = model_monitoring_constants.EventFieldType.MODEL_ENDPOINTS
66
+
67
+ self._engine = get_engine(dsn=self.sql_connection_string)
68
+ self.ModelEndpointsTable = get_ModelEndpointsTable(
69
+ connection_string=self.sql_connection_string
70
+ )
71
+ # Create table if not exist. The `metadata` contains the `ModelEndpointsTable`
72
+ if not self._engine.has_table(self.table_name):
73
+ Base.metadata.create_all(bind=self._engine)
74
+ self.model_endpoints_table = self.ModelEndpointsTable.__table__
75
+
76
+ def write_model_endpoint(self, endpoint: typing.Dict[str, typing.Any]):
77
+ """
78
+ Create a new endpoint record in the SQL table. This method also creates the model endpoints table within the
79
+ SQL database if not exist.
80
+
81
+ :param endpoint: model endpoint dictionary that will be written into the DB.
82
+ """
83
+
84
+ with self._engine.connect() as connection:
85
+ # Adjust timestamps fields
86
+ endpoint[
87
+ model_monitoring_constants.EventFieldType.FIRST_REQUEST
88
+ ] = datetime.now(timezone.utc)
89
+ endpoint[
90
+ model_monitoring_constants.EventFieldType.LAST_REQUEST
91
+ ] = datetime.now(timezone.utc)
92
+
93
+ # Convert the result into a pandas Dataframe and write it into the database
94
+ endpoint_df = pd.DataFrame([endpoint])
95
+
96
+ endpoint_df.to_sql(
97
+ self.table_name, con=connection, index=False, if_exists="append"
98
+ )
99
+
100
+ def update_model_endpoint(
101
+ self, endpoint_id: str, attributes: typing.Dict[str, typing.Any]
102
+ ):
103
+ """
104
+ Update a model endpoint record with a given attributes.
105
+
106
+ :param endpoint_id: The unique id of the model endpoint.
107
+ :param attributes: Dictionary of attributes that will be used for update the model endpoint. Note that the keys
108
+ of the attributes dictionary should exist in the SQL table.
109
+
110
+ """
111
+
112
+ # Update the model endpoint record using sqlalchemy ORM
113
+ with create_session(dsn=self.sql_connection_string) as session:
114
+ # Remove endpoint id (foreign key) from the update query
115
+ attributes.pop(model_monitoring_constants.EventFieldType.ENDPOINT_ID, None)
116
+
117
+ # Generate and commit the update session query
118
+ session.query(self.ModelEndpointsTable).filter(
119
+ self.ModelEndpointsTable.uid == endpoint_id
120
+ ).update(attributes)
121
+ session.commit()
122
+
123
+ def delete_model_endpoint(self, endpoint_id: str):
124
+ """
125
+ Deletes the SQL record of a given model endpoint id.
126
+
127
+ :param endpoint_id: The unique id of the model endpoint.
128
+ """
129
+
130
+ # Delete the model endpoint record using sqlalchemy ORM
131
+ with create_session(dsn=self.sql_connection_string) as session:
132
+ # Generate and commit the delete query
133
+ session.query(self.ModelEndpointsTable).filter_by(uid=endpoint_id).delete()
134
+ session.commit()
135
+
136
+ def get_model_endpoint(
137
+ self,
138
+ endpoint_id: str,
139
+ ) -> typing.Dict[str, typing.Any]:
140
+ """
141
+ Get a single model endpoint record.
142
+
143
+ :param endpoint_id: The unique id of the model endpoint.
144
+
145
+ :return: A model endpoint record as a dictionary.
146
+
147
+ :raise MLRunNotFoundError: If the model endpoints table was not found or the model endpoint id was not found.
148
+ """
149
+
150
+ # Get the model endpoint record using sqlalchemy ORM
151
+ with create_session(dsn=self.sql_connection_string) as session:
152
+ # Generate the get query
153
+ endpoint_record = (
154
+ session.query(self.ModelEndpointsTable)
155
+ .filter_by(uid=endpoint_id)
156
+ .one_or_none()
157
+ )
158
+
159
+ if not endpoint_record:
160
+ raise mlrun.errors.MLRunNotFoundError(f"Endpoint {endpoint_id} not found")
161
+
162
+ # Convert the database values and the table columns into a python dictionary
163
+ return endpoint_record.to_dict()
164
+
165
+ def list_model_endpoints(
166
+ self,
167
+ model: str = None,
168
+ function: str = None,
169
+ labels: typing.List[str] = None,
170
+ top_level: bool = None,
171
+ uids: typing.List = None,
172
+ ) -> typing.List[typing.Dict[str, typing.Any]]:
173
+ """
174
+ Returns a list of model endpoint dictionaries, supports filtering by model, function, labels or top level.
175
+ By default, when no filters are applied, all available model endpoints for the given project will
176
+ be listed.
177
+
178
+ :param model: The name of the model to filter by.
179
+ :param function: The name of the function to filter by.
180
+ :param labels: A list of labels to filter by. Label filters work by either filtering a specific value
181
+ of a label (i.e. list("key=value")) or by looking for the existence of a given
182
+ key (i.e. "key").
183
+ :param top_level: If True will return only routers and endpoint that are NOT children of any router.
184
+ :param uids: List of model endpoint unique ids to include in the result.
185
+
186
+ :return: A list of model endpoint dictionaries.
187
+ """
188
+
189
+ # Generate an empty model endpoints that will be filled afterwards with model endpoint dictionaries
190
+ endpoint_list = []
191
+
192
+ # Get the model endpoints records using sqlalchemy ORM
193
+ with create_session(dsn=self.sql_connection_string) as session:
194
+ # Generate the list query
195
+ query = session.query(self.ModelEndpointsTable).filter_by(
196
+ project=self.project
197
+ )
198
+
199
+ # Apply filters
200
+ if model:
201
+ query = self._filter_values(
202
+ query=query,
203
+ model_endpoints_table=self.model_endpoints_table,
204
+ key_filter=model_monitoring_constants.EventFieldType.MODEL,
205
+ filtered_values=[model],
206
+ )
207
+ if function:
208
+ query = self._filter_values(
209
+ query=query,
210
+ model_endpoints_table=self.model_endpoints_table,
211
+ key_filter=model_monitoring_constants.EventFieldType.FUNCTION,
212
+ filtered_values=[function],
213
+ )
214
+ if uids:
215
+ query = self._filter_values(
216
+ query=query,
217
+ model_endpoints_table=self.model_endpoints_table,
218
+ key_filter=model_monitoring_constants.EventFieldType.UID,
219
+ filtered_values=uids,
220
+ combined=False,
221
+ )
222
+ if top_level:
223
+ node_ep = str(mlrun.common.model_monitoring.EndpointType.NODE_EP.value)
224
+ router_ep = str(mlrun.common.model_monitoring.EndpointType.ROUTER.value)
225
+ endpoint_types = [node_ep, router_ep]
226
+ query = self._filter_values(
227
+ query=query,
228
+ model_endpoints_table=self.model_endpoints_table,
229
+ key_filter=model_monitoring_constants.EventFieldType.ENDPOINT_TYPE,
230
+ filtered_values=endpoint_types,
231
+ combined=False,
232
+ )
233
+ # Convert the results from the DB into a ModelEndpoint object and append it to the model endpoints list
234
+ for endpoint_record in query.all():
235
+ endpoint_dict = endpoint_record.to_dict()
236
+
237
+ # Filter labels
238
+ if labels and not self._validate_labels(
239
+ endpoint_dict=endpoint_dict, labels=labels
240
+ ):
241
+ continue
242
+
243
+ endpoint_list.append(endpoint_dict)
244
+
245
+ return endpoint_list
246
+
247
+ @staticmethod
248
+ def _filter_values(
249
+ query: db.orm.query.Query,
250
+ model_endpoints_table: db.Table,
251
+ key_filter: str,
252
+ filtered_values: typing.List,
253
+ combined=True,
254
+ ) -> db.orm.query.Query:
255
+ """Filtering the SQL query object according to the provided filters.
256
+
257
+ :param query: SQLAlchemy ORM query object. Includes the SELECT statements generated by the ORM
258
+ for getting the model endpoint data from the SQL table.
259
+ :param model_endpoints_table: SQLAlchemy table object that represents the model endpoints table.
260
+ :param key_filter: Key column to filter by.
261
+ :param filtered_values: List of values to filter the query the result.
262
+ :param combined: If true, then apply AND operator on the filtered values list. Otherwise, apply OR
263
+ operator.
264
+
265
+ return: SQLAlchemy ORM query object that represents the updated query with the provided
266
+ filters.
267
+ """
268
+
269
+ if combined and len(filtered_values) > 1:
270
+ raise mlrun.errors.MLRunInvalidArgumentError(
271
+ "Can't apply combined policy with multiple values"
272
+ )
273
+
274
+ if not combined:
275
+ return query.filter(
276
+ model_endpoints_table.c[key_filter].in_(filtered_values)
277
+ )
278
+
279
+ # Generating a tuple with the relevant filters
280
+ filter_query = []
281
+ for _filter in filtered_values:
282
+ filter_query.append(model_endpoints_table.c[key_filter] == _filter)
283
+
284
+ # Apply AND operator on the SQL query object with the filters tuple
285
+ return query.filter(db.and_(*filter_query))
286
+
287
+ @staticmethod
288
+ def _validate_labels(
289
+ endpoint_dict: dict,
290
+ labels: typing.List,
291
+ ) -> bool:
292
+ """Validate that the model endpoint dictionary has the provided labels. There are 2 possible cases:
293
+ 1 - Labels were provided as a list of key-values pairs (e.g. ['label_1=value_1', 'label_2=value_2']): Validate
294
+ that each pair exist in the endpoint dictionary.
295
+ 2 - Labels were provided as a list of key labels (e.g. ['label_1', 'label_2']): Validate that each key exist in
296
+ the endpoint labels dictionary.
297
+
298
+ :param endpoint_dict: Dictionary of the model endpoint records.
299
+ :param labels: List of dictionary of required labels.
300
+
301
+ :return: True if the labels exist in the endpoint labels dictionary, otherwise False.
302
+ """
303
+
304
+ # Convert endpoint labels into dictionary
305
+ endpoint_labels = json.loads(
306
+ endpoint_dict.get(model_monitoring_constants.EventFieldType.LABELS)
307
+ )
308
+
309
+ for label in labels:
310
+ # Case 1 - label is a key=value pair
311
+ if "=" in label:
312
+ lbl, value = list(map(lambda x: x.strip(), label.split("=")))
313
+ if lbl not in endpoint_labels or str(endpoint_labels[lbl]) != value:
314
+ return False
315
+ # Case 2 - label is just a key
316
+ else:
317
+ if label not in endpoint_labels:
318
+ return False
319
+
320
+ return True
321
+
322
+ def delete_model_endpoints_resources(
323
+ self, endpoints: typing.List[typing.Dict[str, typing.Any]]
324
+ ):
325
+ """
326
+ Delete all model endpoints resources in both SQL and the time series DB.
327
+
328
+ :param endpoints: A list of model endpoints flattened dictionaries.
329
+ """
330
+
331
+ for endpoint_dict in endpoints:
332
+ # Delete model endpoint record from SQL table
333
+ self.delete_model_endpoint(
334
+ endpoint_dict[model_monitoring_constants.EventFieldType.UID],
335
+ )
336
+
337
+ def get_endpoint_real_time_metrics(
338
+ self,
339
+ endpoint_id: str,
340
+ metrics: typing.List[str],
341
+ start: str = "now-1h",
342
+ end: str = "now",
343
+ access_key: str = None,
344
+ ) -> typing.Dict[str, typing.List[typing.Tuple[str, float]]]:
345
+ """
346
+ Getting metrics from the time series DB. There are pre-defined metrics for model endpoints such as
347
+ `predictions_per_second` and `latency_avg_5m` but also custom metrics defined by the user.
348
+
349
+ :param endpoint_id: The unique id of the model endpoint.
350
+ :param metrics: A list of real-time metrics to return for the model endpoint.
351
+ :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
352
+ time, a Unix timestamp in milliseconds, a relative time (`'now'` or
353
+ `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
354
+ earliest time.
355
+ :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
356
+ time, a Unix timestamp in milliseconds, a relative time (`'now'` or
357
+ `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
358
+ earliest time.
359
+ :param access_key: V3IO access key that will be used for generating Frames client object. If not
360
+ provided, the access key will be retrieved from the environment variables.
361
+
362
+ :return: A dictionary of metrics in which the key is a metric name and the value is a list of tuples that
363
+ includes timestamps and the values.
364
+ """
365
+ # # TODO : Implement this method once Perometheus is supported
366
+ logger.warning(
367
+ "Real time metrics service using Prometheus will be implemented in 1.4.0"
368
+ )
369
+
370
+ return {}