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

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

Potentially problematic release.


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

Files changed (444) hide show
  1. mlrun/__init__.py +3 -3
  2. mlrun/__main__.py +79 -37
  3. mlrun/api/__init__.py +1 -1
  4. mlrun/api/api/__init__.py +1 -1
  5. mlrun/api/api/api.py +4 -4
  6. mlrun/api/api/deps.py +10 -21
  7. mlrun/api/api/endpoints/__init__.py +1 -1
  8. mlrun/api/api/endpoints/artifacts.py +64 -36
  9. mlrun/api/api/endpoints/auth.py +4 -4
  10. mlrun/api/api/endpoints/background_tasks.py +11 -11
  11. mlrun/api/api/endpoints/client_spec.py +5 -5
  12. mlrun/api/api/endpoints/clusterization_spec.py +6 -4
  13. mlrun/api/api/endpoints/feature_store.py +124 -115
  14. mlrun/api/api/endpoints/files.py +22 -14
  15. mlrun/api/api/endpoints/frontend_spec.py +28 -21
  16. mlrun/api/api/endpoints/functions.py +142 -87
  17. mlrun/api/api/endpoints/grafana_proxy.py +89 -442
  18. mlrun/api/api/endpoints/healthz.py +20 -7
  19. mlrun/api/api/endpoints/hub.py +320 -0
  20. mlrun/api/api/endpoints/internal/__init__.py +1 -1
  21. mlrun/api/api/endpoints/internal/config.py +1 -1
  22. mlrun/api/api/endpoints/internal/memory_reports.py +9 -9
  23. mlrun/api/api/endpoints/logs.py +11 -11
  24. mlrun/api/api/endpoints/model_endpoints.py +74 -70
  25. mlrun/api/api/endpoints/operations.py +13 -9
  26. mlrun/api/api/endpoints/pipelines.py +93 -88
  27. mlrun/api/api/endpoints/projects.py +35 -35
  28. mlrun/api/api/endpoints/runs.py +69 -27
  29. mlrun/api/api/endpoints/runtime_resources.py +28 -28
  30. mlrun/api/api/endpoints/schedules.py +98 -41
  31. mlrun/api/api/endpoints/secrets.py +37 -32
  32. mlrun/api/api/endpoints/submit.py +12 -12
  33. mlrun/api/api/endpoints/tags.py +20 -22
  34. mlrun/api/api/utils.py +251 -42
  35. mlrun/api/constants.py +1 -1
  36. mlrun/api/crud/__init__.py +18 -15
  37. mlrun/api/crud/artifacts.py +10 -10
  38. mlrun/api/crud/client_spec.py +4 -4
  39. mlrun/api/crud/clusterization_spec.py +3 -3
  40. mlrun/api/crud/feature_store.py +54 -46
  41. mlrun/api/crud/functions.py +3 -3
  42. mlrun/api/crud/hub.py +312 -0
  43. mlrun/api/crud/logs.py +11 -9
  44. mlrun/api/crud/model_monitoring/__init__.py +3 -3
  45. mlrun/api/crud/model_monitoring/grafana.py +435 -0
  46. mlrun/api/crud/model_monitoring/model_endpoints.py +352 -129
  47. mlrun/api/crud/notifications.py +149 -0
  48. mlrun/api/crud/pipelines.py +67 -52
  49. mlrun/api/crud/projects.py +51 -23
  50. mlrun/api/crud/runs.py +7 -5
  51. mlrun/api/crud/runtime_resources.py +13 -13
  52. mlrun/api/{db/filedb → crud/runtimes}/__init__.py +1 -1
  53. mlrun/api/crud/runtimes/nuclio/__init__.py +14 -0
  54. mlrun/api/crud/runtimes/nuclio/function.py +505 -0
  55. mlrun/api/crud/runtimes/nuclio/helpers.py +310 -0
  56. mlrun/api/crud/secrets.py +88 -46
  57. mlrun/api/crud/tags.py +5 -5
  58. mlrun/api/db/__init__.py +1 -1
  59. mlrun/api/db/base.py +102 -54
  60. mlrun/api/db/init_db.py +2 -3
  61. mlrun/api/db/session.py +4 -12
  62. mlrun/api/db/sqldb/__init__.py +1 -1
  63. mlrun/api/db/sqldb/db.py +439 -196
  64. mlrun/api/db/sqldb/helpers.py +1 -1
  65. mlrun/api/db/sqldb/models/__init__.py +3 -3
  66. mlrun/api/db/sqldb/models/models_mysql.py +82 -64
  67. mlrun/api/db/sqldb/models/models_sqlite.py +76 -64
  68. mlrun/api/db/sqldb/session.py +27 -20
  69. mlrun/api/initial_data.py +82 -24
  70. mlrun/api/launcher.py +196 -0
  71. mlrun/api/main.py +91 -22
  72. mlrun/api/middlewares.py +6 -5
  73. mlrun/api/migrations_mysql/env.py +1 -1
  74. mlrun/api/migrations_mysql/versions/28383af526f3_market_place_to_hub.py +40 -0
  75. mlrun/api/migrations_mysql/versions/32bae1b0e29c_increase_timestamp_fields_precision.py +1 -1
  76. mlrun/api/migrations_mysql/versions/4903aef6a91d_tag_foreign_key_and_cascades.py +1 -1
  77. mlrun/api/migrations_mysql/versions/5f1351c88a19_adding_background_tasks_table.py +1 -1
  78. mlrun/api/migrations_mysql/versions/88e656800d6a_add_requested_logs_column_and_index_to_.py +1 -1
  79. mlrun/api/migrations_mysql/versions/9d16de5f03a7_adding_data_versions_table.py +1 -1
  80. mlrun/api/migrations_mysql/versions/b86f5b53f3d7_adding_name_and_updated_to_runs_table.py +1 -1
  81. mlrun/api/migrations_mysql/versions/c4af40b0bf61_init.py +1 -1
  82. mlrun/api/migrations_mysql/versions/c905d15bd91d_notifications.py +72 -0
  83. mlrun/api/migrations_mysql/versions/ee041e8fdaa0_adding_next_run_time_column_to_schedule_.py +1 -1
  84. mlrun/api/migrations_sqlite/env.py +1 -1
  85. mlrun/api/migrations_sqlite/versions/11f8dd2dc9fe_init.py +1 -1
  86. mlrun/api/migrations_sqlite/versions/1c954f8cb32d_schedule_last_run_uri.py +1 -1
  87. mlrun/api/migrations_sqlite/versions/2b6d23c715aa_adding_feature_sets.py +1 -1
  88. mlrun/api/migrations_sqlite/versions/4acd9430b093_market_place_to_hub.py +77 -0
  89. mlrun/api/migrations_sqlite/versions/6401142f2d7c_adding_next_run_time_column_to_schedule_.py +1 -1
  90. mlrun/api/migrations_sqlite/versions/64d90a1a69bc_adding_background_tasks_table.py +1 -1
  91. mlrun/api/migrations_sqlite/versions/803438ecd005_add_requested_logs_column_to_runs.py +1 -1
  92. mlrun/api/migrations_sqlite/versions/863114f0c659_refactoring_feature_set.py +1 -1
  93. mlrun/api/migrations_sqlite/versions/959ae00528ad_notifications.py +63 -0
  94. mlrun/api/migrations_sqlite/versions/accf9fc83d38_adding_data_versions_table.py +1 -1
  95. mlrun/api/migrations_sqlite/versions/b68e8e897a28_schedule_labels.py +1 -1
  96. mlrun/api/migrations_sqlite/versions/bcd0c1f9720c_adding_project_labels.py +1 -1
  97. mlrun/api/migrations_sqlite/versions/cf21882f938e_schedule_id.py +1 -1
  98. mlrun/api/migrations_sqlite/versions/d781f58f607f_tag_object_name_string.py +1 -1
  99. mlrun/api/migrations_sqlite/versions/deac06871ace_adding_marketplace_sources_table.py +1 -1
  100. mlrun/api/migrations_sqlite/versions/e1dd5983c06b_schedule_concurrency_limit.py +1 -1
  101. mlrun/api/migrations_sqlite/versions/e5594ed3ab53_adding_name_and_updated_to_runs_table.py +1 -1
  102. mlrun/api/migrations_sqlite/versions/f4249b4ba6fa_adding_feature_vectors.py +1 -1
  103. mlrun/api/migrations_sqlite/versions/f7b5a1a03629_adding_feature_labels.py +1 -1
  104. mlrun/api/schemas/__init__.py +216 -138
  105. mlrun/api/utils/__init__.py +1 -1
  106. mlrun/api/utils/asyncio.py +1 -1
  107. mlrun/api/utils/auth/__init__.py +1 -1
  108. mlrun/api/utils/auth/providers/__init__.py +1 -1
  109. mlrun/api/utils/auth/providers/base.py +7 -7
  110. mlrun/api/utils/auth/providers/nop.py +6 -7
  111. mlrun/api/utils/auth/providers/opa.py +17 -17
  112. mlrun/api/utils/auth/verifier.py +36 -34
  113. mlrun/api/utils/background_tasks.py +24 -24
  114. mlrun/{builder.py → api/utils/builder.py} +216 -123
  115. mlrun/api/utils/clients/__init__.py +1 -1
  116. mlrun/api/utils/clients/chief.py +19 -4
  117. mlrun/api/utils/clients/iguazio.py +106 -60
  118. mlrun/api/utils/clients/log_collector.py +1 -1
  119. mlrun/api/utils/clients/nuclio.py +23 -23
  120. mlrun/api/utils/clients/protocols/grpc.py +2 -2
  121. mlrun/api/utils/db/__init__.py +1 -1
  122. mlrun/api/utils/db/alembic.py +1 -1
  123. mlrun/api/utils/db/backup.py +1 -1
  124. mlrun/api/utils/db/mysql.py +24 -25
  125. mlrun/api/utils/db/sql_collation.py +1 -1
  126. mlrun/api/utils/db/sqlite_migration.py +2 -2
  127. mlrun/api/utils/events/__init__.py +14 -0
  128. mlrun/api/utils/events/base.py +57 -0
  129. mlrun/api/utils/events/events_factory.py +41 -0
  130. mlrun/api/utils/events/iguazio.py +217 -0
  131. mlrun/api/utils/events/nop.py +55 -0
  132. mlrun/api/utils/helpers.py +16 -13
  133. mlrun/api/utils/memory_reports.py +1 -1
  134. mlrun/api/utils/periodic.py +6 -3
  135. mlrun/api/utils/projects/__init__.py +1 -1
  136. mlrun/api/utils/projects/follower.py +33 -33
  137. mlrun/api/utils/projects/leader.py +36 -34
  138. mlrun/api/utils/projects/member.py +27 -27
  139. mlrun/api/utils/projects/remotes/__init__.py +1 -1
  140. mlrun/api/utils/projects/remotes/follower.py +13 -13
  141. mlrun/api/utils/projects/remotes/leader.py +10 -10
  142. mlrun/api/utils/projects/remotes/nop_follower.py +27 -21
  143. mlrun/api/utils/projects/remotes/nop_leader.py +17 -16
  144. mlrun/api/utils/scheduler.py +140 -51
  145. mlrun/api/utils/singletons/__init__.py +1 -1
  146. mlrun/api/utils/singletons/db.py +9 -15
  147. mlrun/api/utils/singletons/k8s.py +677 -5
  148. mlrun/api/utils/singletons/logs_dir.py +1 -1
  149. mlrun/api/utils/singletons/project_member.py +1 -1
  150. mlrun/api/utils/singletons/scheduler.py +1 -1
  151. mlrun/artifacts/__init__.py +2 -2
  152. mlrun/artifacts/base.py +8 -2
  153. mlrun/artifacts/dataset.py +5 -3
  154. mlrun/artifacts/manager.py +7 -1
  155. mlrun/artifacts/model.py +15 -4
  156. mlrun/artifacts/plots.py +1 -1
  157. mlrun/common/__init__.py +1 -1
  158. mlrun/common/constants.py +15 -0
  159. mlrun/common/model_monitoring.py +209 -0
  160. mlrun/common/schemas/__init__.py +167 -0
  161. mlrun/{api → common}/schemas/artifact.py +13 -14
  162. mlrun/{api → common}/schemas/auth.py +10 -8
  163. mlrun/{api → common}/schemas/background_task.py +3 -3
  164. mlrun/{api → common}/schemas/client_spec.py +1 -1
  165. mlrun/{api → common}/schemas/clusterization_spec.py +3 -3
  166. mlrun/{api → common}/schemas/constants.py +21 -8
  167. mlrun/common/schemas/events.py +36 -0
  168. mlrun/{api → common}/schemas/feature_store.py +2 -1
  169. mlrun/{api → common}/schemas/frontend_spec.py +7 -6
  170. mlrun/{api → common}/schemas/function.py +5 -5
  171. mlrun/{api → common}/schemas/http.py +3 -3
  172. mlrun/common/schemas/hub.py +134 -0
  173. mlrun/{api → common}/schemas/k8s.py +3 -3
  174. mlrun/{api → common}/schemas/memory_reports.py +1 -1
  175. mlrun/common/schemas/model_endpoints.py +342 -0
  176. mlrun/common/schemas/notification.py +57 -0
  177. mlrun/{api → common}/schemas/object.py +6 -6
  178. mlrun/{api → common}/schemas/pipeline.py +3 -3
  179. mlrun/{api → common}/schemas/project.py +6 -5
  180. mlrun/common/schemas/regex.py +24 -0
  181. mlrun/common/schemas/runs.py +30 -0
  182. mlrun/{api → common}/schemas/runtime_resource.py +3 -3
  183. mlrun/{api → common}/schemas/schedule.py +19 -7
  184. mlrun/{api → common}/schemas/secret.py +3 -3
  185. mlrun/{api → common}/schemas/tag.py +2 -2
  186. mlrun/common/types.py +25 -0
  187. mlrun/config.py +152 -20
  188. mlrun/data_types/__init__.py +7 -2
  189. mlrun/data_types/data_types.py +4 -2
  190. mlrun/data_types/infer.py +1 -1
  191. mlrun/data_types/spark.py +10 -3
  192. mlrun/datastore/__init__.py +10 -3
  193. mlrun/datastore/azure_blob.py +1 -1
  194. mlrun/datastore/base.py +185 -53
  195. mlrun/datastore/datastore.py +1 -1
  196. mlrun/datastore/filestore.py +1 -1
  197. mlrun/datastore/google_cloud_storage.py +1 -1
  198. mlrun/datastore/inmem.py +4 -1
  199. mlrun/datastore/redis.py +1 -1
  200. mlrun/datastore/s3.py +1 -1
  201. mlrun/datastore/sources.py +192 -70
  202. mlrun/datastore/spark_udf.py +44 -0
  203. mlrun/datastore/store_resources.py +4 -4
  204. mlrun/datastore/targets.py +115 -45
  205. mlrun/datastore/utils.py +127 -5
  206. mlrun/datastore/v3io.py +1 -1
  207. mlrun/datastore/wasbfs/__init__.py +1 -1
  208. mlrun/datastore/wasbfs/fs.py +1 -1
  209. mlrun/db/__init__.py +7 -5
  210. mlrun/db/base.py +112 -68
  211. mlrun/db/httpdb.py +445 -277
  212. mlrun/db/nopdb.py +491 -0
  213. mlrun/db/sqldb.py +112 -65
  214. mlrun/errors.py +6 -1
  215. mlrun/execution.py +44 -22
  216. mlrun/feature_store/__init__.py +1 -1
  217. mlrun/feature_store/api.py +143 -95
  218. mlrun/feature_store/common.py +16 -20
  219. mlrun/feature_store/feature_set.py +42 -12
  220. mlrun/feature_store/feature_vector.py +32 -21
  221. mlrun/feature_store/ingestion.py +9 -12
  222. mlrun/feature_store/retrieval/__init__.py +3 -2
  223. mlrun/feature_store/retrieval/base.py +388 -66
  224. mlrun/feature_store/retrieval/dask_merger.py +63 -151
  225. mlrun/feature_store/retrieval/job.py +30 -12
  226. mlrun/feature_store/retrieval/local_merger.py +40 -133
  227. mlrun/feature_store/retrieval/spark_merger.py +129 -127
  228. mlrun/feature_store/retrieval/storey_merger.py +173 -0
  229. mlrun/feature_store/steps.py +132 -15
  230. mlrun/features.py +8 -3
  231. mlrun/frameworks/__init__.py +1 -1
  232. mlrun/frameworks/_common/__init__.py +1 -1
  233. mlrun/frameworks/_common/artifacts_library.py +1 -1
  234. mlrun/frameworks/_common/mlrun_interface.py +1 -1
  235. mlrun/frameworks/_common/model_handler.py +1 -1
  236. mlrun/frameworks/_common/plan.py +1 -1
  237. mlrun/frameworks/_common/producer.py +1 -1
  238. mlrun/frameworks/_common/utils.py +1 -1
  239. mlrun/frameworks/_dl_common/__init__.py +1 -1
  240. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -1
  241. mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
  242. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +1 -1
  243. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +1 -1
  244. mlrun/frameworks/_dl_common/model_handler.py +1 -1
  245. mlrun/frameworks/_dl_common/utils.py +1 -1
  246. mlrun/frameworks/_ml_common/__init__.py +1 -1
  247. mlrun/frameworks/_ml_common/artifacts_library.py +1 -1
  248. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -1
  249. mlrun/frameworks/_ml_common/loggers/logger.py +1 -1
  250. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
  251. mlrun/frameworks/_ml_common/model_handler.py +1 -1
  252. mlrun/frameworks/_ml_common/pkl_model_server.py +13 -1
  253. mlrun/frameworks/_ml_common/plan.py +1 -1
  254. mlrun/frameworks/_ml_common/plans/__init__.py +1 -1
  255. mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +1 -6
  256. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +1 -1
  257. mlrun/frameworks/_ml_common/plans/dataset_plan.py +1 -1
  258. mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +1 -1
  259. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +1 -1
  260. mlrun/frameworks/_ml_common/producer.py +1 -1
  261. mlrun/frameworks/_ml_common/utils.py +1 -1
  262. mlrun/frameworks/auto_mlrun/__init__.py +1 -1
  263. mlrun/frameworks/auto_mlrun/auto_mlrun.py +1 -1
  264. mlrun/frameworks/huggingface/__init__.py +1 -1
  265. mlrun/frameworks/huggingface/model_server.py +1 -1
  266. mlrun/frameworks/lgbm/__init__.py +1 -1
  267. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -1
  268. mlrun/frameworks/lgbm/callbacks/callback.py +1 -1
  269. mlrun/frameworks/lgbm/callbacks/logging_callback.py +1 -1
  270. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +1 -1
  271. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -1
  272. mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -1
  273. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +1 -1
  274. mlrun/frameworks/lgbm/mlrun_interfaces/model_mlrun_interface.py +1 -1
  275. mlrun/frameworks/lgbm/model_handler.py +1 -1
  276. mlrun/frameworks/lgbm/model_server.py +1 -1
  277. mlrun/frameworks/lgbm/utils.py +1 -1
  278. mlrun/frameworks/onnx/__init__.py +1 -1
  279. mlrun/frameworks/onnx/dataset.py +1 -1
  280. mlrun/frameworks/onnx/mlrun_interface.py +1 -1
  281. mlrun/frameworks/onnx/model_handler.py +1 -1
  282. mlrun/frameworks/onnx/model_server.py +1 -1
  283. mlrun/frameworks/parallel_coordinates.py +1 -1
  284. mlrun/frameworks/pytorch/__init__.py +1 -1
  285. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -1
  286. mlrun/frameworks/pytorch/callbacks/callback.py +1 -1
  287. mlrun/frameworks/pytorch/callbacks/logging_callback.py +1 -1
  288. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +1 -1
  289. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +1 -1
  290. mlrun/frameworks/pytorch/callbacks_handler.py +1 -1
  291. mlrun/frameworks/pytorch/mlrun_interface.py +1 -1
  292. mlrun/frameworks/pytorch/model_handler.py +1 -1
  293. mlrun/frameworks/pytorch/model_server.py +1 -1
  294. mlrun/frameworks/pytorch/utils.py +1 -1
  295. mlrun/frameworks/sklearn/__init__.py +1 -1
  296. mlrun/frameworks/sklearn/estimator.py +1 -1
  297. mlrun/frameworks/sklearn/metric.py +1 -1
  298. mlrun/frameworks/sklearn/metrics_library.py +1 -1
  299. mlrun/frameworks/sklearn/mlrun_interface.py +1 -1
  300. mlrun/frameworks/sklearn/model_handler.py +1 -1
  301. mlrun/frameworks/sklearn/utils.py +1 -1
  302. mlrun/frameworks/tf_keras/__init__.py +1 -1
  303. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -1
  304. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  305. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +1 -1
  306. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +1 -1
  307. mlrun/frameworks/tf_keras/mlrun_interface.py +1 -1
  308. mlrun/frameworks/tf_keras/model_handler.py +1 -1
  309. mlrun/frameworks/tf_keras/model_server.py +1 -1
  310. mlrun/frameworks/tf_keras/utils.py +1 -1
  311. mlrun/frameworks/xgboost/__init__.py +1 -1
  312. mlrun/frameworks/xgboost/mlrun_interface.py +1 -1
  313. mlrun/frameworks/xgboost/model_handler.py +1 -1
  314. mlrun/frameworks/xgboost/utils.py +1 -1
  315. mlrun/k8s_utils.py +14 -765
  316. mlrun/kfpops.py +14 -17
  317. mlrun/launcher/__init__.py +13 -0
  318. mlrun/launcher/base.py +406 -0
  319. mlrun/launcher/client.py +159 -0
  320. mlrun/launcher/factory.py +50 -0
  321. mlrun/launcher/local.py +276 -0
  322. mlrun/launcher/remote.py +178 -0
  323. mlrun/lists.py +10 -2
  324. mlrun/mlutils/__init__.py +1 -1
  325. mlrun/mlutils/data.py +1 -1
  326. mlrun/mlutils/models.py +1 -1
  327. mlrun/mlutils/plots.py +1 -1
  328. mlrun/model.py +252 -14
  329. mlrun/model_monitoring/__init__.py +41 -0
  330. mlrun/model_monitoring/features_drift_table.py +1 -1
  331. mlrun/model_monitoring/helpers.py +123 -38
  332. mlrun/model_monitoring/model_endpoint.py +144 -0
  333. mlrun/model_monitoring/model_monitoring_batch.py +310 -259
  334. mlrun/model_monitoring/stores/__init__.py +106 -0
  335. mlrun/model_monitoring/stores/kv_model_endpoint_store.py +448 -0
  336. mlrun/model_monitoring/stores/model_endpoint_store.py +147 -0
  337. mlrun/model_monitoring/stores/models/__init__.py +23 -0
  338. mlrun/model_monitoring/stores/models/base.py +18 -0
  339. mlrun/model_monitoring/stores/models/mysql.py +100 -0
  340. mlrun/model_monitoring/stores/models/sqlite.py +98 -0
  341. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +370 -0
  342. mlrun/model_monitoring/stream_processing_fs.py +239 -271
  343. mlrun/package/__init__.py +163 -0
  344. mlrun/package/context_handler.py +325 -0
  345. mlrun/package/errors.py +47 -0
  346. mlrun/package/packager.py +298 -0
  347. mlrun/{runtimes/package → package/packagers}/__init__.py +3 -1
  348. mlrun/package/packagers/default_packager.py +422 -0
  349. mlrun/package/packagers/numpy_packagers.py +612 -0
  350. mlrun/package/packagers/pandas_packagers.py +968 -0
  351. mlrun/package/packagers/python_standard_library_packagers.py +616 -0
  352. mlrun/package/packagers_manager.py +786 -0
  353. mlrun/package/utils/__init__.py +53 -0
  354. mlrun/package/utils/_archiver.py +226 -0
  355. mlrun/package/utils/_formatter.py +211 -0
  356. mlrun/package/utils/_pickler.py +234 -0
  357. mlrun/package/utils/_supported_format.py +71 -0
  358. mlrun/package/utils/log_hint_utils.py +93 -0
  359. mlrun/package/utils/type_hint_utils.py +298 -0
  360. mlrun/platforms/__init__.py +1 -1
  361. mlrun/platforms/iguazio.py +34 -2
  362. mlrun/platforms/other.py +1 -1
  363. mlrun/projects/__init__.py +1 -1
  364. mlrun/projects/operations.py +14 -9
  365. mlrun/projects/pipelines.py +31 -13
  366. mlrun/projects/project.py +762 -238
  367. mlrun/render.py +49 -19
  368. mlrun/run.py +57 -326
  369. mlrun/runtimes/__init__.py +3 -9
  370. mlrun/runtimes/base.py +247 -784
  371. mlrun/runtimes/constants.py +1 -1
  372. mlrun/runtimes/daskjob.py +45 -41
  373. mlrun/runtimes/funcdoc.py +43 -7
  374. mlrun/runtimes/function.py +66 -656
  375. mlrun/runtimes/function_reference.py +1 -1
  376. mlrun/runtimes/generators.py +1 -1
  377. mlrun/runtimes/kubejob.py +99 -116
  378. mlrun/runtimes/local.py +59 -66
  379. mlrun/runtimes/mpijob/__init__.py +1 -1
  380. mlrun/runtimes/mpijob/abstract.py +13 -15
  381. mlrun/runtimes/mpijob/v1.py +3 -1
  382. mlrun/runtimes/mpijob/v1alpha1.py +1 -1
  383. mlrun/runtimes/nuclio.py +1 -1
  384. mlrun/runtimes/pod.py +51 -26
  385. mlrun/runtimes/remotesparkjob.py +3 -1
  386. mlrun/runtimes/serving.py +12 -4
  387. mlrun/runtimes/sparkjob/__init__.py +1 -2
  388. mlrun/runtimes/sparkjob/abstract.py +44 -31
  389. mlrun/runtimes/sparkjob/spark3job.py +11 -9
  390. mlrun/runtimes/utils.py +61 -42
  391. mlrun/secrets.py +16 -18
  392. mlrun/serving/__init__.py +3 -2
  393. mlrun/serving/merger.py +1 -1
  394. mlrun/serving/remote.py +1 -1
  395. mlrun/serving/routers.py +39 -42
  396. mlrun/serving/server.py +23 -13
  397. mlrun/serving/serving_wrapper.py +1 -1
  398. mlrun/serving/states.py +172 -39
  399. mlrun/serving/utils.py +1 -1
  400. mlrun/serving/v1_serving.py +1 -1
  401. mlrun/serving/v2_serving.py +29 -21
  402. mlrun/utils/__init__.py +1 -2
  403. mlrun/utils/async_http.py +8 -1
  404. mlrun/utils/azure_vault.py +1 -1
  405. mlrun/utils/clones.py +2 -2
  406. mlrun/utils/condition_evaluator.py +65 -0
  407. mlrun/utils/db.py +52 -0
  408. mlrun/utils/helpers.py +188 -13
  409. mlrun/utils/http.py +89 -54
  410. mlrun/utils/logger.py +48 -8
  411. mlrun/utils/model_monitoring.py +132 -100
  412. mlrun/utils/notifications/__init__.py +1 -1
  413. mlrun/utils/notifications/notification/__init__.py +8 -6
  414. mlrun/utils/notifications/notification/base.py +20 -14
  415. mlrun/utils/notifications/notification/console.py +7 -4
  416. mlrun/utils/notifications/notification/git.py +36 -19
  417. mlrun/utils/notifications/notification/ipython.py +10 -8
  418. mlrun/utils/notifications/notification/slack.py +18 -13
  419. mlrun/utils/notifications/notification_pusher.py +377 -56
  420. mlrun/utils/regex.py +6 -1
  421. mlrun/utils/singleton.py +1 -1
  422. mlrun/utils/v3io_clients.py +1 -1
  423. mlrun/utils/vault.py +270 -269
  424. mlrun/utils/version/__init__.py +1 -1
  425. mlrun/utils/version/version.json +2 -2
  426. mlrun/utils/version/version.py +1 -1
  427. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/METADATA +16 -10
  428. mlrun-1.4.0.dist-info/RECORD +434 -0
  429. mlrun/api/api/endpoints/marketplace.py +0 -257
  430. mlrun/api/crud/marketplace.py +0 -221
  431. mlrun/api/crud/model_monitoring/model_endpoint_store.py +0 -847
  432. mlrun/api/db/filedb/db.py +0 -518
  433. mlrun/api/schemas/marketplace.py +0 -128
  434. mlrun/api/schemas/model_endpoints.py +0 -185
  435. mlrun/db/filedb.py +0 -891
  436. mlrun/feature_store/retrieval/online.py +0 -92
  437. mlrun/model_monitoring/constants.py +0 -67
  438. mlrun/runtimes/package/context_handler.py +0 -711
  439. mlrun/runtimes/sparkjob/spark2job.py +0 -59
  440. mlrun-1.3.3.dist-info/RECORD +0 -381
  441. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
  442. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
  443. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
  444. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
mlrun/api/crud/logs.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -21,13 +21,13 @@ from http import HTTPStatus
21
21
  from fastapi.concurrency import run_in_threadpool
22
22
  from sqlalchemy.orm import Session
23
23
 
24
- import mlrun.api.schemas
25
24
  import mlrun.api.utils.clients.log_collector as log_collector
25
+ import mlrun.api.utils.singletons.k8s
26
+ import mlrun.common.schemas
26
27
  import mlrun.utils.singleton
27
28
  from mlrun.api.api.utils import log_and_raise, log_path, project_logs_path
28
29
  from mlrun.api.constants import LogSources
29
30
  from mlrun.api.utils.singletons.db import get_db
30
- from mlrun.api.utils.singletons.k8s import get_k8s
31
31
  from mlrun.runtimes.constants import PodPhases
32
32
  from mlrun.utils import logger
33
33
 
@@ -85,7 +85,7 @@ class Logs(
85
85
  log_stream = None
86
86
  if (
87
87
  mlrun.mlconf.log_collector.mode
88
- == mlrun.api.schemas.LogsCollectorMode.best_effort
88
+ == mlrun.common.schemas.LogsCollectorMode.best_effort
89
89
  and source == LogSources.AUTO
90
90
  ):
91
91
  try:
@@ -112,7 +112,7 @@ class Logs(
112
112
  )
113
113
  elif (
114
114
  mlrun.mlconf.log_collector.mode
115
- == mlrun.api.schemas.LogsCollectorMode.sidecar
115
+ == mlrun.common.schemas.LogsCollectorMode.sidecar
116
116
  and source == LogSources.AUTO
117
117
  ):
118
118
  log_stream = self._get_logs_from_logs_collector(
@@ -123,7 +123,7 @@ class Logs(
123
123
  )
124
124
  elif (
125
125
  mlrun.mlconf.log_collector.mode
126
- == mlrun.api.schemas.LogsCollectorMode.legacy
126
+ == mlrun.common.schemas.LogsCollectorMode.legacy
127
127
  or source != LogSources.AUTO
128
128
  ):
129
129
  log_stream = self._get_logs_legacy_method_generator_wrapper(
@@ -178,10 +178,12 @@ class Logs(
178
178
  fp.seek(offset)
179
179
  log_contents = fp.read(size)
180
180
  elif source in [LogSources.AUTO, LogSources.K8S]:
181
- k8s = get_k8s()
181
+ k8s = mlrun.api.utils.singletons.k8s.get_k8s_helper()
182
182
  if k8s and k8s.is_running_inside_kubernetes_cluster():
183
183
  run_kind = run.get("metadata", {}).get("labels", {}).get("kind")
184
- pods = get_k8s().get_logger_pods(project, uid, run_kind)
184
+ pods = mlrun.api.utils.singletons.k8s.get_k8s_helper().get_logger_pods(
185
+ project, uid, run_kind
186
+ )
185
187
  if pods:
186
188
  if len(pods) > 1:
187
189
 
@@ -195,7 +197,7 @@ class Logs(
195
197
  )
196
198
  pod, pod_phase = list(pods.items())[0]
197
199
  if pod_phase != PodPhases.pending:
198
- resp = get_k8s().logs(pod)
200
+ resp = mlrun.api.utils.singletons.k8s.get_k8s_helper().logs(pod)
199
201
  if resp:
200
202
  if size == -1:
201
203
  log_contents = resp.encode()[offset:]
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,6 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  #
15
+ # flake8: noqa: F401 - this is until we take care of the F401 violations with respect to __all__ & sphinx
15
16
 
16
- from .model_endpoint_store import ModelEndpointStoreType # noqa: F401
17
- from .model_endpoints import ModelEndpoints # noqa: F401
17
+ from .model_endpoints import ModelEndpoints
@@ -0,0 +1,435 @@
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 typing import Any, Dict, List, Optional, Set
17
+
18
+ import numpy as np
19
+ import pandas as pd
20
+ from fastapi.concurrency import run_in_threadpool
21
+ from sqlalchemy.orm import Session
22
+
23
+ import mlrun.api.crud
24
+ import mlrun.api.utils.auth.verifier
25
+ import mlrun.common.model_monitoring
26
+ import mlrun.common.schemas
27
+ from mlrun.api.utils.singletons.project_member import get_project_member
28
+ from mlrun.errors import MLRunBadRequestError
29
+ from mlrun.utils import config, logger
30
+ from mlrun.utils.model_monitoring import parse_model_endpoint_store_prefix
31
+ from mlrun.utils.v3io_clients import get_frames_client
32
+
33
+
34
+ def grafana_list_projects(
35
+ db_session: Session,
36
+ auth_info: mlrun.common.schemas.AuthInfo,
37
+ query_parameters: Dict[str, str],
38
+ ) -> List[str]:
39
+ """
40
+ List available project names. Will be used as a filter in each grafana dashboard.
41
+
42
+ :param db_session: A session that manages the current dialog with the database.
43
+ :param auth_info: The auth info of the request.
44
+ :param query_parameters: Dictionary of query parameters attached to the request. Note that this parameter is
45
+ required by the API even though it is not being used in this function.
46
+
47
+ :return: List of available project names.
48
+ """
49
+
50
+ projects_output = get_project_member().list_projects(
51
+ db_session,
52
+ format_=mlrun.common.schemas.ProjectsFormat.name_only,
53
+ leader_session=auth_info.session,
54
+ )
55
+ return projects_output.projects
56
+
57
+
58
+ # The following functions were not removed due to backward compatibility that is related to iguazio version <= 3.5.2
59
+
60
+
61
+ async def grafana_list_endpoints(
62
+ body: Dict[str, Any],
63
+ query_parameters: Dict[str, str],
64
+ auth_info: mlrun.common.schemas.AuthInfo,
65
+ ) -> List[mlrun.common.schemas.GrafanaTable]:
66
+ project = query_parameters.get("project")
67
+
68
+ # Filters
69
+ model = query_parameters.get("model", None)
70
+ function = query_parameters.get("function", None)
71
+ labels = query_parameters.get("labels", "")
72
+ labels = labels.split(",") if labels else []
73
+
74
+ # Metrics to include
75
+ metrics = query_parameters.get("metrics", "")
76
+ metrics = metrics.split(",") if metrics else []
77
+
78
+ # Time range for metrics
79
+ start = body.get("rangeRaw", {}).get("start", "now-1h")
80
+ end = body.get("rangeRaw", {}).get("end", "now")
81
+
82
+ # Endpoint type filter - will be used to filter the router models
83
+ filter_router = query_parameters.get("filter_router", None)
84
+
85
+ if project:
86
+ await mlrun.api.utils.auth.verifier.AuthVerifier().query_project_permissions(
87
+ project,
88
+ mlrun.common.schemas.AuthorizationAction.read,
89
+ auth_info,
90
+ )
91
+ endpoint_list = await run_in_threadpool(
92
+ mlrun.api.crud.ModelEndpoints().list_model_endpoints,
93
+ auth_info=auth_info,
94
+ project=project,
95
+ model=model,
96
+ function=function,
97
+ labels=labels,
98
+ metrics=metrics,
99
+ start=start,
100
+ end=end,
101
+ )
102
+ allowed_endpoints = await mlrun.api.utils.auth.verifier.AuthVerifier().filter_project_resources_by_permissions(
103
+ mlrun.common.schemas.AuthorizationResourceTypes.model_endpoint,
104
+ endpoint_list.endpoints,
105
+ lambda _endpoint: (
106
+ _endpoint.metadata.project,
107
+ _endpoint.metadata.uid,
108
+ ),
109
+ auth_info,
110
+ )
111
+ endpoint_list.endpoints = allowed_endpoints
112
+
113
+ columns = [
114
+ mlrun.common.schemas.GrafanaColumn(text="endpoint_id", type="string"),
115
+ mlrun.common.schemas.GrafanaColumn(text="endpoint_function", type="string"),
116
+ mlrun.common.schemas.GrafanaColumn(text="endpoint_model", type="string"),
117
+ mlrun.common.schemas.GrafanaColumn(text="endpoint_model_class", type="string"),
118
+ mlrun.common.schemas.GrafanaColumn(text="first_request", type="time"),
119
+ mlrun.common.schemas.GrafanaColumn(text="last_request", type="time"),
120
+ mlrun.common.schemas.GrafanaColumn(text="accuracy", type="number"),
121
+ mlrun.common.schemas.GrafanaColumn(text="error_count", type="number"),
122
+ mlrun.common.schemas.GrafanaColumn(text="drift_status", type="number"),
123
+ mlrun.common.schemas.GrafanaColumn(
124
+ text="predictions_per_second", type="number"
125
+ ),
126
+ mlrun.common.schemas.GrafanaColumn(text="latency_avg_1h", type="number"),
127
+ ]
128
+
129
+ table = mlrun.common.schemas.GrafanaTable(columns=columns)
130
+ for endpoint in endpoint_list.endpoints:
131
+ if (
132
+ filter_router
133
+ and endpoint.status.endpoint_type
134
+ == mlrun.common.model_monitoring.EndpointType.ROUTER
135
+ ):
136
+ continue
137
+ row = [
138
+ endpoint.metadata.uid,
139
+ endpoint.spec.function_uri,
140
+ endpoint.spec.model,
141
+ endpoint.spec.model_class,
142
+ endpoint.status.first_request,
143
+ endpoint.status.last_request,
144
+ "N/A", # Leaving here for backwards compatibility
145
+ endpoint.status.error_count,
146
+ endpoint.status.drift_status,
147
+ ]
148
+
149
+ if (
150
+ endpoint.status.metrics
151
+ and mlrun.common.model_monitoring.EventKeyMetrics.GENERIC
152
+ in endpoint.status.metrics
153
+ ):
154
+ row.extend(
155
+ [
156
+ endpoint.status.metrics[
157
+ mlrun.common.model_monitoring.EventKeyMetrics.GENERIC
158
+ ][
159
+ mlrun.common.model_monitoring.EventLiveStats.PREDICTIONS_PER_SECOND
160
+ ],
161
+ endpoint.status.metrics[
162
+ mlrun.common.model_monitoring.EventKeyMetrics.GENERIC
163
+ ][mlrun.common.model_monitoring.EventLiveStats.LATENCY_AVG_1H],
164
+ ]
165
+ )
166
+
167
+ table.add_row(*row)
168
+
169
+ return [table]
170
+
171
+
172
+ async def grafana_individual_feature_analysis(
173
+ body: Dict[str, Any],
174
+ query_parameters: Dict[str, str],
175
+ auth_info: mlrun.common.schemas.AuthInfo,
176
+ ):
177
+ endpoint_id = query_parameters.get("endpoint_id")
178
+ project = query_parameters.get("project")
179
+ await mlrun.api.utils.auth.verifier.AuthVerifier().query_project_resource_permissions(
180
+ mlrun.common.schemas.AuthorizationResourceTypes.model_endpoint,
181
+ project,
182
+ endpoint_id,
183
+ mlrun.common.schemas.AuthorizationAction.read,
184
+ auth_info,
185
+ )
186
+
187
+ endpoint = await run_in_threadpool(
188
+ mlrun.api.crud.ModelEndpoints().get_model_endpoint,
189
+ auth_info=auth_info,
190
+ project=project,
191
+ endpoint_id=endpoint_id,
192
+ feature_analysis=True,
193
+ )
194
+
195
+ # Load JSON data from KV, make sure not to fail if a field is missing
196
+ feature_stats = endpoint.status.feature_stats or {}
197
+ current_stats = endpoint.status.current_stats or {}
198
+ drift_measures = endpoint.status.drift_measures or {}
199
+
200
+ table = mlrun.common.schemas.GrafanaTable(
201
+ columns=[
202
+ mlrun.common.schemas.GrafanaColumn(text="feature_name", type="string"),
203
+ mlrun.common.schemas.GrafanaColumn(text="actual_min", type="number"),
204
+ mlrun.common.schemas.GrafanaColumn(text="actual_mean", type="number"),
205
+ mlrun.common.schemas.GrafanaColumn(text="actual_max", type="number"),
206
+ mlrun.common.schemas.GrafanaColumn(text="expected_min", type="number"),
207
+ mlrun.common.schemas.GrafanaColumn(text="expected_mean", type="number"),
208
+ mlrun.common.schemas.GrafanaColumn(text="expected_max", type="number"),
209
+ mlrun.common.schemas.GrafanaColumn(text="tvd", type="number"),
210
+ mlrun.common.schemas.GrafanaColumn(text="hellinger", type="number"),
211
+ mlrun.common.schemas.GrafanaColumn(text="kld", type="number"),
212
+ ]
213
+ )
214
+
215
+ for feature, base_stat in feature_stats.items():
216
+ current_stat = current_stats.get(feature, {})
217
+ drift_measure = drift_measures.get(feature, {})
218
+
219
+ table.add_row(
220
+ feature,
221
+ current_stat.get("min"),
222
+ current_stat.get("mean"),
223
+ current_stat.get("max"),
224
+ base_stat.get("min"),
225
+ base_stat.get("mean"),
226
+ base_stat.get("max"),
227
+ drift_measure.get("tvd"),
228
+ drift_measure.get("hellinger"),
229
+ drift_measure.get("kld"),
230
+ )
231
+
232
+ return [table]
233
+
234
+
235
+ async def grafana_overall_feature_analysis(
236
+ body: Dict[str, Any],
237
+ query_parameters: Dict[str, str],
238
+ auth_info: mlrun.common.schemas.AuthInfo,
239
+ ):
240
+ endpoint_id = query_parameters.get("endpoint_id")
241
+ project = query_parameters.get("project")
242
+ await mlrun.api.utils.auth.verifier.AuthVerifier().query_project_resource_permissions(
243
+ mlrun.common.schemas.AuthorizationResourceTypes.model_endpoint,
244
+ project,
245
+ endpoint_id,
246
+ mlrun.common.schemas.AuthorizationAction.read,
247
+ auth_info,
248
+ )
249
+ endpoint = await run_in_threadpool(
250
+ mlrun.api.crud.ModelEndpoints().get_model_endpoint,
251
+ auth_info=auth_info,
252
+ project=project,
253
+ endpoint_id=endpoint_id,
254
+ feature_analysis=True,
255
+ )
256
+
257
+ table = mlrun.common.schemas.GrafanaTable(
258
+ columns=[
259
+ mlrun.common.schemas.GrafanaNumberColumn(text="tvd_sum"),
260
+ mlrun.common.schemas.GrafanaNumberColumn(text="tvd_mean"),
261
+ mlrun.common.schemas.GrafanaNumberColumn(text="hellinger_sum"),
262
+ mlrun.common.schemas.GrafanaNumberColumn(text="hellinger_mean"),
263
+ mlrun.common.schemas.GrafanaNumberColumn(text="kld_sum"),
264
+ mlrun.common.schemas.GrafanaNumberColumn(text="kld_mean"),
265
+ ]
266
+ )
267
+
268
+ if endpoint.status.drift_measures:
269
+ table.add_row(
270
+ endpoint.status.drift_measures.get("tvd_sum"),
271
+ endpoint.status.drift_measures.get("tvd_mean"),
272
+ endpoint.status.drift_measures.get("hellinger_sum"),
273
+ endpoint.status.drift_measures.get("hellinger_mean"),
274
+ endpoint.status.drift_measures.get("kld_sum"),
275
+ endpoint.status.drift_measures.get("kld_mean"),
276
+ )
277
+
278
+ return [table]
279
+
280
+
281
+ async def grafana_incoming_features(
282
+ body: Dict[str, Any],
283
+ query_parameters: Dict[str, str],
284
+ auth_info: mlrun.common.schemas.AuthInfo,
285
+ ):
286
+ endpoint_id = query_parameters.get("endpoint_id")
287
+ project = query_parameters.get("project")
288
+ start = body.get("rangeRaw", {}).get("from", "now-1h")
289
+ end = body.get("rangeRaw", {}).get("to", "now")
290
+
291
+ await mlrun.api.utils.auth.verifier.AuthVerifier().query_project_resource_permissions(
292
+ mlrun.common.schemas.AuthorizationResourceTypes.model_endpoint,
293
+ project,
294
+ endpoint_id,
295
+ mlrun.common.schemas.AuthorizationAction.read,
296
+ auth_info,
297
+ )
298
+
299
+ endpoint = await run_in_threadpool(
300
+ mlrun.api.crud.ModelEndpoints().get_model_endpoint,
301
+ auth_info=auth_info,
302
+ project=project,
303
+ endpoint_id=endpoint_id,
304
+ )
305
+
306
+ time_series = []
307
+
308
+ feature_names = endpoint.spec.feature_names
309
+
310
+ if not feature_names:
311
+ logger.warn(
312
+ "'feature_names' is either missing or not initialized in endpoint record",
313
+ endpoint_id=endpoint.metadata.uid,
314
+ )
315
+ return time_series
316
+
317
+ path = config.model_endpoint_monitoring.store_prefixes.default.format(
318
+ project=project, kind=mlrun.common.schemas.ModelMonitoringStoreKinds.EVENTS
319
+ )
320
+ _, container, path = parse_model_endpoint_store_prefix(path)
321
+
322
+ client = get_frames_client(
323
+ token=auth_info.data_session,
324
+ address=config.v3io_framesd,
325
+ container=container,
326
+ )
327
+
328
+ data: pd.DataFrame = await run_in_threadpool(
329
+ client.read,
330
+ backend="tsdb",
331
+ table=path,
332
+ columns=feature_names,
333
+ filter=f"endpoint_id=='{endpoint_id}'",
334
+ start=start,
335
+ end=end,
336
+ )
337
+
338
+ data.drop(["endpoint_id"], axis=1, inplace=True, errors="ignore")
339
+ data.index = data.index.astype(np.int64) // 10**6
340
+
341
+ for feature, indexed_values in data.to_dict().items():
342
+ target = mlrun.common.schemas.GrafanaTimeSeriesTarget(target=feature)
343
+ for index, value in indexed_values.items():
344
+ data_point = mlrun.common.schemas.GrafanaDataPoint(
345
+ value=float(value), timestamp=index
346
+ )
347
+ target.add_data_point(data_point)
348
+ time_series.append(target)
349
+
350
+ return time_series
351
+
352
+
353
+ def parse_query_parameters(request_body: Dict[str, Any]) -> Dict[str, str]:
354
+ """
355
+ This function searches for the target field in Grafana's SimpleJson json. Once located, the target string is
356
+ parsed by splitting on semi-colons (;). Each part in the resulting list is then split by an equal sign (=) to be
357
+ read as key-value pairs.
358
+ """
359
+
360
+ # Try to get the target
361
+ targets = request_body.get("targets", [])
362
+
363
+ if len(targets) > 1:
364
+ logger.warn(
365
+ f"The 'targets' list contains more than one element ({len(targets)}), all targets except the first one are "
366
+ f"ignored."
367
+ )
368
+
369
+ target_obj = targets[0] if targets else {}
370
+ target_query = target_obj.get("target") if target_obj else ""
371
+
372
+ if not target_query:
373
+ raise MLRunBadRequestError(f"Target missing in request body:\n {request_body}")
374
+
375
+ parameters = _parse_parameters(target_query)
376
+
377
+ return parameters
378
+
379
+
380
+ def parse_search_parameters(request_body: Dict[str, Any]) -> Dict[str, str]:
381
+ """
382
+ This function searches for the target field in Grafana's SimpleJson json. Once located, the target string is
383
+ parsed by splitting on semi-colons (;). Each part in the resulting list is then split by an equal sign (=) to be
384
+ read as key-value pairs.
385
+ """
386
+
387
+ # Try to get the target
388
+ target = request_body.get("target")
389
+
390
+ if not target:
391
+ raise MLRunBadRequestError(f"Target missing in request body:\n {request_body}")
392
+
393
+ parameters = _parse_parameters(target)
394
+
395
+ return parameters
396
+
397
+
398
+ def _parse_parameters(target_query):
399
+ parameters = {}
400
+ for query in filter(lambda q: q, target_query.split(";")):
401
+ query_parts = query.split("=")
402
+ if len(query_parts) < 2:
403
+ raise MLRunBadRequestError(
404
+ f"Query must contain both query key and query value. Expected query_key=query_value, found {query} "
405
+ f"instead."
406
+ )
407
+ parameters[query_parts[0]] = query_parts[1]
408
+ return parameters
409
+
410
+
411
+ def drop_grafana_escape_chars(query_parameters: Dict[str, str]):
412
+ query_parameters = dict(query_parameters)
413
+ endpoint_id = query_parameters.get("endpoint_id")
414
+ if endpoint_id is not None:
415
+ query_parameters["endpoint_id"] = endpoint_id.replace("\\", "")
416
+ return query_parameters
417
+
418
+
419
+ def validate_query_parameters(
420
+ query_parameters: Dict[str, str], supported_endpoints: Optional[Set[str]] = None
421
+ ):
422
+ """Validates the parameters sent via Grafana's SimpleJson query"""
423
+ if "target_endpoint" not in query_parameters:
424
+ raise MLRunBadRequestError(
425
+ f"Expected 'target_endpoint' field in query, found {query_parameters} instead"
426
+ )
427
+
428
+ if (
429
+ supported_endpoints is not None
430
+ and query_parameters["target_endpoint"] not in supported_endpoints
431
+ ):
432
+ raise MLRunBadRequestError(
433
+ f"{query_parameters['target_endpoint']} unsupported in query parameters: {query_parameters}. "
434
+ f"Currently supports: {','.join(supported_endpoints)}"
435
+ )