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

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

Potentially problematic release.


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

Files changed (444) hide show
  1. mlrun/__init__.py +3 -3
  2. mlrun/__main__.py +79 -37
  3. mlrun/api/__init__.py +1 -1
  4. mlrun/api/api/__init__.py +1 -1
  5. mlrun/api/api/api.py +4 -4
  6. mlrun/api/api/deps.py +10 -21
  7. mlrun/api/api/endpoints/__init__.py +1 -1
  8. mlrun/api/api/endpoints/artifacts.py +64 -36
  9. mlrun/api/api/endpoints/auth.py +4 -4
  10. mlrun/api/api/endpoints/background_tasks.py +11 -11
  11. mlrun/api/api/endpoints/client_spec.py +5 -5
  12. mlrun/api/api/endpoints/clusterization_spec.py +6 -4
  13. mlrun/api/api/endpoints/feature_store.py +124 -115
  14. mlrun/api/api/endpoints/files.py +22 -14
  15. mlrun/api/api/endpoints/frontend_spec.py +28 -21
  16. mlrun/api/api/endpoints/functions.py +142 -87
  17. mlrun/api/api/endpoints/grafana_proxy.py +89 -442
  18. mlrun/api/api/endpoints/healthz.py +20 -7
  19. mlrun/api/api/endpoints/hub.py +320 -0
  20. mlrun/api/api/endpoints/internal/__init__.py +1 -1
  21. mlrun/api/api/endpoints/internal/config.py +1 -1
  22. mlrun/api/api/endpoints/internal/memory_reports.py +9 -9
  23. mlrun/api/api/endpoints/logs.py +11 -11
  24. mlrun/api/api/endpoints/model_endpoints.py +74 -70
  25. mlrun/api/api/endpoints/operations.py +13 -9
  26. mlrun/api/api/endpoints/pipelines.py +93 -88
  27. mlrun/api/api/endpoints/projects.py +35 -35
  28. mlrun/api/api/endpoints/runs.py +69 -27
  29. mlrun/api/api/endpoints/runtime_resources.py +28 -28
  30. mlrun/api/api/endpoints/schedules.py +98 -41
  31. mlrun/api/api/endpoints/secrets.py +37 -32
  32. mlrun/api/api/endpoints/submit.py +12 -12
  33. mlrun/api/api/endpoints/tags.py +20 -22
  34. mlrun/api/api/utils.py +251 -42
  35. mlrun/api/constants.py +1 -1
  36. mlrun/api/crud/__init__.py +18 -15
  37. mlrun/api/crud/artifacts.py +10 -10
  38. mlrun/api/crud/client_spec.py +4 -4
  39. mlrun/api/crud/clusterization_spec.py +3 -3
  40. mlrun/api/crud/feature_store.py +54 -46
  41. mlrun/api/crud/functions.py +3 -3
  42. mlrun/api/crud/hub.py +312 -0
  43. mlrun/api/crud/logs.py +11 -9
  44. mlrun/api/crud/model_monitoring/__init__.py +3 -3
  45. mlrun/api/crud/model_monitoring/grafana.py +435 -0
  46. mlrun/api/crud/model_monitoring/model_endpoints.py +352 -129
  47. mlrun/api/crud/notifications.py +149 -0
  48. mlrun/api/crud/pipelines.py +67 -52
  49. mlrun/api/crud/projects.py +51 -23
  50. mlrun/api/crud/runs.py +7 -5
  51. mlrun/api/crud/runtime_resources.py +13 -13
  52. mlrun/api/{db/filedb → crud/runtimes}/__init__.py +1 -1
  53. mlrun/api/crud/runtimes/nuclio/__init__.py +14 -0
  54. mlrun/api/crud/runtimes/nuclio/function.py +505 -0
  55. mlrun/api/crud/runtimes/nuclio/helpers.py +310 -0
  56. mlrun/api/crud/secrets.py +88 -46
  57. mlrun/api/crud/tags.py +5 -5
  58. mlrun/api/db/__init__.py +1 -1
  59. mlrun/api/db/base.py +102 -54
  60. mlrun/api/db/init_db.py +2 -3
  61. mlrun/api/db/session.py +4 -12
  62. mlrun/api/db/sqldb/__init__.py +1 -1
  63. mlrun/api/db/sqldb/db.py +439 -196
  64. mlrun/api/db/sqldb/helpers.py +1 -1
  65. mlrun/api/db/sqldb/models/__init__.py +3 -3
  66. mlrun/api/db/sqldb/models/models_mysql.py +82 -64
  67. mlrun/api/db/sqldb/models/models_sqlite.py +76 -64
  68. mlrun/api/db/sqldb/session.py +27 -20
  69. mlrun/api/initial_data.py +82 -24
  70. mlrun/api/launcher.py +196 -0
  71. mlrun/api/main.py +91 -22
  72. mlrun/api/middlewares.py +6 -5
  73. mlrun/api/migrations_mysql/env.py +1 -1
  74. mlrun/api/migrations_mysql/versions/28383af526f3_market_place_to_hub.py +40 -0
  75. mlrun/api/migrations_mysql/versions/32bae1b0e29c_increase_timestamp_fields_precision.py +1 -1
  76. mlrun/api/migrations_mysql/versions/4903aef6a91d_tag_foreign_key_and_cascades.py +1 -1
  77. mlrun/api/migrations_mysql/versions/5f1351c88a19_adding_background_tasks_table.py +1 -1
  78. mlrun/api/migrations_mysql/versions/88e656800d6a_add_requested_logs_column_and_index_to_.py +1 -1
  79. mlrun/api/migrations_mysql/versions/9d16de5f03a7_adding_data_versions_table.py +1 -1
  80. mlrun/api/migrations_mysql/versions/b86f5b53f3d7_adding_name_and_updated_to_runs_table.py +1 -1
  81. mlrun/api/migrations_mysql/versions/c4af40b0bf61_init.py +1 -1
  82. mlrun/api/migrations_mysql/versions/c905d15bd91d_notifications.py +72 -0
  83. mlrun/api/migrations_mysql/versions/ee041e8fdaa0_adding_next_run_time_column_to_schedule_.py +1 -1
  84. mlrun/api/migrations_sqlite/env.py +1 -1
  85. mlrun/api/migrations_sqlite/versions/11f8dd2dc9fe_init.py +1 -1
  86. mlrun/api/migrations_sqlite/versions/1c954f8cb32d_schedule_last_run_uri.py +1 -1
  87. mlrun/api/migrations_sqlite/versions/2b6d23c715aa_adding_feature_sets.py +1 -1
  88. mlrun/api/migrations_sqlite/versions/4acd9430b093_market_place_to_hub.py +77 -0
  89. mlrun/api/migrations_sqlite/versions/6401142f2d7c_adding_next_run_time_column_to_schedule_.py +1 -1
  90. mlrun/api/migrations_sqlite/versions/64d90a1a69bc_adding_background_tasks_table.py +1 -1
  91. mlrun/api/migrations_sqlite/versions/803438ecd005_add_requested_logs_column_to_runs.py +1 -1
  92. mlrun/api/migrations_sqlite/versions/863114f0c659_refactoring_feature_set.py +1 -1
  93. mlrun/api/migrations_sqlite/versions/959ae00528ad_notifications.py +63 -0
  94. mlrun/api/migrations_sqlite/versions/accf9fc83d38_adding_data_versions_table.py +1 -1
  95. mlrun/api/migrations_sqlite/versions/b68e8e897a28_schedule_labels.py +1 -1
  96. mlrun/api/migrations_sqlite/versions/bcd0c1f9720c_adding_project_labels.py +1 -1
  97. mlrun/api/migrations_sqlite/versions/cf21882f938e_schedule_id.py +1 -1
  98. mlrun/api/migrations_sqlite/versions/d781f58f607f_tag_object_name_string.py +1 -1
  99. mlrun/api/migrations_sqlite/versions/deac06871ace_adding_marketplace_sources_table.py +1 -1
  100. mlrun/api/migrations_sqlite/versions/e1dd5983c06b_schedule_concurrency_limit.py +1 -1
  101. mlrun/api/migrations_sqlite/versions/e5594ed3ab53_adding_name_and_updated_to_runs_table.py +1 -1
  102. mlrun/api/migrations_sqlite/versions/f4249b4ba6fa_adding_feature_vectors.py +1 -1
  103. mlrun/api/migrations_sqlite/versions/f7b5a1a03629_adding_feature_labels.py +1 -1
  104. mlrun/api/schemas/__init__.py +216 -138
  105. mlrun/api/utils/__init__.py +1 -1
  106. mlrun/api/utils/asyncio.py +1 -1
  107. mlrun/api/utils/auth/__init__.py +1 -1
  108. mlrun/api/utils/auth/providers/__init__.py +1 -1
  109. mlrun/api/utils/auth/providers/base.py +7 -7
  110. mlrun/api/utils/auth/providers/nop.py +6 -7
  111. mlrun/api/utils/auth/providers/opa.py +17 -17
  112. mlrun/api/utils/auth/verifier.py +36 -34
  113. mlrun/api/utils/background_tasks.py +24 -24
  114. mlrun/{builder.py → api/utils/builder.py} +216 -123
  115. mlrun/api/utils/clients/__init__.py +1 -1
  116. mlrun/api/utils/clients/chief.py +19 -4
  117. mlrun/api/utils/clients/iguazio.py +106 -60
  118. mlrun/api/utils/clients/log_collector.py +1 -1
  119. mlrun/api/utils/clients/nuclio.py +23 -23
  120. mlrun/api/utils/clients/protocols/grpc.py +2 -2
  121. mlrun/api/utils/db/__init__.py +1 -1
  122. mlrun/api/utils/db/alembic.py +1 -1
  123. mlrun/api/utils/db/backup.py +1 -1
  124. mlrun/api/utils/db/mysql.py +24 -25
  125. mlrun/api/utils/db/sql_collation.py +1 -1
  126. mlrun/api/utils/db/sqlite_migration.py +2 -2
  127. mlrun/api/utils/events/__init__.py +14 -0
  128. mlrun/api/utils/events/base.py +57 -0
  129. mlrun/api/utils/events/events_factory.py +41 -0
  130. mlrun/api/utils/events/iguazio.py +217 -0
  131. mlrun/api/utils/events/nop.py +55 -0
  132. mlrun/api/utils/helpers.py +16 -13
  133. mlrun/api/utils/memory_reports.py +1 -1
  134. mlrun/api/utils/periodic.py +6 -3
  135. mlrun/api/utils/projects/__init__.py +1 -1
  136. mlrun/api/utils/projects/follower.py +33 -33
  137. mlrun/api/utils/projects/leader.py +36 -34
  138. mlrun/api/utils/projects/member.py +27 -27
  139. mlrun/api/utils/projects/remotes/__init__.py +1 -1
  140. mlrun/api/utils/projects/remotes/follower.py +13 -13
  141. mlrun/api/utils/projects/remotes/leader.py +10 -10
  142. mlrun/api/utils/projects/remotes/nop_follower.py +27 -21
  143. mlrun/api/utils/projects/remotes/nop_leader.py +17 -16
  144. mlrun/api/utils/scheduler.py +140 -51
  145. mlrun/api/utils/singletons/__init__.py +1 -1
  146. mlrun/api/utils/singletons/db.py +9 -15
  147. mlrun/api/utils/singletons/k8s.py +677 -5
  148. mlrun/api/utils/singletons/logs_dir.py +1 -1
  149. mlrun/api/utils/singletons/project_member.py +1 -1
  150. mlrun/api/utils/singletons/scheduler.py +1 -1
  151. mlrun/artifacts/__init__.py +2 -2
  152. mlrun/artifacts/base.py +8 -2
  153. mlrun/artifacts/dataset.py +5 -3
  154. mlrun/artifacts/manager.py +7 -1
  155. mlrun/artifacts/model.py +15 -4
  156. mlrun/artifacts/plots.py +1 -1
  157. mlrun/common/__init__.py +1 -1
  158. mlrun/common/constants.py +15 -0
  159. mlrun/common/model_monitoring.py +209 -0
  160. mlrun/common/schemas/__init__.py +167 -0
  161. mlrun/{api → common}/schemas/artifact.py +13 -14
  162. mlrun/{api → common}/schemas/auth.py +10 -8
  163. mlrun/{api → common}/schemas/background_task.py +3 -3
  164. mlrun/{api → common}/schemas/client_spec.py +1 -1
  165. mlrun/{api → common}/schemas/clusterization_spec.py +3 -3
  166. mlrun/{api → common}/schemas/constants.py +21 -8
  167. mlrun/common/schemas/events.py +36 -0
  168. mlrun/{api → common}/schemas/feature_store.py +2 -1
  169. mlrun/{api → common}/schemas/frontend_spec.py +7 -6
  170. mlrun/{api → common}/schemas/function.py +5 -5
  171. mlrun/{api → common}/schemas/http.py +3 -3
  172. mlrun/common/schemas/hub.py +134 -0
  173. mlrun/{api → common}/schemas/k8s.py +3 -3
  174. mlrun/{api → common}/schemas/memory_reports.py +1 -1
  175. mlrun/common/schemas/model_endpoints.py +342 -0
  176. mlrun/common/schemas/notification.py +57 -0
  177. mlrun/{api → common}/schemas/object.py +6 -6
  178. mlrun/{api → common}/schemas/pipeline.py +3 -3
  179. mlrun/{api → common}/schemas/project.py +6 -5
  180. mlrun/common/schemas/regex.py +24 -0
  181. mlrun/common/schemas/runs.py +30 -0
  182. mlrun/{api → common}/schemas/runtime_resource.py +3 -3
  183. mlrun/{api → common}/schemas/schedule.py +19 -7
  184. mlrun/{api → common}/schemas/secret.py +3 -3
  185. mlrun/{api → common}/schemas/tag.py +2 -2
  186. mlrun/common/types.py +25 -0
  187. mlrun/config.py +152 -20
  188. mlrun/data_types/__init__.py +7 -2
  189. mlrun/data_types/data_types.py +4 -2
  190. mlrun/data_types/infer.py +1 -1
  191. mlrun/data_types/spark.py +10 -3
  192. mlrun/datastore/__init__.py +10 -3
  193. mlrun/datastore/azure_blob.py +1 -1
  194. mlrun/datastore/base.py +185 -53
  195. mlrun/datastore/datastore.py +1 -1
  196. mlrun/datastore/filestore.py +1 -1
  197. mlrun/datastore/google_cloud_storage.py +1 -1
  198. mlrun/datastore/inmem.py +4 -1
  199. mlrun/datastore/redis.py +1 -1
  200. mlrun/datastore/s3.py +1 -1
  201. mlrun/datastore/sources.py +192 -70
  202. mlrun/datastore/spark_udf.py +44 -0
  203. mlrun/datastore/store_resources.py +4 -4
  204. mlrun/datastore/targets.py +115 -45
  205. mlrun/datastore/utils.py +127 -5
  206. mlrun/datastore/v3io.py +1 -1
  207. mlrun/datastore/wasbfs/__init__.py +1 -1
  208. mlrun/datastore/wasbfs/fs.py +1 -1
  209. mlrun/db/__init__.py +7 -5
  210. mlrun/db/base.py +112 -68
  211. mlrun/db/httpdb.py +445 -277
  212. mlrun/db/nopdb.py +491 -0
  213. mlrun/db/sqldb.py +112 -65
  214. mlrun/errors.py +6 -1
  215. mlrun/execution.py +44 -22
  216. mlrun/feature_store/__init__.py +1 -1
  217. mlrun/feature_store/api.py +143 -95
  218. mlrun/feature_store/common.py +16 -20
  219. mlrun/feature_store/feature_set.py +42 -12
  220. mlrun/feature_store/feature_vector.py +32 -21
  221. mlrun/feature_store/ingestion.py +9 -12
  222. mlrun/feature_store/retrieval/__init__.py +3 -2
  223. mlrun/feature_store/retrieval/base.py +388 -66
  224. mlrun/feature_store/retrieval/dask_merger.py +63 -151
  225. mlrun/feature_store/retrieval/job.py +30 -12
  226. mlrun/feature_store/retrieval/local_merger.py +40 -133
  227. mlrun/feature_store/retrieval/spark_merger.py +129 -127
  228. mlrun/feature_store/retrieval/storey_merger.py +173 -0
  229. mlrun/feature_store/steps.py +132 -15
  230. mlrun/features.py +8 -3
  231. mlrun/frameworks/__init__.py +1 -1
  232. mlrun/frameworks/_common/__init__.py +1 -1
  233. mlrun/frameworks/_common/artifacts_library.py +1 -1
  234. mlrun/frameworks/_common/mlrun_interface.py +1 -1
  235. mlrun/frameworks/_common/model_handler.py +1 -1
  236. mlrun/frameworks/_common/plan.py +1 -1
  237. mlrun/frameworks/_common/producer.py +1 -1
  238. mlrun/frameworks/_common/utils.py +1 -1
  239. mlrun/frameworks/_dl_common/__init__.py +1 -1
  240. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -1
  241. mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
  242. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +1 -1
  243. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +1 -1
  244. mlrun/frameworks/_dl_common/model_handler.py +1 -1
  245. mlrun/frameworks/_dl_common/utils.py +1 -1
  246. mlrun/frameworks/_ml_common/__init__.py +1 -1
  247. mlrun/frameworks/_ml_common/artifacts_library.py +1 -1
  248. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -1
  249. mlrun/frameworks/_ml_common/loggers/logger.py +1 -1
  250. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
  251. mlrun/frameworks/_ml_common/model_handler.py +1 -1
  252. mlrun/frameworks/_ml_common/pkl_model_server.py +13 -1
  253. mlrun/frameworks/_ml_common/plan.py +1 -1
  254. mlrun/frameworks/_ml_common/plans/__init__.py +1 -1
  255. mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +1 -6
  256. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +1 -1
  257. mlrun/frameworks/_ml_common/plans/dataset_plan.py +1 -1
  258. mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +1 -1
  259. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +1 -1
  260. mlrun/frameworks/_ml_common/producer.py +1 -1
  261. mlrun/frameworks/_ml_common/utils.py +1 -1
  262. mlrun/frameworks/auto_mlrun/__init__.py +1 -1
  263. mlrun/frameworks/auto_mlrun/auto_mlrun.py +1 -1
  264. mlrun/frameworks/huggingface/__init__.py +1 -1
  265. mlrun/frameworks/huggingface/model_server.py +1 -1
  266. mlrun/frameworks/lgbm/__init__.py +1 -1
  267. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -1
  268. mlrun/frameworks/lgbm/callbacks/callback.py +1 -1
  269. mlrun/frameworks/lgbm/callbacks/logging_callback.py +1 -1
  270. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +1 -1
  271. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -1
  272. mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -1
  273. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +1 -1
  274. mlrun/frameworks/lgbm/mlrun_interfaces/model_mlrun_interface.py +1 -1
  275. mlrun/frameworks/lgbm/model_handler.py +1 -1
  276. mlrun/frameworks/lgbm/model_server.py +1 -1
  277. mlrun/frameworks/lgbm/utils.py +1 -1
  278. mlrun/frameworks/onnx/__init__.py +1 -1
  279. mlrun/frameworks/onnx/dataset.py +1 -1
  280. mlrun/frameworks/onnx/mlrun_interface.py +1 -1
  281. mlrun/frameworks/onnx/model_handler.py +1 -1
  282. mlrun/frameworks/onnx/model_server.py +1 -1
  283. mlrun/frameworks/parallel_coordinates.py +1 -1
  284. mlrun/frameworks/pytorch/__init__.py +1 -1
  285. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -1
  286. mlrun/frameworks/pytorch/callbacks/callback.py +1 -1
  287. mlrun/frameworks/pytorch/callbacks/logging_callback.py +1 -1
  288. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +1 -1
  289. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +1 -1
  290. mlrun/frameworks/pytorch/callbacks_handler.py +1 -1
  291. mlrun/frameworks/pytorch/mlrun_interface.py +1 -1
  292. mlrun/frameworks/pytorch/model_handler.py +1 -1
  293. mlrun/frameworks/pytorch/model_server.py +1 -1
  294. mlrun/frameworks/pytorch/utils.py +1 -1
  295. mlrun/frameworks/sklearn/__init__.py +1 -1
  296. mlrun/frameworks/sklearn/estimator.py +1 -1
  297. mlrun/frameworks/sklearn/metric.py +1 -1
  298. mlrun/frameworks/sklearn/metrics_library.py +1 -1
  299. mlrun/frameworks/sklearn/mlrun_interface.py +1 -1
  300. mlrun/frameworks/sklearn/model_handler.py +1 -1
  301. mlrun/frameworks/sklearn/utils.py +1 -1
  302. mlrun/frameworks/tf_keras/__init__.py +1 -1
  303. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -1
  304. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  305. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +1 -1
  306. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +1 -1
  307. mlrun/frameworks/tf_keras/mlrun_interface.py +1 -1
  308. mlrun/frameworks/tf_keras/model_handler.py +1 -1
  309. mlrun/frameworks/tf_keras/model_server.py +1 -1
  310. mlrun/frameworks/tf_keras/utils.py +1 -1
  311. mlrun/frameworks/xgboost/__init__.py +1 -1
  312. mlrun/frameworks/xgboost/mlrun_interface.py +1 -1
  313. mlrun/frameworks/xgboost/model_handler.py +1 -1
  314. mlrun/frameworks/xgboost/utils.py +1 -1
  315. mlrun/k8s_utils.py +14 -765
  316. mlrun/kfpops.py +14 -17
  317. mlrun/launcher/__init__.py +13 -0
  318. mlrun/launcher/base.py +406 -0
  319. mlrun/launcher/client.py +159 -0
  320. mlrun/launcher/factory.py +50 -0
  321. mlrun/launcher/local.py +276 -0
  322. mlrun/launcher/remote.py +178 -0
  323. mlrun/lists.py +10 -2
  324. mlrun/mlutils/__init__.py +1 -1
  325. mlrun/mlutils/data.py +1 -1
  326. mlrun/mlutils/models.py +1 -1
  327. mlrun/mlutils/plots.py +1 -1
  328. mlrun/model.py +252 -14
  329. mlrun/model_monitoring/__init__.py +41 -0
  330. mlrun/model_monitoring/features_drift_table.py +1 -1
  331. mlrun/model_monitoring/helpers.py +123 -38
  332. mlrun/model_monitoring/model_endpoint.py +144 -0
  333. mlrun/model_monitoring/model_monitoring_batch.py +310 -259
  334. mlrun/model_monitoring/stores/__init__.py +106 -0
  335. mlrun/model_monitoring/stores/kv_model_endpoint_store.py +448 -0
  336. mlrun/model_monitoring/stores/model_endpoint_store.py +147 -0
  337. mlrun/model_monitoring/stores/models/__init__.py +23 -0
  338. mlrun/model_monitoring/stores/models/base.py +18 -0
  339. mlrun/model_monitoring/stores/models/mysql.py +100 -0
  340. mlrun/model_monitoring/stores/models/sqlite.py +98 -0
  341. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +370 -0
  342. mlrun/model_monitoring/stream_processing_fs.py +239 -271
  343. mlrun/package/__init__.py +163 -0
  344. mlrun/package/context_handler.py +325 -0
  345. mlrun/package/errors.py +47 -0
  346. mlrun/package/packager.py +298 -0
  347. mlrun/{runtimes/package → package/packagers}/__init__.py +3 -1
  348. mlrun/package/packagers/default_packager.py +422 -0
  349. mlrun/package/packagers/numpy_packagers.py +612 -0
  350. mlrun/package/packagers/pandas_packagers.py +968 -0
  351. mlrun/package/packagers/python_standard_library_packagers.py +616 -0
  352. mlrun/package/packagers_manager.py +786 -0
  353. mlrun/package/utils/__init__.py +53 -0
  354. mlrun/package/utils/_archiver.py +226 -0
  355. mlrun/package/utils/_formatter.py +211 -0
  356. mlrun/package/utils/_pickler.py +234 -0
  357. mlrun/package/utils/_supported_format.py +71 -0
  358. mlrun/package/utils/log_hint_utils.py +93 -0
  359. mlrun/package/utils/type_hint_utils.py +298 -0
  360. mlrun/platforms/__init__.py +1 -1
  361. mlrun/platforms/iguazio.py +34 -2
  362. mlrun/platforms/other.py +1 -1
  363. mlrun/projects/__init__.py +1 -1
  364. mlrun/projects/operations.py +14 -9
  365. mlrun/projects/pipelines.py +31 -13
  366. mlrun/projects/project.py +762 -238
  367. mlrun/render.py +49 -19
  368. mlrun/run.py +57 -326
  369. mlrun/runtimes/__init__.py +3 -9
  370. mlrun/runtimes/base.py +247 -784
  371. mlrun/runtimes/constants.py +1 -1
  372. mlrun/runtimes/daskjob.py +45 -41
  373. mlrun/runtimes/funcdoc.py +43 -7
  374. mlrun/runtimes/function.py +66 -656
  375. mlrun/runtimes/function_reference.py +1 -1
  376. mlrun/runtimes/generators.py +1 -1
  377. mlrun/runtimes/kubejob.py +99 -116
  378. mlrun/runtimes/local.py +59 -66
  379. mlrun/runtimes/mpijob/__init__.py +1 -1
  380. mlrun/runtimes/mpijob/abstract.py +13 -15
  381. mlrun/runtimes/mpijob/v1.py +3 -1
  382. mlrun/runtimes/mpijob/v1alpha1.py +1 -1
  383. mlrun/runtimes/nuclio.py +1 -1
  384. mlrun/runtimes/pod.py +51 -26
  385. mlrun/runtimes/remotesparkjob.py +3 -1
  386. mlrun/runtimes/serving.py +12 -4
  387. mlrun/runtimes/sparkjob/__init__.py +1 -2
  388. mlrun/runtimes/sparkjob/abstract.py +44 -31
  389. mlrun/runtimes/sparkjob/spark3job.py +11 -9
  390. mlrun/runtimes/utils.py +61 -42
  391. mlrun/secrets.py +16 -18
  392. mlrun/serving/__init__.py +3 -2
  393. mlrun/serving/merger.py +1 -1
  394. mlrun/serving/remote.py +1 -1
  395. mlrun/serving/routers.py +39 -42
  396. mlrun/serving/server.py +23 -13
  397. mlrun/serving/serving_wrapper.py +1 -1
  398. mlrun/serving/states.py +172 -39
  399. mlrun/serving/utils.py +1 -1
  400. mlrun/serving/v1_serving.py +1 -1
  401. mlrun/serving/v2_serving.py +29 -21
  402. mlrun/utils/__init__.py +1 -2
  403. mlrun/utils/async_http.py +8 -1
  404. mlrun/utils/azure_vault.py +1 -1
  405. mlrun/utils/clones.py +2 -2
  406. mlrun/utils/condition_evaluator.py +65 -0
  407. mlrun/utils/db.py +52 -0
  408. mlrun/utils/helpers.py +188 -13
  409. mlrun/utils/http.py +89 -54
  410. mlrun/utils/logger.py +48 -8
  411. mlrun/utils/model_monitoring.py +132 -100
  412. mlrun/utils/notifications/__init__.py +1 -1
  413. mlrun/utils/notifications/notification/__init__.py +8 -6
  414. mlrun/utils/notifications/notification/base.py +20 -14
  415. mlrun/utils/notifications/notification/console.py +7 -4
  416. mlrun/utils/notifications/notification/git.py +36 -19
  417. mlrun/utils/notifications/notification/ipython.py +10 -8
  418. mlrun/utils/notifications/notification/slack.py +18 -13
  419. mlrun/utils/notifications/notification_pusher.py +377 -56
  420. mlrun/utils/regex.py +6 -1
  421. mlrun/utils/singleton.py +1 -1
  422. mlrun/utils/v3io_clients.py +1 -1
  423. mlrun/utils/vault.py +270 -269
  424. mlrun/utils/version/__init__.py +1 -1
  425. mlrun/utils/version/version.json +2 -2
  426. mlrun/utils/version/version.py +1 -1
  427. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/METADATA +16 -10
  428. mlrun-1.4.0.dist-info/RECORD +434 -0
  429. mlrun/api/api/endpoints/marketplace.py +0 -257
  430. mlrun/api/crud/marketplace.py +0 -221
  431. mlrun/api/crud/model_monitoring/model_endpoint_store.py +0 -847
  432. mlrun/api/db/filedb/db.py +0 -518
  433. mlrun/api/schemas/marketplace.py +0 -128
  434. mlrun/api/schemas/model_endpoints.py +0 -185
  435. mlrun/db/filedb.py +0 -891
  436. mlrun/feature_store/retrieval/online.py +0 -92
  437. mlrun/model_monitoring/constants.py +0 -67
  438. mlrun/runtimes/package/context_handler.py +0 -711
  439. mlrun/runtimes/sparkjob/spark2job.py +0 -59
  440. mlrun-1.3.3rc1.dist-info/RECORD +0 -381
  441. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
  442. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
  443. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
  444. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
@@ -1,847 +0,0 @@
1
- # Copyright 2018 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 enum
17
- import json
18
- import typing
19
- from abc import ABC, abstractmethod
20
-
21
- import v3io.dataplane
22
- import v3io_frames
23
-
24
- import mlrun
25
- import mlrun.api.schemas
26
- import mlrun.model_monitoring.constants as model_monitoring_constants
27
- import mlrun.utils.model_monitoring
28
- import mlrun.utils.v3io_clients
29
- from mlrun.utils import logger
30
-
31
-
32
- class _ModelEndpointStore(ABC):
33
- """
34
- An abstract class to handle the model endpoint in the DB target.
35
- """
36
-
37
- def __init__(self, project: str):
38
- """
39
- Initialize a new model endpoint target.
40
-
41
- :param project: The name of the project.
42
- """
43
- self.project = project
44
-
45
- @abstractmethod
46
- def write_model_endpoint(self, endpoint: mlrun.api.schemas.ModelEndpoint):
47
- """
48
- Create a new endpoint record in the DB table.
49
-
50
- :param endpoint: ModelEndpoint object that will be written into the DB.
51
- """
52
- pass
53
-
54
- @abstractmethod
55
- def update_model_endpoint(self, endpoint_id: str, attributes: dict):
56
- """
57
- Update a model endpoint record with a given attributes.
58
-
59
- :param endpoint_id: The unique id of the model endpoint.
60
- :param attributes: Dictionary of attributes that will be used for update the model endpoint. Note that the keys
61
- of the attributes dictionary should exist in the KV table.
62
-
63
- """
64
- pass
65
-
66
- @abstractmethod
67
- def delete_model_endpoint(self, endpoint_id: str):
68
- """
69
- Deletes the record of a given model endpoint id.
70
-
71
- :param endpoint_id: The unique id of the model endpoint.
72
- """
73
- pass
74
-
75
- @abstractmethod
76
- def delete_model_endpoints_resources(
77
- self, endpoints: mlrun.api.schemas.model_endpoints.ModelEndpointList
78
- ):
79
- """
80
- Delete all model endpoints resources.
81
-
82
- :param endpoints: An object of ModelEndpointList which is literally a list of model endpoints along with some
83
- metadata. To get a standard list of model endpoints use ModelEndpointList.endpoints.
84
- """
85
- pass
86
-
87
- @abstractmethod
88
- def get_model_endpoint(
89
- self,
90
- metrics: typing.List[str] = None,
91
- start: str = "now-1h",
92
- end: str = "now",
93
- feature_analysis: bool = False,
94
- endpoint_id: str = None,
95
- ) -> mlrun.api.schemas.ModelEndpoint:
96
- """
97
- Get a single model endpoint object. You can apply different time series metrics that will be added to the
98
- result.
99
-
100
- :param endpoint_id: The unique id of the model endpoint.
101
- :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
102
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
103
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
104
- earliest time.
105
- :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
106
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
107
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
108
- earliest time.
109
- :param metrics: A list of metrics to return for the model endpoint. There are pre-defined metrics for
110
- model endpoints such as predictions_per_second and latency_avg_5m but also custom
111
- metrics defined by the user. Please note that these metrics are stored in the time
112
- series DB and the results will be appeared under model_endpoint.spec.metrics.
113
- :param feature_analysis: When True, the base feature statistics and current feature statistics will be added to
114
- the output of the resulting object.
115
-
116
- :return: A ModelEndpoint object.
117
- """
118
- pass
119
-
120
- @abstractmethod
121
- def list_model_endpoints(
122
- self, model: str, function: str, labels: typing.List, top_level: bool
123
- ):
124
- """
125
- Returns a list of endpoint unique ids, supports filtering by model, function,
126
- labels or top level. By default, when no filters are applied, all available endpoint ids for the given project
127
- will be listed.
128
-
129
- :param model: The name of the model to filter by.
130
- :param function: The name of the function to filter by.
131
- :param labels: A list of labels to filter by. Label filters work by either filtering a specific value
132
- of a label (i.e. list("key==value")) or by looking for the existence of a given
133
- key (i.e. "key").
134
- :param top_level: If True will return only routers and endpoint that are NOT children of any router.
135
-
136
- :return: List of model endpoints unique ids.
137
- """
138
- pass
139
-
140
-
141
- class _ModelEndpointKVStore(_ModelEndpointStore):
142
- """
143
- Handles the DB operations when the DB target is from type KV. For the KV operations, we use an instance of V3IO
144
- client and usually the KV table can be found under v3io:///users/pipelines/project-name/model-endpoints/endpoints/.
145
- """
146
-
147
- def __init__(self, access_key: str, project: str):
148
- super().__init__(project=project)
149
- # Initialize a V3IO client instance
150
- self.access_key = access_key
151
- self.client = mlrun.utils.v3io_clients.get_v3io_client(
152
- endpoint=mlrun.mlconf.v3io_api, access_key=self.access_key
153
- )
154
- # Get the KV table path and container
155
- self.path, self.container = self._get_path_and_container()
156
-
157
- def write_model_endpoint(self, endpoint: mlrun.api.schemas.ModelEndpoint):
158
- """
159
- Create a new endpoint record in the KV table.
160
-
161
- :param endpoint: ModelEndpoint object that will be written into the DB.
162
- """
163
-
164
- # Flatten the model endpoint structure in order to write it into the DB table.
165
- # More details about the model endpoint available attributes can be found under
166
- # :py:class:`~mlrun.api.schemas.ModelEndpoint`.`
167
- attributes = self.flatten_model_endpoint_attributes(endpoint)
168
-
169
- # Create or update the model endpoint record
170
- self.client.kv.put(
171
- container=self.container,
172
- table_path=self.path,
173
- key=endpoint.metadata.uid,
174
- attributes=attributes,
175
- )
176
-
177
- def update_model_endpoint(self, endpoint_id: str, attributes: dict):
178
- """
179
- Update a model endpoint record with a given attributes.
180
-
181
- :param endpoint_id: The unique id of the model endpoint.
182
- :param attributes: Dictionary of attributes that will be used for update the model endpoint. Note that the keys
183
- of the attributes dictionary should exist in the KV table. More details about the model
184
- endpoint available attributes can be found under
185
- :py:class:`~mlrun.api.schemas.ModelEndpoint`.
186
-
187
- """
188
-
189
- self.client.kv.update(
190
- container=self.container,
191
- table_path=self.path,
192
- key=endpoint_id,
193
- attributes=attributes,
194
- )
195
-
196
- logger.info("Model endpoint table updated", endpoint_id=endpoint_id)
197
-
198
- def delete_model_endpoint(
199
- self,
200
- endpoint_id: str,
201
- ):
202
- """
203
- Deletes the KV record of a given model endpoint id.
204
-
205
- :param endpoint_id: The unique id of the model endpoint.
206
- """
207
-
208
- self.client.kv.delete(
209
- container=self.container,
210
- table_path=self.path,
211
- key=endpoint_id,
212
- )
213
-
214
- logger.info("Model endpoint table cleared", endpoint_id=endpoint_id)
215
-
216
- def get_model_endpoint(
217
- self,
218
- endpoint_id: str = None,
219
- start: str = "now-1h",
220
- end: str = "now",
221
- metrics: typing.List[str] = None,
222
- feature_analysis: bool = False,
223
- ) -> mlrun.api.schemas.ModelEndpoint:
224
- """
225
- Get a single model endpoint object. You can apply different time series metrics that will be added to the
226
- result.
227
-
228
- :param endpoint_id: The unique id of the model endpoint.
229
- :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
230
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
231
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
232
- earliest time.
233
- :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
234
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
235
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
236
- earliest time.
237
- :param metrics: A list of metrics to return for the model endpoint. There are pre-defined metrics for
238
- model endpoints such as predictions_per_second and latency_avg_5m but also custom
239
- metrics defined by the user. Please note that these metrics are stored in the time
240
- series DB and the results will be appeared under model_endpoint.spec.metrics.
241
- :param feature_analysis: When True, the base feature statistics and current feature statistics will be added to
242
- the output of the resulting object.
243
-
244
- :return: A ModelEndpoint object.
245
- """
246
- logger.info(
247
- "Getting model endpoint record from kv",
248
- endpoint_id=endpoint_id,
249
- )
250
-
251
- # Getting the raw data from the KV table
252
- endpoint = self.client.kv.get(
253
- container=self.container,
254
- table_path=self.path,
255
- key=endpoint_id,
256
- raise_for_status=v3io.dataplane.RaiseForStatus.never,
257
- access_key=self.access_key,
258
- )
259
- endpoint = endpoint.output.item
260
-
261
- if not endpoint:
262
- raise mlrun.errors.MLRunNotFoundError(f"Endpoint {endpoint_id} not found")
263
-
264
- # Generate a model endpoint object from the model endpoint KV record
265
- endpoint_obj = self._convert_into_model_endpoint_object(
266
- endpoint, start, end, metrics, feature_analysis
267
- )
268
-
269
- return endpoint_obj
270
-
271
- def _convert_into_model_endpoint_object(
272
- self, endpoint, start, end, metrics, feature_analysis
273
- ):
274
- """
275
- Create a ModelEndpoint object according to a provided endpoint record from the DB.
276
-
277
- :param endpoint: KV record of model endpoint which need to be converted into a valid ModelEndpoint
278
- object.
279
- :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
280
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
281
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
282
- earliest time.
283
- :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
284
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
285
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
286
- earliest time.
287
- :param metrics: A list of metrics to return for the model endpoint. There are pre-defined metrics for
288
- model endpoints such as predictions_per_second and latency_avg_5m but also custom
289
- metrics defined by the user. Please note that these metrics are stored in the time
290
- series DB and the results will be appeared under model_endpoint.spec.metrics.
291
- :param feature_analysis: When True, the base feature statistics and current feature statistics will be added to
292
- the output of the resulting object.
293
-
294
- :return: A ModelEndpoint object.
295
- """
296
-
297
- # Parse JSON values into a dictionary
298
- feature_names = self._json_loads_if_not_none(endpoint.get("feature_names"))
299
- label_names = self._json_loads_if_not_none(endpoint.get("label_names"))
300
- feature_stats = self._json_loads_if_not_none(endpoint.get("feature_stats"))
301
- current_stats = self._json_loads_if_not_none(endpoint.get("current_stats"))
302
- children = self._json_loads_if_not_none(endpoint.get("children"))
303
- monitor_configuration = self._json_loads_if_not_none(
304
- endpoint.get("monitor_configuration")
305
- )
306
- endpoint_type = self._json_loads_if_not_none(endpoint.get("endpoint_type"))
307
- children_uids = self._json_loads_if_not_none(endpoint.get("children_uids"))
308
- labels = self._json_loads_if_not_none(endpoint.get("labels"))
309
-
310
- # Convert into model endpoint object
311
- endpoint_obj = mlrun.api.schemas.ModelEndpoint(
312
- metadata=mlrun.api.schemas.ModelEndpointMetadata(
313
- project=endpoint.get("project"),
314
- labels=labels,
315
- uid=endpoint.get("endpoint_id"),
316
- ),
317
- spec=mlrun.api.schemas.ModelEndpointSpec(
318
- function_uri=endpoint.get("function_uri"),
319
- model=endpoint.get("model"),
320
- model_class=endpoint.get("model_class"),
321
- model_uri=endpoint.get("model_uri"),
322
- feature_names=feature_names or None,
323
- label_names=label_names or None,
324
- stream_path=endpoint.get("stream_path"),
325
- algorithm=endpoint.get("algorithm"),
326
- monitor_configuration=monitor_configuration or None,
327
- active=endpoint.get("active"),
328
- monitoring_mode=endpoint.get("monitoring_mode"),
329
- ),
330
- status=mlrun.api.schemas.ModelEndpointStatus(
331
- state=endpoint.get("state") or None,
332
- feature_stats=feature_stats or None,
333
- current_stats=current_stats or None,
334
- children=children or None,
335
- first_request=endpoint.get("first_request"),
336
- last_request=endpoint.get("last_request"),
337
- accuracy=endpoint.get("accuracy"),
338
- error_count=endpoint.get("error_count"),
339
- drift_status=endpoint.get("drift_status"),
340
- endpoint_type=endpoint_type or None,
341
- children_uids=children_uids or None,
342
- monitoring_feature_set_uri=endpoint.get("monitoring_feature_set_uri")
343
- or None,
344
- ),
345
- )
346
-
347
- # If feature analysis was applied, add feature stats and current stats to the model endpoint result
348
- if feature_analysis and feature_names:
349
- endpoint_features = self.get_endpoint_features(
350
- feature_names=feature_names,
351
- feature_stats=feature_stats,
352
- current_stats=current_stats,
353
- )
354
- if endpoint_features:
355
- endpoint_obj.status.features = endpoint_features
356
- # Add the latest drift measures results (calculated by the model monitoring batch)
357
- drift_measures = self._json_loads_if_not_none(
358
- endpoint.get("drift_measures")
359
- )
360
- endpoint_obj.status.drift_measures = drift_measures
361
-
362
- # If time metrics were provided, retrieve the results from the time series DB
363
- if metrics:
364
- endpoint_metrics = self.get_endpoint_metrics(
365
- endpoint_id=endpoint_obj.metadata.uid,
366
- start=start,
367
- end=end,
368
- metrics=metrics,
369
- )
370
- if endpoint_metrics:
371
- endpoint_obj.status.metrics = endpoint_metrics
372
-
373
- return endpoint_obj
374
-
375
- def _get_path_and_container(self):
376
- """Getting path and container based on the model monitoring configurations"""
377
- path = mlrun.mlconf.model_endpoint_monitoring.store_prefixes.default.format(
378
- project=self.project,
379
- kind=mlrun.api.schemas.ModelMonitoringStoreKinds.ENDPOINTS,
380
- )
381
- (
382
- _,
383
- container,
384
- path,
385
- ) = mlrun.utils.model_monitoring.parse_model_endpoint_store_prefix(path)
386
- return path, container
387
-
388
- def list_model_endpoints(
389
- self, model: str, function: str, labels: typing.List, top_level: bool
390
- ):
391
- """
392
- Returns a list of endpoint unique ids, supports filtering by model, function,
393
- labels or top level. By default, when no filters are applied, all available endpoint ids for the given project
394
- will be listed.
395
-
396
- :param model: The name of the model to filter by.
397
- :param function: The name of the function to filter by.
398
- :param labels: A list of labels to filter by. Label filters work by either filtering a specific value
399
- of a label (i.e. list("key==value")) or by looking for the existence of a given
400
- key (i.e. "key").
401
- :param top_level: If True will return only routers and endpoint that are NOT children of any router.
402
-
403
- :return: List of model endpoints unique ids.
404
- """
405
-
406
- # Retrieve the raw data from the KV table and get the endpoint ids
407
- cursor = self.client.kv.new_cursor(
408
- container=self.container,
409
- table_path=self.path,
410
- filter_expression=self.build_kv_cursor_filter_expression(
411
- self.project,
412
- function,
413
- model,
414
- labels,
415
- top_level,
416
- ),
417
- attribute_names=["endpoint_id"],
418
- raise_for_status=v3io.dataplane.RaiseForStatus.never,
419
- )
420
- try:
421
- items = cursor.all()
422
- except Exception:
423
- return []
424
-
425
- # Create a list of model endpoints unique ids
426
- uids = [item["endpoint_id"] for item in items]
427
-
428
- return uids
429
-
430
- def delete_model_endpoints_resources(
431
- self, endpoints: mlrun.api.schemas.model_endpoints.ModelEndpointList
432
- ):
433
- """
434
- Delete all model endpoints resources in both KV and the time series DB.
435
-
436
- :param endpoints: An object of ModelEndpointList which is literally a list of model endpoints along with some
437
- metadata. To get a standard list of model endpoints use ModelEndpointList.endpoints.
438
- """
439
-
440
- # Delete model endpoint record from KV table
441
- for endpoint in endpoints.endpoints:
442
- self.delete_model_endpoint(
443
- endpoint.metadata.uid,
444
- )
445
-
446
- # Delete remain records in the KV
447
- all_records = self.client.kv.new_cursor(
448
- container=self.container,
449
- table_path=self.path,
450
- raise_for_status=v3io.dataplane.RaiseForStatus.never,
451
- ).all()
452
-
453
- all_records = [r["__name"] for r in all_records]
454
-
455
- # Cleanup KV
456
- for record in all_records:
457
- self.client.kv.delete(
458
- container=self.container,
459
- table_path=self.path,
460
- key=record,
461
- raise_for_status=v3io.dataplane.RaiseForStatus.never,
462
- )
463
-
464
- # Cleanup TSDB
465
- frames = mlrun.utils.v3io_clients.get_frames_client(
466
- token=self.access_key,
467
- address=mlrun.mlconf.v3io_framesd,
468
- container=self.container,
469
- )
470
-
471
- # Generate the required tsdb paths
472
- tsdb_path, filtered_path = self._generate_tsdb_paths()
473
-
474
- # Delete time series DB resources
475
- try:
476
- frames.delete(
477
- backend=model_monitoring_constants.StoreTarget.TSDB,
478
- table=filtered_path,
479
- if_missing=v3io_frames.frames_pb2.IGNORE,
480
- )
481
- except v3io_frames.errors.CreateError:
482
- # Frames might raise an exception if schema file does not exist.
483
- pass
484
-
485
- # Final cleanup of tsdb path
486
- tsdb_path.replace("://u", ":///u")
487
- store, _ = mlrun.store_manager.get_or_create_store(tsdb_path)
488
- store.rm(tsdb_path, recursive=True)
489
-
490
- def _generate_tsdb_paths(self) -> typing.Tuple[str, str]:
491
- """Generate a short path to the TSDB resources and a filtered path for the frames object
492
-
493
- :return: A tuple of:
494
- [0] = Short path to the TSDB resources
495
- [1] = Filtered path to TSDB events without schema and container
496
- """
497
- # Full path for the time series DB events
498
- full_path = (
499
- mlrun.mlconf.model_endpoint_monitoring.store_prefixes.default.format(
500
- project=self.project,
501
- kind=mlrun.api.schemas.ModelMonitoringStoreKinds.EVENTS,
502
- )
503
- )
504
-
505
- # Generate the main directory with the TSDB resources
506
- tsdb_path = mlrun.utils.model_monitoring.parse_model_endpoint_project_prefix(
507
- full_path, self.project
508
- )
509
-
510
- # Generate filtered path without schema and container as required by the frames object
511
- (
512
- _,
513
- _,
514
- filtered_path,
515
- ) = mlrun.utils.model_monitoring.parse_model_endpoint_store_prefix(full_path)
516
- return tsdb_path, filtered_path
517
-
518
- @staticmethod
519
- def build_kv_cursor_filter_expression(
520
- project: str,
521
- function: str = None,
522
- model: str = None,
523
- labels: typing.List[str] = None,
524
- top_level: bool = False,
525
- ) -> str:
526
- """
527
- Convert the provided filters into a valid filter expression. The expected filter expression includes different
528
- conditions, divided by ' AND '.
529
-
530
- :param project: The name of the project.
531
- :param model: The name of the model to filter by.
532
- :param function: The name of the function to filter by.
533
- :param labels: A list of labels to filter by. Label filters work by either filtering a specific value of
534
- a label (i.e. list("key==value")) or by looking for the existence of a given
535
- key (i.e. "key").
536
- :param top_level: If True will return only routers and endpoint that are NOT children of any router.
537
-
538
- :return: A valid filter expression as a string.
539
- """
540
-
541
- if not project:
542
- raise mlrun.errors.MLRunInvalidArgumentError("project can't be empty")
543
-
544
- # Add project filter
545
- filter_expression = [f"project=='{project}'"]
546
-
547
- # Add function and model filters
548
- if function:
549
- filter_expression.append(f"function=='{function}'")
550
- if model:
551
- filter_expression.append(f"model=='{model}'")
552
-
553
- # Add labels filters
554
- if labels:
555
- for label in labels:
556
-
557
- if not label.startswith("_"):
558
- label = f"_{label}"
559
-
560
- if "=" in label:
561
- lbl, value = list(map(lambda x: x.strip(), label.split("=")))
562
- filter_expression.append(f"{lbl}=='{value}'")
563
- else:
564
- filter_expression.append(f"exists({label})")
565
-
566
- # Apply top_level filter (remove endpoints that considered a child of a router)
567
- if top_level:
568
- filter_expression.append(
569
- f"(endpoint_type=='{str(mlrun.utils.model_monitoring.EndpointType.NODE_EP.value)}' "
570
- f"OR endpoint_type=='{str(mlrun.utils.model_monitoring.EndpointType.ROUTER.value)}')"
571
- )
572
-
573
- return " AND ".join(filter_expression)
574
-
575
- @staticmethod
576
- def flatten_model_endpoint_attributes(
577
- endpoint: mlrun.api.schemas.ModelEndpoint,
578
- ) -> typing.Dict:
579
- """
580
- Retrieving flatten structure of the model endpoint object.
581
-
582
- :param endpoint: ModelEndpoint object that will be used for getting the attributes.
583
-
584
- :return: A flat dictionary of attributes.
585
- """
586
-
587
- # Prepare the data for the attributes dictionary
588
- labels = endpoint.metadata.labels or {}
589
- searchable_labels = {f"_{k}": v for k, v in labels.items()}
590
- feature_names = endpoint.spec.feature_names or []
591
- label_names = endpoint.spec.label_names or []
592
- feature_stats = endpoint.status.feature_stats or {}
593
- current_stats = endpoint.status.current_stats or {}
594
- children = endpoint.status.children or []
595
- endpoint_type = endpoint.status.endpoint_type or None
596
- children_uids = endpoint.status.children_uids or []
597
-
598
- # Fill the data. Note that because it is a flat dictionary, we use json.dumps() for encoding hierarchies
599
- # such as current_stats or label_names
600
- attributes = {
601
- "endpoint_id": endpoint.metadata.uid,
602
- "project": endpoint.metadata.project,
603
- "function_uri": endpoint.spec.function_uri,
604
- "model": endpoint.spec.model,
605
- "model_class": endpoint.spec.model_class or "",
606
- "labels": json.dumps(labels),
607
- "model_uri": endpoint.spec.model_uri or "",
608
- "stream_path": endpoint.spec.stream_path or "",
609
- "active": endpoint.spec.active or "",
610
- "monitoring_feature_set_uri": endpoint.status.monitoring_feature_set_uri
611
- or "",
612
- "monitoring_mode": endpoint.spec.monitoring_mode or "",
613
- "state": endpoint.status.state or "",
614
- "feature_stats": json.dumps(feature_stats),
615
- "current_stats": json.dumps(current_stats),
616
- "feature_names": json.dumps(feature_names),
617
- "children": json.dumps(children),
618
- "label_names": json.dumps(label_names),
619
- "endpoint_type": json.dumps(endpoint_type),
620
- "children_uids": json.dumps(children_uids),
621
- **searchable_labels,
622
- }
623
- return attributes
624
-
625
- @staticmethod
626
- def _json_loads_if_not_none(field: typing.Any) -> typing.Any:
627
- return json.loads(field) if field is not None else None
628
-
629
- @staticmethod
630
- def get_endpoint_features(
631
- feature_names: typing.List[str],
632
- feature_stats: dict = None,
633
- current_stats: dict = None,
634
- ) -> typing.List[mlrun.api.schemas.Features]:
635
- """
636
- Getting a new list of features that exist in feature_names along with their expected (feature_stats) and
637
- actual (current_stats) stats. The expected stats were calculated during the creation of the model endpoint,
638
- usually based on the data from the Model Artifact. The actual stats are based on the results from the latest
639
- model monitoring batch job.
640
-
641
- param feature_names: List of feature names.
642
- param feature_stats: Dictionary of feature stats that were stored during the creation of the model endpoint
643
- object.
644
- param current_stats: Dictionary of the latest stats that were stored during the last run of the model monitoring
645
- batch job.
646
-
647
- return: List of feature objects. Each feature has a name, weight, expected values, and actual values. More info
648
- can be found under mlrun.api.schemas.Features.
649
- """
650
-
651
- # Initialize feature and current stats dictionaries
652
- safe_feature_stats = feature_stats or {}
653
- safe_current_stats = current_stats or {}
654
-
655
- # Create feature object and add it to a general features list
656
- features = []
657
- for name in feature_names:
658
- if feature_stats is not None and name not in feature_stats:
659
- logger.warn("Feature missing from 'feature_stats'", name=name)
660
- if current_stats is not None and name not in current_stats:
661
- logger.warn("Feature missing from 'current_stats'", name=name)
662
- f = mlrun.api.schemas.Features.new(
663
- name, safe_feature_stats.get(name), safe_current_stats.get(name)
664
- )
665
- features.append(f)
666
- return features
667
-
668
- def get_endpoint_metrics(
669
- self,
670
- endpoint_id: str,
671
- metrics: typing.List[str],
672
- start: str = "now-1h",
673
- end: str = "now",
674
- ) -> typing.Dict[str, mlrun.api.schemas.Metric]:
675
- """
676
- Getting metrics from the time series DB. There are pre-defined metrics for model endpoints such as
677
- predictions_per_second and latency_avg_5m but also custom metrics defined by the user.
678
-
679
- :param endpoint_id: The unique id of the model endpoint.
680
- :param metrics: A list of metrics to return for the model endpoint.
681
- :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
682
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
683
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
684
- earliest time.
685
- :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
686
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or
687
- `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
688
- earliest time.
689
-
690
- :return: A dictionary of metrics in which the key is a metric name and the value is a Metric object that also
691
- includes the relevant timestamp. More details about the Metric object can be found under
692
- mlrun.api.schemas.Metric.
693
- """
694
-
695
- if not metrics:
696
- raise mlrun.errors.MLRunInvalidArgumentError(
697
- "Metric names must be provided"
698
- )
699
-
700
- # Initialize metrics mapping dictionary
701
- metrics_mapping = {}
702
-
703
- # Getting the path for the time series DB
704
- events_path = (
705
- mlrun.mlconf.model_endpoint_monitoring.store_prefixes.default.format(
706
- project=self.project,
707
- kind=mlrun.api.schemas.ModelMonitoringStoreKinds.EVENTS,
708
- )
709
- )
710
- (
711
- _,
712
- _,
713
- events_path,
714
- ) = mlrun.utils.model_monitoring.parse_model_endpoint_store_prefix(events_path)
715
-
716
- # Retrieve the raw data from the time series DB based on the provided metrics and time ranges
717
- frames_client = mlrun.utils.v3io_clients.get_frames_client(
718
- token=self.access_key,
719
- address=mlrun.mlconf.v3io_framesd,
720
- container=self.container,
721
- )
722
-
723
- try:
724
- data = frames_client.read(
725
- backend=model_monitoring_constants.StoreTarget.TSDB,
726
- table=events_path,
727
- columns=["endpoint_id", *metrics],
728
- filter=f"endpoint_id=='{endpoint_id}'",
729
- start=start,
730
- end=end,
731
- )
732
-
733
- # Fill the metrics mapping dictionary with the metric name and values
734
- data_dict = data.to_dict()
735
- for metric in metrics:
736
- metric_data = data_dict.get(metric)
737
- if metric_data is None:
738
- continue
739
-
740
- values = [
741
- (str(timestamp), value) for timestamp, value in metric_data.items()
742
- ]
743
- metrics_mapping[metric] = mlrun.api.schemas.Metric(
744
- name=metric, values=values
745
- )
746
- except v3io_frames.errors.ReadError:
747
- logger.warn("Failed to read tsdb", endpoint=endpoint_id)
748
- return metrics_mapping
749
-
750
-
751
- class _ModelEndpointSQLStore(_ModelEndpointStore):
752
- def write_model_endpoint(self, endpoint, update=True):
753
- raise NotImplementedError
754
-
755
- def update_model_endpoint(self, endpoint_id, attributes):
756
- raise NotImplementedError
757
-
758
- def delete_model_endpoint(self, endpoint_id):
759
- raise NotImplementedError
760
-
761
- def delete_model_endpoints_resources(
762
- self, endpoints: mlrun.api.schemas.model_endpoints.ModelEndpointList
763
- ):
764
- raise NotImplementedError
765
-
766
- def get_model_endpoint(
767
- self,
768
- metrics: typing.List[str] = None,
769
- start: str = "now-1h",
770
- end: str = "now",
771
- feature_analysis: bool = False,
772
- endpoint_id: str = None,
773
- ):
774
- raise NotImplementedError
775
-
776
- def list_model_endpoints(
777
- self, model: str, function: str, labels: typing.List, top_level: bool
778
- ):
779
- raise NotImplementedError
780
-
781
-
782
- class ModelEndpointStoreType(enum.Enum):
783
- """Enum class to handle the different store type values for saving a model endpoint record."""
784
-
785
- kv = "kv"
786
- sql = "sql"
787
-
788
- def to_endpoint_target(
789
- self, project: str, access_key: str = None
790
- ) -> _ModelEndpointStore:
791
- """
792
- Return a ModelEndpointStore object based on the provided enum value.
793
-
794
- :param project: The name of the project.
795
- :param access_key: Access key with permission to the DB table. Note that if access key is None and the
796
- endpoint target is from type KV then the access key will be retrieved from the environment
797
- variable.
798
-
799
- :return: ModelEndpointStore object.
800
-
801
- """
802
-
803
- if self.value == ModelEndpointStoreType.kv.value:
804
-
805
- # Get V3IO access key from env
806
- access_key = (
807
- mlrun.mlconf.get_v3io_access_key() if access_key is None else access_key
808
- )
809
-
810
- return _ModelEndpointKVStore(project=project, access_key=access_key)
811
-
812
- # Assuming SQL store target if store type is not KV.
813
- # Update these lines once there are more than two store target types.
814
- return _ModelEndpointSQLStore(project=project)
815
-
816
- @classmethod
817
- def _missing_(cls, value: typing.Any):
818
- """A lookup function to handle an invalid value.
819
- :param value: Provided enum (invalid) value.
820
- """
821
- valid_values = list(cls.__members__.keys())
822
- raise mlrun.errors.MLRunInvalidArgumentError(
823
- "%r is not a valid %s, please choose a valid value: %s."
824
- % (value, cls.__name__, valid_values)
825
- )
826
-
827
-
828
- def get_model_endpoint_target(
829
- project: str, access_key: str = None
830
- ) -> _ModelEndpointStore:
831
- """
832
- Getting the DB target type based on mlrun.config.model_endpoint_monitoring.store_type.
833
-
834
- :param project: The name of the project.
835
- :param access_key: Access key with permission to the DB table.
836
-
837
- :return: ModelEndpointStore object. Using this object, the user can apply different operations on the
838
- model endpoint record such as write, update, get and delete.
839
- """
840
-
841
- # Get store type value from ModelEndpointStoreType enum class
842
- model_endpoint_store_type = ModelEndpointStoreType(
843
- mlrun.mlconf.model_endpoint_monitoring.store_type
844
- )
845
-
846
- # Convert into model endpoint store target object
847
- return model_endpoint_store_type.to_endpoint_target(project, access_key)