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

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

Potentially problematic release.


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

Files changed (444) hide show
  1. mlrun/__init__.py +3 -3
  2. mlrun/__main__.py +79 -37
  3. mlrun/api/__init__.py +1 -1
  4. mlrun/api/api/__init__.py +1 -1
  5. mlrun/api/api/api.py +4 -4
  6. mlrun/api/api/deps.py +10 -21
  7. mlrun/api/api/endpoints/__init__.py +1 -1
  8. mlrun/api/api/endpoints/artifacts.py +64 -36
  9. mlrun/api/api/endpoints/auth.py +4 -4
  10. mlrun/api/api/endpoints/background_tasks.py +11 -11
  11. mlrun/api/api/endpoints/client_spec.py +5 -5
  12. mlrun/api/api/endpoints/clusterization_spec.py +6 -4
  13. mlrun/api/api/endpoints/feature_store.py +124 -115
  14. mlrun/api/api/endpoints/files.py +22 -14
  15. mlrun/api/api/endpoints/frontend_spec.py +28 -21
  16. mlrun/api/api/endpoints/functions.py +142 -87
  17. mlrun/api/api/endpoints/grafana_proxy.py +89 -442
  18. mlrun/api/api/endpoints/healthz.py +20 -7
  19. mlrun/api/api/endpoints/hub.py +320 -0
  20. mlrun/api/api/endpoints/internal/__init__.py +1 -1
  21. mlrun/api/api/endpoints/internal/config.py +1 -1
  22. mlrun/api/api/endpoints/internal/memory_reports.py +9 -9
  23. mlrun/api/api/endpoints/logs.py +11 -11
  24. mlrun/api/api/endpoints/model_endpoints.py +74 -70
  25. mlrun/api/api/endpoints/operations.py +13 -9
  26. mlrun/api/api/endpoints/pipelines.py +93 -88
  27. mlrun/api/api/endpoints/projects.py +35 -35
  28. mlrun/api/api/endpoints/runs.py +69 -27
  29. mlrun/api/api/endpoints/runtime_resources.py +28 -28
  30. mlrun/api/api/endpoints/schedules.py +98 -41
  31. mlrun/api/api/endpoints/secrets.py +37 -32
  32. mlrun/api/api/endpoints/submit.py +12 -12
  33. mlrun/api/api/endpoints/tags.py +20 -22
  34. mlrun/api/api/utils.py +251 -42
  35. mlrun/api/constants.py +1 -1
  36. mlrun/api/crud/__init__.py +18 -15
  37. mlrun/api/crud/artifacts.py +10 -10
  38. mlrun/api/crud/client_spec.py +4 -4
  39. mlrun/api/crud/clusterization_spec.py +3 -3
  40. mlrun/api/crud/feature_store.py +54 -46
  41. mlrun/api/crud/functions.py +3 -3
  42. mlrun/api/crud/hub.py +312 -0
  43. mlrun/api/crud/logs.py +11 -9
  44. mlrun/api/crud/model_monitoring/__init__.py +3 -3
  45. mlrun/api/crud/model_monitoring/grafana.py +435 -0
  46. mlrun/api/crud/model_monitoring/model_endpoints.py +352 -129
  47. mlrun/api/crud/notifications.py +149 -0
  48. mlrun/api/crud/pipelines.py +67 -52
  49. mlrun/api/crud/projects.py +51 -23
  50. mlrun/api/crud/runs.py +7 -5
  51. mlrun/api/crud/runtime_resources.py +13 -13
  52. mlrun/api/{db/filedb → crud/runtimes}/__init__.py +1 -1
  53. mlrun/api/crud/runtimes/nuclio/__init__.py +14 -0
  54. mlrun/api/crud/runtimes/nuclio/function.py +505 -0
  55. mlrun/api/crud/runtimes/nuclio/helpers.py +310 -0
  56. mlrun/api/crud/secrets.py +88 -46
  57. mlrun/api/crud/tags.py +5 -5
  58. mlrun/api/db/__init__.py +1 -1
  59. mlrun/api/db/base.py +102 -54
  60. mlrun/api/db/init_db.py +2 -3
  61. mlrun/api/db/session.py +4 -12
  62. mlrun/api/db/sqldb/__init__.py +1 -1
  63. mlrun/api/db/sqldb/db.py +439 -196
  64. mlrun/api/db/sqldb/helpers.py +1 -1
  65. mlrun/api/db/sqldb/models/__init__.py +3 -3
  66. mlrun/api/db/sqldb/models/models_mysql.py +82 -64
  67. mlrun/api/db/sqldb/models/models_sqlite.py +76 -64
  68. mlrun/api/db/sqldb/session.py +27 -20
  69. mlrun/api/initial_data.py +82 -24
  70. mlrun/api/launcher.py +196 -0
  71. mlrun/api/main.py +91 -22
  72. mlrun/api/middlewares.py +6 -5
  73. mlrun/api/migrations_mysql/env.py +1 -1
  74. mlrun/api/migrations_mysql/versions/28383af526f3_market_place_to_hub.py +40 -0
  75. mlrun/api/migrations_mysql/versions/32bae1b0e29c_increase_timestamp_fields_precision.py +1 -1
  76. mlrun/api/migrations_mysql/versions/4903aef6a91d_tag_foreign_key_and_cascades.py +1 -1
  77. mlrun/api/migrations_mysql/versions/5f1351c88a19_adding_background_tasks_table.py +1 -1
  78. mlrun/api/migrations_mysql/versions/88e656800d6a_add_requested_logs_column_and_index_to_.py +1 -1
  79. mlrun/api/migrations_mysql/versions/9d16de5f03a7_adding_data_versions_table.py +1 -1
  80. mlrun/api/migrations_mysql/versions/b86f5b53f3d7_adding_name_and_updated_to_runs_table.py +1 -1
  81. mlrun/api/migrations_mysql/versions/c4af40b0bf61_init.py +1 -1
  82. mlrun/api/migrations_mysql/versions/c905d15bd91d_notifications.py +72 -0
  83. mlrun/api/migrations_mysql/versions/ee041e8fdaa0_adding_next_run_time_column_to_schedule_.py +1 -1
  84. mlrun/api/migrations_sqlite/env.py +1 -1
  85. mlrun/api/migrations_sqlite/versions/11f8dd2dc9fe_init.py +1 -1
  86. mlrun/api/migrations_sqlite/versions/1c954f8cb32d_schedule_last_run_uri.py +1 -1
  87. mlrun/api/migrations_sqlite/versions/2b6d23c715aa_adding_feature_sets.py +1 -1
  88. mlrun/api/migrations_sqlite/versions/4acd9430b093_market_place_to_hub.py +77 -0
  89. mlrun/api/migrations_sqlite/versions/6401142f2d7c_adding_next_run_time_column_to_schedule_.py +1 -1
  90. mlrun/api/migrations_sqlite/versions/64d90a1a69bc_adding_background_tasks_table.py +1 -1
  91. mlrun/api/migrations_sqlite/versions/803438ecd005_add_requested_logs_column_to_runs.py +1 -1
  92. mlrun/api/migrations_sqlite/versions/863114f0c659_refactoring_feature_set.py +1 -1
  93. mlrun/api/migrations_sqlite/versions/959ae00528ad_notifications.py +63 -0
  94. mlrun/api/migrations_sqlite/versions/accf9fc83d38_adding_data_versions_table.py +1 -1
  95. mlrun/api/migrations_sqlite/versions/b68e8e897a28_schedule_labels.py +1 -1
  96. mlrun/api/migrations_sqlite/versions/bcd0c1f9720c_adding_project_labels.py +1 -1
  97. mlrun/api/migrations_sqlite/versions/cf21882f938e_schedule_id.py +1 -1
  98. mlrun/api/migrations_sqlite/versions/d781f58f607f_tag_object_name_string.py +1 -1
  99. mlrun/api/migrations_sqlite/versions/deac06871ace_adding_marketplace_sources_table.py +1 -1
  100. mlrun/api/migrations_sqlite/versions/e1dd5983c06b_schedule_concurrency_limit.py +1 -1
  101. mlrun/api/migrations_sqlite/versions/e5594ed3ab53_adding_name_and_updated_to_runs_table.py +1 -1
  102. mlrun/api/migrations_sqlite/versions/f4249b4ba6fa_adding_feature_vectors.py +1 -1
  103. mlrun/api/migrations_sqlite/versions/f7b5a1a03629_adding_feature_labels.py +1 -1
  104. mlrun/api/schemas/__init__.py +216 -138
  105. mlrun/api/utils/__init__.py +1 -1
  106. mlrun/api/utils/asyncio.py +1 -1
  107. mlrun/api/utils/auth/__init__.py +1 -1
  108. mlrun/api/utils/auth/providers/__init__.py +1 -1
  109. mlrun/api/utils/auth/providers/base.py +7 -7
  110. mlrun/api/utils/auth/providers/nop.py +6 -7
  111. mlrun/api/utils/auth/providers/opa.py +17 -17
  112. mlrun/api/utils/auth/verifier.py +36 -34
  113. mlrun/api/utils/background_tasks.py +24 -24
  114. mlrun/{builder.py → api/utils/builder.py} +216 -123
  115. mlrun/api/utils/clients/__init__.py +1 -1
  116. mlrun/api/utils/clients/chief.py +19 -4
  117. mlrun/api/utils/clients/iguazio.py +106 -60
  118. mlrun/api/utils/clients/log_collector.py +1 -1
  119. mlrun/api/utils/clients/nuclio.py +23 -23
  120. mlrun/api/utils/clients/protocols/grpc.py +2 -2
  121. mlrun/api/utils/db/__init__.py +1 -1
  122. mlrun/api/utils/db/alembic.py +1 -1
  123. mlrun/api/utils/db/backup.py +1 -1
  124. mlrun/api/utils/db/mysql.py +24 -25
  125. mlrun/api/utils/db/sql_collation.py +1 -1
  126. mlrun/api/utils/db/sqlite_migration.py +2 -2
  127. mlrun/api/utils/events/__init__.py +14 -0
  128. mlrun/api/utils/events/base.py +57 -0
  129. mlrun/api/utils/events/events_factory.py +41 -0
  130. mlrun/api/utils/events/iguazio.py +217 -0
  131. mlrun/api/utils/events/nop.py +55 -0
  132. mlrun/api/utils/helpers.py +16 -13
  133. mlrun/api/utils/memory_reports.py +1 -1
  134. mlrun/api/utils/periodic.py +6 -3
  135. mlrun/api/utils/projects/__init__.py +1 -1
  136. mlrun/api/utils/projects/follower.py +33 -33
  137. mlrun/api/utils/projects/leader.py +36 -34
  138. mlrun/api/utils/projects/member.py +27 -27
  139. mlrun/api/utils/projects/remotes/__init__.py +1 -1
  140. mlrun/api/utils/projects/remotes/follower.py +13 -13
  141. mlrun/api/utils/projects/remotes/leader.py +10 -10
  142. mlrun/api/utils/projects/remotes/nop_follower.py +27 -21
  143. mlrun/api/utils/projects/remotes/nop_leader.py +17 -16
  144. mlrun/api/utils/scheduler.py +140 -51
  145. mlrun/api/utils/singletons/__init__.py +1 -1
  146. mlrun/api/utils/singletons/db.py +9 -15
  147. mlrun/api/utils/singletons/k8s.py +677 -5
  148. mlrun/api/utils/singletons/logs_dir.py +1 -1
  149. mlrun/api/utils/singletons/project_member.py +1 -1
  150. mlrun/api/utils/singletons/scheduler.py +1 -1
  151. mlrun/artifacts/__init__.py +2 -2
  152. mlrun/artifacts/base.py +8 -2
  153. mlrun/artifacts/dataset.py +5 -3
  154. mlrun/artifacts/manager.py +7 -1
  155. mlrun/artifacts/model.py +15 -4
  156. mlrun/artifacts/plots.py +1 -1
  157. mlrun/common/__init__.py +1 -1
  158. mlrun/common/constants.py +15 -0
  159. mlrun/common/model_monitoring.py +209 -0
  160. mlrun/common/schemas/__init__.py +167 -0
  161. mlrun/{api → common}/schemas/artifact.py +13 -14
  162. mlrun/{api → common}/schemas/auth.py +10 -8
  163. mlrun/{api → common}/schemas/background_task.py +3 -3
  164. mlrun/{api → common}/schemas/client_spec.py +1 -1
  165. mlrun/{api → common}/schemas/clusterization_spec.py +3 -3
  166. mlrun/{api → common}/schemas/constants.py +21 -8
  167. mlrun/common/schemas/events.py +36 -0
  168. mlrun/{api → common}/schemas/feature_store.py +2 -1
  169. mlrun/{api → common}/schemas/frontend_spec.py +7 -6
  170. mlrun/{api → common}/schemas/function.py +5 -5
  171. mlrun/{api → common}/schemas/http.py +3 -3
  172. mlrun/common/schemas/hub.py +134 -0
  173. mlrun/{api → common}/schemas/k8s.py +3 -3
  174. mlrun/{api → common}/schemas/memory_reports.py +1 -1
  175. mlrun/common/schemas/model_endpoints.py +342 -0
  176. mlrun/common/schemas/notification.py +57 -0
  177. mlrun/{api → common}/schemas/object.py +6 -6
  178. mlrun/{api → common}/schemas/pipeline.py +3 -3
  179. mlrun/{api → common}/schemas/project.py +6 -5
  180. mlrun/common/schemas/regex.py +24 -0
  181. mlrun/common/schemas/runs.py +30 -0
  182. mlrun/{api → common}/schemas/runtime_resource.py +3 -3
  183. mlrun/{api → common}/schemas/schedule.py +19 -7
  184. mlrun/{api → common}/schemas/secret.py +3 -3
  185. mlrun/{api → common}/schemas/tag.py +2 -2
  186. mlrun/common/types.py +25 -0
  187. mlrun/config.py +152 -20
  188. mlrun/data_types/__init__.py +7 -2
  189. mlrun/data_types/data_types.py +4 -2
  190. mlrun/data_types/infer.py +1 -1
  191. mlrun/data_types/spark.py +10 -3
  192. mlrun/datastore/__init__.py +10 -3
  193. mlrun/datastore/azure_blob.py +1 -1
  194. mlrun/datastore/base.py +185 -53
  195. mlrun/datastore/datastore.py +1 -1
  196. mlrun/datastore/filestore.py +1 -1
  197. mlrun/datastore/google_cloud_storage.py +1 -1
  198. mlrun/datastore/inmem.py +4 -1
  199. mlrun/datastore/redis.py +1 -1
  200. mlrun/datastore/s3.py +1 -1
  201. mlrun/datastore/sources.py +192 -70
  202. mlrun/datastore/spark_udf.py +44 -0
  203. mlrun/datastore/store_resources.py +4 -4
  204. mlrun/datastore/targets.py +115 -45
  205. mlrun/datastore/utils.py +127 -5
  206. mlrun/datastore/v3io.py +1 -1
  207. mlrun/datastore/wasbfs/__init__.py +1 -1
  208. mlrun/datastore/wasbfs/fs.py +1 -1
  209. mlrun/db/__init__.py +7 -5
  210. mlrun/db/base.py +112 -68
  211. mlrun/db/httpdb.py +445 -277
  212. mlrun/db/nopdb.py +491 -0
  213. mlrun/db/sqldb.py +112 -65
  214. mlrun/errors.py +6 -1
  215. mlrun/execution.py +44 -22
  216. mlrun/feature_store/__init__.py +1 -1
  217. mlrun/feature_store/api.py +143 -95
  218. mlrun/feature_store/common.py +16 -20
  219. mlrun/feature_store/feature_set.py +42 -12
  220. mlrun/feature_store/feature_vector.py +32 -21
  221. mlrun/feature_store/ingestion.py +9 -12
  222. mlrun/feature_store/retrieval/__init__.py +3 -2
  223. mlrun/feature_store/retrieval/base.py +388 -66
  224. mlrun/feature_store/retrieval/dask_merger.py +63 -151
  225. mlrun/feature_store/retrieval/job.py +30 -12
  226. mlrun/feature_store/retrieval/local_merger.py +40 -133
  227. mlrun/feature_store/retrieval/spark_merger.py +129 -127
  228. mlrun/feature_store/retrieval/storey_merger.py +173 -0
  229. mlrun/feature_store/steps.py +132 -15
  230. mlrun/features.py +8 -3
  231. mlrun/frameworks/__init__.py +1 -1
  232. mlrun/frameworks/_common/__init__.py +1 -1
  233. mlrun/frameworks/_common/artifacts_library.py +1 -1
  234. mlrun/frameworks/_common/mlrun_interface.py +1 -1
  235. mlrun/frameworks/_common/model_handler.py +1 -1
  236. mlrun/frameworks/_common/plan.py +1 -1
  237. mlrun/frameworks/_common/producer.py +1 -1
  238. mlrun/frameworks/_common/utils.py +1 -1
  239. mlrun/frameworks/_dl_common/__init__.py +1 -1
  240. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -1
  241. mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
  242. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +1 -1
  243. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +1 -1
  244. mlrun/frameworks/_dl_common/model_handler.py +1 -1
  245. mlrun/frameworks/_dl_common/utils.py +1 -1
  246. mlrun/frameworks/_ml_common/__init__.py +1 -1
  247. mlrun/frameworks/_ml_common/artifacts_library.py +1 -1
  248. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -1
  249. mlrun/frameworks/_ml_common/loggers/logger.py +1 -1
  250. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
  251. mlrun/frameworks/_ml_common/model_handler.py +1 -1
  252. mlrun/frameworks/_ml_common/pkl_model_server.py +13 -1
  253. mlrun/frameworks/_ml_common/plan.py +1 -1
  254. mlrun/frameworks/_ml_common/plans/__init__.py +1 -1
  255. mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +1 -6
  256. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +1 -1
  257. mlrun/frameworks/_ml_common/plans/dataset_plan.py +1 -1
  258. mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +1 -1
  259. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +1 -1
  260. mlrun/frameworks/_ml_common/producer.py +1 -1
  261. mlrun/frameworks/_ml_common/utils.py +1 -1
  262. mlrun/frameworks/auto_mlrun/__init__.py +1 -1
  263. mlrun/frameworks/auto_mlrun/auto_mlrun.py +1 -1
  264. mlrun/frameworks/huggingface/__init__.py +1 -1
  265. mlrun/frameworks/huggingface/model_server.py +1 -1
  266. mlrun/frameworks/lgbm/__init__.py +1 -1
  267. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -1
  268. mlrun/frameworks/lgbm/callbacks/callback.py +1 -1
  269. mlrun/frameworks/lgbm/callbacks/logging_callback.py +1 -1
  270. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +1 -1
  271. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -1
  272. mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -1
  273. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +1 -1
  274. mlrun/frameworks/lgbm/mlrun_interfaces/model_mlrun_interface.py +1 -1
  275. mlrun/frameworks/lgbm/model_handler.py +1 -1
  276. mlrun/frameworks/lgbm/model_server.py +1 -1
  277. mlrun/frameworks/lgbm/utils.py +1 -1
  278. mlrun/frameworks/onnx/__init__.py +1 -1
  279. mlrun/frameworks/onnx/dataset.py +1 -1
  280. mlrun/frameworks/onnx/mlrun_interface.py +1 -1
  281. mlrun/frameworks/onnx/model_handler.py +1 -1
  282. mlrun/frameworks/onnx/model_server.py +1 -1
  283. mlrun/frameworks/parallel_coordinates.py +1 -1
  284. mlrun/frameworks/pytorch/__init__.py +1 -1
  285. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -1
  286. mlrun/frameworks/pytorch/callbacks/callback.py +1 -1
  287. mlrun/frameworks/pytorch/callbacks/logging_callback.py +1 -1
  288. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +1 -1
  289. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +1 -1
  290. mlrun/frameworks/pytorch/callbacks_handler.py +1 -1
  291. mlrun/frameworks/pytorch/mlrun_interface.py +1 -1
  292. mlrun/frameworks/pytorch/model_handler.py +1 -1
  293. mlrun/frameworks/pytorch/model_server.py +1 -1
  294. mlrun/frameworks/pytorch/utils.py +1 -1
  295. mlrun/frameworks/sklearn/__init__.py +1 -1
  296. mlrun/frameworks/sklearn/estimator.py +1 -1
  297. mlrun/frameworks/sklearn/metric.py +1 -1
  298. mlrun/frameworks/sklearn/metrics_library.py +1 -1
  299. mlrun/frameworks/sklearn/mlrun_interface.py +1 -1
  300. mlrun/frameworks/sklearn/model_handler.py +1 -1
  301. mlrun/frameworks/sklearn/utils.py +1 -1
  302. mlrun/frameworks/tf_keras/__init__.py +1 -1
  303. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -1
  304. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  305. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +1 -1
  306. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +1 -1
  307. mlrun/frameworks/tf_keras/mlrun_interface.py +1 -1
  308. mlrun/frameworks/tf_keras/model_handler.py +1 -1
  309. mlrun/frameworks/tf_keras/model_server.py +1 -1
  310. mlrun/frameworks/tf_keras/utils.py +1 -1
  311. mlrun/frameworks/xgboost/__init__.py +1 -1
  312. mlrun/frameworks/xgboost/mlrun_interface.py +1 -1
  313. mlrun/frameworks/xgboost/model_handler.py +1 -1
  314. mlrun/frameworks/xgboost/utils.py +1 -1
  315. mlrun/k8s_utils.py +14 -765
  316. mlrun/kfpops.py +14 -17
  317. mlrun/launcher/__init__.py +13 -0
  318. mlrun/launcher/base.py +406 -0
  319. mlrun/launcher/client.py +159 -0
  320. mlrun/launcher/factory.py +50 -0
  321. mlrun/launcher/local.py +276 -0
  322. mlrun/launcher/remote.py +178 -0
  323. mlrun/lists.py +10 -2
  324. mlrun/mlutils/__init__.py +1 -1
  325. mlrun/mlutils/data.py +1 -1
  326. mlrun/mlutils/models.py +1 -1
  327. mlrun/mlutils/plots.py +1 -1
  328. mlrun/model.py +252 -14
  329. mlrun/model_monitoring/__init__.py +41 -0
  330. mlrun/model_monitoring/features_drift_table.py +1 -1
  331. mlrun/model_monitoring/helpers.py +123 -38
  332. mlrun/model_monitoring/model_endpoint.py +144 -0
  333. mlrun/model_monitoring/model_monitoring_batch.py +310 -259
  334. mlrun/model_monitoring/stores/__init__.py +106 -0
  335. mlrun/model_monitoring/stores/kv_model_endpoint_store.py +448 -0
  336. mlrun/model_monitoring/stores/model_endpoint_store.py +147 -0
  337. mlrun/model_monitoring/stores/models/__init__.py +23 -0
  338. mlrun/model_monitoring/stores/models/base.py +18 -0
  339. mlrun/model_monitoring/stores/models/mysql.py +100 -0
  340. mlrun/model_monitoring/stores/models/sqlite.py +98 -0
  341. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +370 -0
  342. mlrun/model_monitoring/stream_processing_fs.py +239 -271
  343. mlrun/package/__init__.py +163 -0
  344. mlrun/package/context_handler.py +325 -0
  345. mlrun/package/errors.py +47 -0
  346. mlrun/package/packager.py +298 -0
  347. mlrun/{runtimes/package → package/packagers}/__init__.py +3 -1
  348. mlrun/package/packagers/default_packager.py +422 -0
  349. mlrun/package/packagers/numpy_packagers.py +612 -0
  350. mlrun/package/packagers/pandas_packagers.py +968 -0
  351. mlrun/package/packagers/python_standard_library_packagers.py +616 -0
  352. mlrun/package/packagers_manager.py +786 -0
  353. mlrun/package/utils/__init__.py +53 -0
  354. mlrun/package/utils/_archiver.py +226 -0
  355. mlrun/package/utils/_formatter.py +211 -0
  356. mlrun/package/utils/_pickler.py +234 -0
  357. mlrun/package/utils/_supported_format.py +71 -0
  358. mlrun/package/utils/log_hint_utils.py +93 -0
  359. mlrun/package/utils/type_hint_utils.py +298 -0
  360. mlrun/platforms/__init__.py +1 -1
  361. mlrun/platforms/iguazio.py +34 -2
  362. mlrun/platforms/other.py +1 -1
  363. mlrun/projects/__init__.py +1 -1
  364. mlrun/projects/operations.py +14 -9
  365. mlrun/projects/pipelines.py +31 -13
  366. mlrun/projects/project.py +762 -238
  367. mlrun/render.py +49 -19
  368. mlrun/run.py +57 -326
  369. mlrun/runtimes/__init__.py +3 -9
  370. mlrun/runtimes/base.py +247 -784
  371. mlrun/runtimes/constants.py +1 -1
  372. mlrun/runtimes/daskjob.py +45 -41
  373. mlrun/runtimes/funcdoc.py +43 -7
  374. mlrun/runtimes/function.py +66 -656
  375. mlrun/runtimes/function_reference.py +1 -1
  376. mlrun/runtimes/generators.py +1 -1
  377. mlrun/runtimes/kubejob.py +99 -116
  378. mlrun/runtimes/local.py +59 -66
  379. mlrun/runtimes/mpijob/__init__.py +1 -1
  380. mlrun/runtimes/mpijob/abstract.py +13 -15
  381. mlrun/runtimes/mpijob/v1.py +3 -1
  382. mlrun/runtimes/mpijob/v1alpha1.py +1 -1
  383. mlrun/runtimes/nuclio.py +1 -1
  384. mlrun/runtimes/pod.py +51 -26
  385. mlrun/runtimes/remotesparkjob.py +3 -1
  386. mlrun/runtimes/serving.py +12 -4
  387. mlrun/runtimes/sparkjob/__init__.py +1 -2
  388. mlrun/runtimes/sparkjob/abstract.py +44 -31
  389. mlrun/runtimes/sparkjob/spark3job.py +11 -9
  390. mlrun/runtimes/utils.py +61 -42
  391. mlrun/secrets.py +16 -18
  392. mlrun/serving/__init__.py +3 -2
  393. mlrun/serving/merger.py +1 -1
  394. mlrun/serving/remote.py +1 -1
  395. mlrun/serving/routers.py +39 -42
  396. mlrun/serving/server.py +23 -13
  397. mlrun/serving/serving_wrapper.py +1 -1
  398. mlrun/serving/states.py +172 -39
  399. mlrun/serving/utils.py +1 -1
  400. mlrun/serving/v1_serving.py +1 -1
  401. mlrun/serving/v2_serving.py +29 -21
  402. mlrun/utils/__init__.py +1 -2
  403. mlrun/utils/async_http.py +8 -1
  404. mlrun/utils/azure_vault.py +1 -1
  405. mlrun/utils/clones.py +2 -2
  406. mlrun/utils/condition_evaluator.py +65 -0
  407. mlrun/utils/db.py +52 -0
  408. mlrun/utils/helpers.py +188 -13
  409. mlrun/utils/http.py +89 -54
  410. mlrun/utils/logger.py +48 -8
  411. mlrun/utils/model_monitoring.py +132 -100
  412. mlrun/utils/notifications/__init__.py +1 -1
  413. mlrun/utils/notifications/notification/__init__.py +8 -6
  414. mlrun/utils/notifications/notification/base.py +20 -14
  415. mlrun/utils/notifications/notification/console.py +7 -4
  416. mlrun/utils/notifications/notification/git.py +36 -19
  417. mlrun/utils/notifications/notification/ipython.py +10 -8
  418. mlrun/utils/notifications/notification/slack.py +18 -13
  419. mlrun/utils/notifications/notification_pusher.py +377 -56
  420. mlrun/utils/regex.py +6 -1
  421. mlrun/utils/singleton.py +1 -1
  422. mlrun/utils/v3io_clients.py +1 -1
  423. mlrun/utils/vault.py +270 -269
  424. mlrun/utils/version/__init__.py +1 -1
  425. mlrun/utils/version/version.json +2 -2
  426. mlrun/utils/version/version.py +1 -1
  427. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/METADATA +16 -10
  428. mlrun-1.4.0.dist-info/RECORD +434 -0
  429. mlrun/api/api/endpoints/marketplace.py +0 -257
  430. mlrun/api/crud/marketplace.py +0 -221
  431. mlrun/api/crud/model_monitoring/model_endpoint_store.py +0 -847
  432. mlrun/api/db/filedb/db.py +0 -518
  433. mlrun/api/schemas/marketplace.py +0 -128
  434. mlrun/api/schemas/model_endpoints.py +0 -185
  435. mlrun/db/filedb.py +0 -891
  436. mlrun/feature_store/retrieval/online.py +0 -92
  437. mlrun/model_monitoring/constants.py +0 -67
  438. mlrun/runtimes/package/context_handler.py +0 -711
  439. mlrun/runtimes/sparkjob/spark2job.py +0 -59
  440. mlrun-1.3.3rc1.dist-info/RECORD +0 -381
  441. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
  442. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
  443. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
  444. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
mlrun/db/httpdb.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.
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
  import enum
15
15
  import http
16
+ import re
16
17
  import tempfile
17
18
  import time
18
19
  import traceback
@@ -27,11 +28,12 @@ import requests
27
28
  import semver
28
29
 
29
30
  import mlrun
31
+ import mlrun.api.utils.helpers
32
+ import mlrun.common.schemas
33
+ import mlrun.model_monitoring.model_endpoint
30
34
  import mlrun.projects
31
- from mlrun.api import schemas
32
35
  from mlrun.errors import MLRunInvalidArgumentError, err_to_str
33
36
 
34
- from ..api.schemas import ModelEndpoint
35
37
  from ..artifacts import Artifact
36
38
  from ..config import config
37
39
  from ..feature_store import FeatureSet, FeatureVector
@@ -98,6 +100,12 @@ class HTTPRunDB(RunDBInterface):
98
100
  """
99
101
 
100
102
  kind = "http"
103
+ # by default we don't retry on POST request as they are usually not idempotent
104
+ # here is a list of identified POST requests that are idempotent ('store' vs 'create') and can be retried
105
+ RETRIABLE_POST_PATHS = [
106
+ r"\/?projects\/.+\/artifacts\/.+\/.+",
107
+ r"\/?run\/.+\/.+",
108
+ ]
101
109
 
102
110
  def __init__(self, base_url, user="", password="", token=""):
103
111
  self.base_url = base_url
@@ -192,13 +200,13 @@ class HTTPRunDB(RunDBInterface):
192
200
  if "Authorization" not in kw.setdefault("headers", {}):
193
201
  kw["headers"].update({"Authorization": "Bearer " + self.token})
194
202
 
195
- if mlrun.api.schemas.HeaderNames.client_version not in kw.setdefault(
203
+ if mlrun.common.schemas.HeaderNames.client_version not in kw.setdefault(
196
204
  "headers", {}
197
205
  ):
198
206
  kw["headers"].update(
199
207
  {
200
- mlrun.api.schemas.HeaderNames.client_version: self.client_version,
201
- mlrun.api.schemas.HeaderNames.python_version: self.python_version,
208
+ mlrun.common.schemas.HeaderNames.client_version: self.client_version,
209
+ mlrun.common.schemas.HeaderNames.python_version: self.python_version,
202
210
  }
203
211
  )
204
212
 
@@ -210,8 +218,10 @@ class HTTPRunDB(RunDBInterface):
210
218
  if isinstance(dict_[key], enum.Enum):
211
219
  dict_[key] = dict_[key].value
212
220
 
213
- if not self.session:
214
- self.session = self._init_session()
221
+ # if the method is POST, we need to update the session with the appropriate retry policy
222
+ if not self.session or method == "POST":
223
+ retry_on_post = self._is_retry_on_post_allowed(method, path)
224
+ self.session = self._init_session(retry_on_post)
215
225
 
216
226
  try:
217
227
  response = self.session.request(
@@ -239,16 +249,29 @@ class HTTPRunDB(RunDBInterface):
239
249
 
240
250
  return response
241
251
 
242
- def _init_session(self):
252
+ def _init_session(self, retry_on_post: bool = False):
243
253
  return mlrun.utils.HTTPSessionWithRetry(
244
254
  retry_on_exception=config.httpdb.retry_api_call_on_exception
245
- == mlrun.api.schemas.HTTPSessionRetryMode.enabled.value
255
+ == mlrun.common.schemas.HTTPSessionRetryMode.enabled.value,
256
+ retry_on_post=retry_on_post,
246
257
  )
247
258
 
248
259
  def _path_of(self, prefix, project, uid):
249
260
  project = project or config.default_project
250
261
  return f"{prefix}/{project}/{uid}"
251
262
 
263
+ def _is_retry_on_post_allowed(self, method, path: str):
264
+ """
265
+ Check if the given path is allowed to be retried on POST method
266
+ :param method: used to verify that the method is POST since if there is no session initialized there is no
267
+ need to initialize it with retry policy for POST when the method is not POST
268
+ :param path: the path to check
269
+ :return: True if the path is allowed to be retried on POST method and method is POST, False otherwise
270
+ """
271
+ return method == "POST" and any(
272
+ re.match(regex, path) for regex in self.RETRIABLE_POST_PATHS
273
+ )
274
+
252
275
  def connect(self, secrets=None):
253
276
  """Connect to the MLRun API server. Must be called prior to executing any other method.
254
277
  The code utilizes the URL for the API server from the configuration - ``mlconf.dbpath``.
@@ -499,16 +522,16 @@ class HTTPRunDB(RunDBInterface):
499
522
  body = _as_json(struct)
500
523
  self.api_call("POST", path, error, params=params, body=body)
501
524
 
502
- def update_run(self, updates: dict, uid, project="", iter=0):
525
+ def update_run(self, updates: dict, uid, project="", iter=0, timeout=45):
503
526
  """Update the details of a stored run in the DB."""
504
527
 
505
528
  path = self._path_of("run", project, uid)
506
529
  params = {"iter": iter}
507
530
  error = f"update run {project}/{uid}"
508
531
  body = _as_json(updates)
509
- self.api_call("PATCH", path, error, params=params, body=body)
532
+ self.api_call("PATCH", path, error, params=params, body=body, timeout=timeout)
510
533
 
511
- def abort_run(self, uid, project="", iter=0):
534
+ def abort_run(self, uid, project="", iter=0, timeout=45):
512
535
  """
513
536
  Abort a running run - will remove the run's runtime resources and mark its state as aborted
514
537
  """
@@ -517,6 +540,7 @@ class HTTPRunDB(RunDBInterface):
517
540
  uid,
518
541
  project,
519
542
  iter,
543
+ timeout,
520
544
  )
521
545
 
522
546
  def read_run(self, uid, project="", iter=0):
@@ -548,28 +572,33 @@ class HTTPRunDB(RunDBInterface):
548
572
 
549
573
  def list_runs(
550
574
  self,
551
- name=None,
575
+ name: Optional[str] = None,
552
576
  uid: Optional[Union[str, List[str]]] = None,
553
- project=None,
554
- labels=None,
555
- state=None,
556
- sort=True,
557
- last=0,
558
- iter=False,
559
- start_time_from: datetime = None,
560
- start_time_to: datetime = None,
561
- last_update_time_from: datetime = None,
562
- last_update_time_to: datetime = None,
563
- partition_by: Union[schemas.RunPartitionByField, str] = None,
577
+ project: Optional[str] = None,
578
+ labels: Optional[Union[str, List[str]]] = None,
579
+ state: Optional[str] = None,
580
+ sort: bool = True,
581
+ last: int = 0,
582
+ iter: bool = False,
583
+ start_time_from: Optional[datetime] = None,
584
+ start_time_to: Optional[datetime] = None,
585
+ last_update_time_from: Optional[datetime] = None,
586
+ last_update_time_to: Optional[datetime] = None,
587
+ partition_by: Optional[
588
+ Union[mlrun.common.schemas.RunPartitionByField, str]
589
+ ] = None,
564
590
  rows_per_partition: int = 1,
565
- partition_sort_by: Union[schemas.SortField, str] = None,
566
- partition_order: Union[schemas.OrderType, str] = schemas.OrderType.desc,
591
+ partition_sort_by: Optional[Union[mlrun.common.schemas.SortField, str]] = None,
592
+ partition_order: Union[
593
+ mlrun.common.schemas.OrderType, str
594
+ ] = mlrun.common.schemas.OrderType.desc,
567
595
  max_partitions: int = 0,
596
+ with_notifications: bool = False,
568
597
  ) -> RunList:
569
598
  """Retrieve a list of runs, filtered by various options.
570
599
  Example::
571
600
 
572
- runs = db.list_runs(name='download', project='iris', labels='owner=admin')
601
+ runs = db.list_runs(name='download', project='iris', labels=['owner=admin', 'kind=job'])
573
602
  # If running in Jupyter, can use the .show() function to display the results
574
603
  db.list_runs(name='', project=project_name).show()
575
604
 
@@ -577,8 +606,8 @@ class HTTPRunDB(RunDBInterface):
577
606
  :param name: Name of the run to retrieve.
578
607
  :param uid: Unique ID of the run, or a list of run UIDs.
579
608
  :param project: Project that the runs belongs to.
580
- :param labels: List runs that have a specific label assigned. Currently only a single label filter can be
581
- applied, otherwise result will be empty.
609
+ :param labels: List runs that have specific labels assigned. a single or multi label filter can be
610
+ applied.
582
611
  :param state: List only runs whose state is specified.
583
612
  :param sort: Whether to sort the result according to their start time. Otherwise, results will be
584
613
  returned by their internal order in the DB (order will not be guaranteed).
@@ -598,6 +627,7 @@ class HTTPRunDB(RunDBInterface):
598
627
  :param partition_order: Order of sorting within partitions - `asc` or `desc`. Default is `desc`.
599
628
  :param max_partitions: Maximal number of partitions to include in the result. Default is `0` which means no
600
629
  limit.
630
+ :param with_notifications: Return runs with notifications, and join them to the response. Default is `False`.
601
631
  """
602
632
 
603
633
  project = project or config.default_project
@@ -613,12 +643,13 @@ class HTTPRunDB(RunDBInterface):
613
643
  "start_time_to": datetime_to_iso(start_time_to),
614
644
  "last_update_time_from": datetime_to_iso(last_update_time_from),
615
645
  "last_update_time_to": datetime_to_iso(last_update_time_to),
646
+ "with-notifications": with_notifications,
616
647
  }
617
648
 
618
649
  if partition_by:
619
650
  params.update(
620
651
  self._generate_partition_by_params(
621
- schemas.RunPartitionByField,
652
+ mlrun.common.schemas.RunPartitionByField,
622
653
  partition_by,
623
654
  rows_per_partition,
624
655
  partition_sort_by,
@@ -687,7 +718,7 @@ class HTTPRunDB(RunDBInterface):
687
718
  endpoint_path = f"projects/{project}/artifacts/{key}?tag={tag}"
688
719
  error = f"read artifact {project}/{key}"
689
720
  # explicitly set artifacts format to 'full' since old servers may default to 'legacy'
690
- params = {"format": schemas.ArtifactsFormat.full.value}
721
+ params = {"format": mlrun.common.schemas.ArtifactsFormat.full.value}
691
722
  if iter:
692
723
  params["iter"] = str(iter)
693
724
  resp = self.api_call("GET", endpoint_path, error, params=params)
@@ -715,7 +746,7 @@ class HTTPRunDB(RunDBInterface):
715
746
  iter: int = None,
716
747
  best_iteration: bool = False,
717
748
  kind: str = None,
718
- category: Union[str, schemas.ArtifactCategories] = None,
749
+ category: Union[str, mlrun.common.schemas.ArtifactCategories] = None,
719
750
  ) -> ArtifactList:
720
751
  """List artifacts filtered by various parameters.
721
752
 
@@ -728,8 +759,9 @@ class HTTPRunDB(RunDBInterface):
728
759
  # Show artifacts with label filters - both uploaded and of binary type
729
760
  result_labels = db.list_artifacts('results', tag='*', project='iris', labels=['uploaded', 'type=binary'])
730
761
 
731
- :param name: Name of artifacts to retrieve. Name is used as a like query, and is not case-sensitive. This means
732
- that querying for ``name`` may return artifacts named ``my_Name_1`` or ``surname``.
762
+ :param name: Name of artifacts to retrieve. Name with '~' prefix is used as a like query, and is not
763
+ case-sensitive. This means that querying for ``~name`` may return artifacts named
764
+ ``my_Name_1`` or ``surname``.
733
765
  :param project: Project name.
734
766
  :param tag: Return artifacts assigned this tag.
735
767
  :param labels: Return artifacts that have these labels. Labels can either be a dictionary {"label": "value"} or
@@ -759,7 +791,7 @@ class HTTPRunDB(RunDBInterface):
759
791
  "best-iteration": best_iteration,
760
792
  "kind": kind,
761
793
  "category": category,
762
- "format": schemas.ArtifactsFormat.full.value,
794
+ "format": mlrun.common.schemas.ArtifactsFormat.full.value,
763
795
  }
764
796
  error = "list artifacts"
765
797
  endpoint_path = f"projects/{project}/artifacts"
@@ -792,7 +824,7 @@ class HTTPRunDB(RunDBInterface):
792
824
  def list_artifact_tags(
793
825
  self,
794
826
  project=None,
795
- category: Union[str, schemas.ArtifactCategories] = None,
827
+ category: Union[str, mlrun.common.schemas.ArtifactCategories] = None,
796
828
  ) -> List[str]:
797
829
  """Return a list of all the tags assigned to artifacts in the scope of the given project."""
798
830
 
@@ -820,7 +852,7 @@ class HTTPRunDB(RunDBInterface):
820
852
 
821
853
  params = {"tag": tag, "versioned": versioned}
822
854
  project = project or config.default_project
823
- path = self._path_of("func", project, name)
855
+ path = f"projects/{project}/functions/{name}"
824
856
 
825
857
  error = f"store function {project}/{name}"
826
858
  resp = self.api_call(
@@ -835,7 +867,7 @@ class HTTPRunDB(RunDBInterface):
835
867
 
836
868
  params = {"tag": tag, "hash_key": hash_key}
837
869
  project = project or config.default_project
838
- path = self._path_of("func", project, name)
870
+ path = f"projects/{project}/functions/{name}"
839
871
  error = f"get function {project}/{name}"
840
872
  resp = self.api_call("GET", path, error, params=params)
841
873
  return resp.json()["func"]
@@ -857,15 +889,15 @@ class HTTPRunDB(RunDBInterface):
857
889
  :param labels: Return functions that have specific labels assigned to them.
858
890
  :returns: List of function objects (as dictionary).
859
891
  """
860
-
892
+ project = project or config.default_project
861
893
  params = {
862
- "project": project or config.default_project,
863
894
  "name": name,
864
895
  "tag": tag,
865
896
  "label": labels or [],
866
897
  }
867
898
  error = "list functions"
868
- resp = self.api_call("GET", "funcs", error, params=params)
899
+ path = f"projects/{project}/functions"
900
+ resp = self.api_call("GET", path, error, params=params)
869
901
  return resp.json()["funcs"]
870
902
 
871
903
  def list_runtime_resources(
@@ -874,11 +906,13 @@ class HTTPRunDB(RunDBInterface):
874
906
  label_selector: Optional[str] = None,
875
907
  kind: Optional[str] = None,
876
908
  object_id: Optional[str] = None,
877
- group_by: Optional[mlrun.api.schemas.ListRuntimeResourcesGroupByField] = None,
909
+ group_by: Optional[
910
+ mlrun.common.schemas.ListRuntimeResourcesGroupByField
911
+ ] = None,
878
912
  ) -> Union[
879
- mlrun.api.schemas.RuntimeResourcesOutput,
880
- mlrun.api.schemas.GroupedByJobRuntimeResourcesOutput,
881
- mlrun.api.schemas.GroupedByProjectRuntimeResourcesOutput,
913
+ mlrun.common.schemas.RuntimeResourcesOutput,
914
+ mlrun.common.schemas.GroupedByJobRuntimeResourcesOutput,
915
+ mlrun.common.schemas.GroupedByProjectRuntimeResourcesOutput,
882
916
  ]:
883
917
  """List current runtime resources, which are usually (but not limited to) Kubernetes pods or CRDs.
884
918
  Function applies for runs of type `['dask', 'job', 'spark', 'remote-spark', 'mpijob']`, and will return per
@@ -907,25 +941,25 @@ class HTTPRunDB(RunDBInterface):
907
941
  )
908
942
  if group_by is None:
909
943
  structured_list = [
910
- mlrun.api.schemas.KindRuntimeResources(**kind_runtime_resources)
944
+ mlrun.common.schemas.KindRuntimeResources(**kind_runtime_resources)
911
945
  for kind_runtime_resources in response.json()
912
946
  ]
913
947
  return structured_list
914
- elif group_by == mlrun.api.schemas.ListRuntimeResourcesGroupByField.job:
948
+ elif group_by == mlrun.common.schemas.ListRuntimeResourcesGroupByField.job:
915
949
  structured_dict = {}
916
950
  for project, job_runtime_resources_map in response.json().items():
917
951
  for job_id, runtime_resources in job_runtime_resources_map.items():
918
952
  structured_dict.setdefault(project, {})[
919
953
  job_id
920
- ] = mlrun.api.schemas.RuntimeResources(**runtime_resources)
954
+ ] = mlrun.common.schemas.RuntimeResources(**runtime_resources)
921
955
  return structured_dict
922
- elif group_by == mlrun.api.schemas.ListRuntimeResourcesGroupByField.project:
956
+ elif group_by == mlrun.common.schemas.ListRuntimeResourcesGroupByField.project:
923
957
  structured_dict = {}
924
958
  for project, kind_runtime_resources_map in response.json().items():
925
959
  for kind, runtime_resources in kind_runtime_resources_map.items():
926
960
  structured_dict.setdefault(project, {})[
927
961
  kind
928
- ] = mlrun.api.schemas.RuntimeResources(**runtime_resources)
962
+ ] = mlrun.common.schemas.RuntimeResources(**runtime_resources)
929
963
  return structured_dict
930
964
  else:
931
965
  raise NotImplementedError(
@@ -940,7 +974,7 @@ class HTTPRunDB(RunDBInterface):
940
974
  object_id: Optional[str] = None,
941
975
  force: bool = False,
942
976
  grace_period: int = None,
943
- ) -> mlrun.api.schemas.GroupedByProjectRuntimeResourcesOutput:
977
+ ) -> mlrun.common.schemas.GroupedByProjectRuntimeResourcesOutput:
944
978
  """Delete all runtime resources which are in terminal state.
945
979
 
946
980
  :param project: Delete only runtime resources of a specific project, by default None, which will delete only
@@ -955,7 +989,7 @@ class HTTPRunDB(RunDBInterface):
955
989
  :param grace_period: Grace period given to the runtime resource before they are actually removed, counted from
956
990
  the moment they moved to terminal state (defaults to mlrun.mlconf.runtime_resources_deletion_grace_period).
957
991
 
958
- :returns: :py:class:`~mlrun.api.schemas.GroupedByProjectRuntimeResourcesOutput` listing the runtime resources
992
+ :returns: :py:class:`~mlrun.common.schemas.GroupedByProjectRuntimeResourcesOutput` listing the runtime resources
959
993
  that were removed.
960
994
  """
961
995
  if grace_period is None:
@@ -985,10 +1019,12 @@ class HTTPRunDB(RunDBInterface):
985
1019
  for kind, runtime_resources in kind_runtime_resources_map.items():
986
1020
  structured_dict.setdefault(project, {})[
987
1021
  kind
988
- ] = mlrun.api.schemas.RuntimeResources(**runtime_resources)
1022
+ ] = mlrun.common.schemas.RuntimeResources(**runtime_resources)
989
1023
  return structured_dict
990
1024
 
991
- def create_schedule(self, project: str, schedule: schemas.ScheduleInput):
1025
+ def create_schedule(
1026
+ self, project: str, schedule: mlrun.common.schemas.ScheduleInput
1027
+ ):
992
1028
  """Create a new schedule on the given project. The details on the actual object to schedule as well as the
993
1029
  schedule itself are within the schedule object provided.
994
1030
  The :py:class:`~ScheduleCronTrigger` follows the guidelines in
@@ -1000,7 +1036,7 @@ class HTTPRunDB(RunDBInterface):
1000
1036
 
1001
1037
  Example::
1002
1038
 
1003
- from mlrun.api import schemas
1039
+ from mlrun.common import schemas
1004
1040
 
1005
1041
  # Execute the get_data_func function every Tuesday at 15:30
1006
1042
  schedule = schemas.ScheduleInput(
@@ -1019,7 +1055,7 @@ class HTTPRunDB(RunDBInterface):
1019
1055
  self.api_call("POST", path, error_message, body=dict_to_json(schedule.dict()))
1020
1056
 
1021
1057
  def update_schedule(
1022
- self, project: str, name: str, schedule: schemas.ScheduleUpdate
1058
+ self, project: str, name: str, schedule: mlrun.common.schemas.ScheduleUpdate
1023
1059
  ):
1024
1060
  """Update an existing schedule, replace it with the details contained in the schedule object."""
1025
1061
 
@@ -1031,7 +1067,7 @@ class HTTPRunDB(RunDBInterface):
1031
1067
 
1032
1068
  def get_schedule(
1033
1069
  self, project: str, name: str, include_last_run: bool = False
1034
- ) -> schemas.ScheduleOutput:
1070
+ ) -> mlrun.common.schemas.ScheduleOutput:
1035
1071
  """Retrieve details of the schedule in question. Besides returning the details of the schedule object itself,
1036
1072
  this function also returns the next scheduled run for this specific schedule, as well as potentially the
1037
1073
  results of the last run executed through this schedule.
@@ -1047,15 +1083,15 @@ class HTTPRunDB(RunDBInterface):
1047
1083
  resp = self.api_call(
1048
1084
  "GET", path, error_message, params={"include_last_run": include_last_run}
1049
1085
  )
1050
- return schemas.ScheduleOutput(**resp.json())
1086
+ return mlrun.common.schemas.ScheduleOutput(**resp.json())
1051
1087
 
1052
1088
  def list_schedules(
1053
1089
  self,
1054
1090
  project: str,
1055
1091
  name: str = None,
1056
- kind: schemas.ScheduleKinds = None,
1092
+ kind: mlrun.common.schemas.ScheduleKinds = None,
1057
1093
  include_last_run: bool = False,
1058
- ) -> schemas.SchedulesOutput:
1094
+ ) -> mlrun.common.schemas.SchedulesOutput:
1059
1095
  """Retrieve list of schedules of specific name or kind.
1060
1096
 
1061
1097
  :param project: Project name.
@@ -1070,7 +1106,7 @@ class HTTPRunDB(RunDBInterface):
1070
1106
  path = f"projects/{project}/schedules"
1071
1107
  error_message = f"Failed listing schedules for {project} ? {kind} {name}"
1072
1108
  resp = self.api_call("GET", path, error_message, params=params)
1073
- return schemas.SchedulesOutput(**resp.json())
1109
+ return mlrun.common.schemas.SchedulesOutput(**resp.json())
1074
1110
 
1075
1111
  def delete_schedule(self, project: str, name: str):
1076
1112
  """Delete a specific schedule by name."""
@@ -1133,19 +1169,20 @@ class HTTPRunDB(RunDBInterface):
1133
1169
  def get_builder_status(
1134
1170
  self,
1135
1171
  func: BaseRuntime,
1136
- offset=0,
1137
- logs=True,
1138
- last_log_timestamp=0,
1139
- verbose=False,
1172
+ offset: int = 0,
1173
+ logs: bool = True,
1174
+ last_log_timestamp: float = 0.0,
1175
+ verbose: bool = False,
1140
1176
  ):
1141
1177
  """Retrieve the status of a build operation currently in progress.
1142
1178
 
1143
- :param func: Function object that is being built.
1144
- :param offset: Offset into the build logs to retrieve logs from.
1145
- :param logs: Should build logs be retrieved.
1146
- :param last_log_timestamp: Last timestamp of logs that were already retrieved. Function will return only logs
1147
- later than this parameter.
1148
- :param verbose: Add verbose logs into the output.
1179
+ :param func: Function object that is being built.
1180
+ :param offset: Offset into the build logs to retrieve logs from.
1181
+ :param logs: Should build logs be retrieved.
1182
+ :param last_log_timestamp: Last timestamp of logs that were already retrieved. Function will return only logs
1183
+ later than this parameter.
1184
+ :param verbose: Add verbose logs into the output.
1185
+
1149
1186
  :returns: The following parameters:
1150
1187
 
1151
1188
  - Text of builder logs.
@@ -1199,7 +1236,7 @@ class HTTPRunDB(RunDBInterface):
1199
1236
  text = resp.content.decode()
1200
1237
  return text, last_log_timestamp
1201
1238
 
1202
- def remote_start(self, func_url) -> schemas.BackgroundTask:
1239
+ def remote_start(self, func_url) -> mlrun.common.schemas.BackgroundTask:
1203
1240
  """Execute a function remotely, Used for ``dask`` functions.
1204
1241
 
1205
1242
  :param func_url: URL to the function to be executed.
@@ -1222,13 +1259,13 @@ class HTTPRunDB(RunDBInterface):
1222
1259
  logger.error(f"bad resp!!\n{resp.text}")
1223
1260
  raise ValueError("bad function start response")
1224
1261
 
1225
- return schemas.BackgroundTask(**resp.json())
1262
+ return mlrun.common.schemas.BackgroundTask(**resp.json())
1226
1263
 
1227
1264
  def get_project_background_task(
1228
1265
  self,
1229
1266
  project: str,
1230
1267
  name: str,
1231
- ) -> schemas.BackgroundTask:
1268
+ ) -> mlrun.common.schemas.BackgroundTask:
1232
1269
  """Retrieve updated information on a project background task being executed."""
1233
1270
 
1234
1271
  project = project or config.default_project
@@ -1237,15 +1274,15 @@ class HTTPRunDB(RunDBInterface):
1237
1274
  f"Failed getting project background task. project={project}, name={name}"
1238
1275
  )
1239
1276
  response = self.api_call("GET", path, error_message)
1240
- return schemas.BackgroundTask(**response.json())
1277
+ return mlrun.common.schemas.BackgroundTask(**response.json())
1241
1278
 
1242
- def get_background_task(self, name: str) -> schemas.BackgroundTask:
1279
+ def get_background_task(self, name: str) -> mlrun.common.schemas.BackgroundTask:
1243
1280
  """Retrieve updated information on a background task being executed."""
1244
1281
 
1245
1282
  path = f"background-tasks/{name}"
1246
1283
  error_message = f"Failed getting background task. name={name}"
1247
1284
  response = self.api_call("GET", path, error_message)
1248
- return schemas.BackgroundTask(**response.json())
1285
+ return mlrun.common.schemas.BackgroundTask(**response.json())
1249
1286
 
1250
1287
  def remote_status(self, project, name, kind, selector):
1251
1288
  """Retrieve status of a function being executed remotely (relevant to ``dask`` functions).
@@ -1270,7 +1307,9 @@ class HTTPRunDB(RunDBInterface):
1270
1307
  return resp.json()["data"]
1271
1308
 
1272
1309
  def submit_job(
1273
- self, runspec, schedule: Union[str, schemas.ScheduleCronTrigger] = None
1310
+ self,
1311
+ runspec,
1312
+ schedule: Union[str, mlrun.common.schemas.ScheduleCronTrigger] = None,
1274
1313
  ):
1275
1314
  """Submit a job for remote execution.
1276
1315
 
@@ -1282,7 +1321,7 @@ class HTTPRunDB(RunDBInterface):
1282
1321
  try:
1283
1322
  req = {"task": runspec.to_dict()}
1284
1323
  if schedule:
1285
- if isinstance(schedule, schemas.ScheduleCronTrigger):
1324
+ if isinstance(schedule, mlrun.common.schemas.ScheduleCronTrigger):
1286
1325
  schedule = schedule.dict()
1287
1326
  req["schedule"] = schedule
1288
1327
  timeout = (int(config.submit_timeout) or 120) + 20
@@ -1364,7 +1403,9 @@ class HTTPRunDB(RunDBInterface):
1364
1403
  if arguments:
1365
1404
  if not isinstance(arguments, dict):
1366
1405
  raise ValueError("arguments must be dict type")
1367
- headers[schemas.HeaderNames.pipeline_arguments] = str(arguments)
1406
+ headers[mlrun.common.schemas.HeaderNames.pipeline_arguments] = str(
1407
+ arguments
1408
+ )
1368
1409
 
1369
1410
  if not path.isfile(pipe_file):
1370
1411
  raise OSError(f"file {pipe_file} doesnt exist")
@@ -1403,10 +1444,10 @@ class HTTPRunDB(RunDBInterface):
1403
1444
  page_token: str = "",
1404
1445
  filter_: str = "",
1405
1446
  format_: Union[
1406
- str, mlrun.api.schemas.PipelinesFormat
1407
- ] = mlrun.api.schemas.PipelinesFormat.metadata_only,
1447
+ str, mlrun.common.schemas.PipelinesFormat
1448
+ ] = mlrun.common.schemas.PipelinesFormat.metadata_only,
1408
1449
  page_size: int = None,
1409
- ) -> mlrun.api.schemas.PipelinesOutput:
1450
+ ) -> mlrun.common.schemas.PipelinesOutput:
1410
1451
  """Retrieve a list of KFP pipelines. This function can be invoked to get all pipelines from all projects,
1411
1452
  by specifying ``project=*``, in which case pagination can be used and the various sorting and pagination
1412
1453
  properties can be applied. If a specific project is requested, then the pagination options cannot be
@@ -1425,9 +1466,9 @@ class HTTPRunDB(RunDBInterface):
1425
1466
  :param page_size: Size of a single page when applying pagination.
1426
1467
  """
1427
1468
 
1428
- if project != "*" and (page_token or page_size or sort_by):
1469
+ if project != "*" and (page_token or page_size):
1429
1470
  raise mlrun.errors.MLRunInvalidArgumentError(
1430
- "Filtering by project can not be used together with pagination, or sorting"
1471
+ "Filtering by project can not be used together with pagination"
1431
1472
  )
1432
1473
  params = {
1433
1474
  "namespace": namespace,
@@ -1442,7 +1483,7 @@ class HTTPRunDB(RunDBInterface):
1442
1483
  response = self.api_call(
1443
1484
  "GET", f"projects/{project}/pipelines", error_message, params=params
1444
1485
  )
1445
- return mlrun.api.schemas.PipelinesOutput(**response.json())
1486
+ return mlrun.common.schemas.PipelinesOutput(**response.json())
1446
1487
 
1447
1488
  def get_pipeline(
1448
1489
  self,
@@ -1450,27 +1491,23 @@ class HTTPRunDB(RunDBInterface):
1450
1491
  namespace: str = None,
1451
1492
  timeout: int = 10,
1452
1493
  format_: Union[
1453
- str, mlrun.api.schemas.PipelinesFormat
1454
- ] = mlrun.api.schemas.PipelinesFormat.summary,
1494
+ str, mlrun.common.schemas.PipelinesFormat
1495
+ ] = mlrun.common.schemas.PipelinesFormat.summary,
1455
1496
  project: str = None,
1456
1497
  ):
1457
1498
  """Retrieve details of a specific pipeline using its run ID (as provided when the pipeline was executed)."""
1458
1499
 
1459
- try:
1460
- params = {}
1461
- if namespace:
1462
- params["namespace"] = namespace
1463
- params["format"] = format_
1464
- project_path = project if project else "*"
1465
- resp = self.api_call(
1466
- "GET",
1467
- f"projects/{project_path}/pipelines/{run_id}",
1468
- params=params,
1469
- timeout=timeout,
1470
- )
1471
- except OSError as err:
1472
- logger.error(f"error cannot get pipeline: {err_to_str(err)}")
1473
- raise OSError(f"error: cannot get pipeline, {err_to_str(err)}")
1500
+ params = {}
1501
+ if namespace:
1502
+ params["namespace"] = namespace
1503
+ params["format"] = format_
1504
+ project_path = project if project else "*"
1505
+ resp = self.api_call(
1506
+ "GET",
1507
+ f"projects/{project_path}/pipelines/{run_id}",
1508
+ params=params,
1509
+ timeout=timeout,
1510
+ )
1474
1511
 
1475
1512
  if not resp.ok:
1476
1513
  logger.error(f"bad resp!!\n{resp.text}")
@@ -1486,7 +1523,7 @@ class HTTPRunDB(RunDBInterface):
1486
1523
 
1487
1524
  def create_feature_set(
1488
1525
  self,
1489
- feature_set: Union[dict, schemas.FeatureSet, FeatureSet],
1526
+ feature_set: Union[dict, mlrun.common.schemas.FeatureSet, FeatureSet],
1490
1527
  project="",
1491
1528
  versioned=True,
1492
1529
  ) -> dict:
@@ -1499,7 +1536,7 @@ class HTTPRunDB(RunDBInterface):
1499
1536
  will be kept in the DB and can be retrieved until explicitly deleted.
1500
1537
  :returns: The :py:class:`~mlrun.feature_store.FeatureSet` object (as dict).
1501
1538
  """
1502
- if isinstance(feature_set, schemas.FeatureSet):
1539
+ if isinstance(feature_set, mlrun.common.schemas.FeatureSet):
1503
1540
  feature_set = feature_set.dict()
1504
1541
  elif isinstance(feature_set, FeatureSet):
1505
1542
  feature_set = feature_set.to_dict()
@@ -1633,10 +1670,14 @@ class HTTPRunDB(RunDBInterface):
1633
1670
  entities: List[str] = None,
1634
1671
  features: List[str] = None,
1635
1672
  labels: List[str] = None,
1636
- partition_by: Union[schemas.FeatureStorePartitionByField, str] = None,
1673
+ partition_by: Union[
1674
+ mlrun.common.schemas.FeatureStorePartitionByField, str
1675
+ ] = None,
1637
1676
  rows_per_partition: int = 1,
1638
- partition_sort_by: Union[schemas.SortField, str] = None,
1639
- partition_order: Union[schemas.OrderType, str] = schemas.OrderType.desc,
1677
+ partition_sort_by: Union[mlrun.common.schemas.SortField, str] = None,
1678
+ partition_order: Union[
1679
+ mlrun.common.schemas.OrderType, str
1680
+ ] = mlrun.common.schemas.OrderType.desc,
1640
1681
  ) -> List[FeatureSet]:
1641
1682
  """Retrieve a list of feature-sets matching the criteria provided.
1642
1683
 
@@ -1670,7 +1711,7 @@ class HTTPRunDB(RunDBInterface):
1670
1711
  if partition_by:
1671
1712
  params.update(
1672
1713
  self._generate_partition_by_params(
1673
- schemas.FeatureStorePartitionByField,
1714
+ mlrun.common.schemas.FeatureStorePartitionByField,
1674
1715
  partition_by,
1675
1716
  rows_per_partition,
1676
1717
  partition_sort_by,
@@ -1690,7 +1731,7 @@ class HTTPRunDB(RunDBInterface):
1690
1731
 
1691
1732
  def store_feature_set(
1692
1733
  self,
1693
- feature_set: Union[dict, schemas.FeatureSet, FeatureSet],
1734
+ feature_set: Union[dict, mlrun.common.schemas.FeatureSet, FeatureSet],
1694
1735
  name=None,
1695
1736
  project="",
1696
1737
  tag=None,
@@ -1715,7 +1756,7 @@ class HTTPRunDB(RunDBInterface):
1715
1756
  reference = self._resolve_reference(tag, uid)
1716
1757
  params = {"versioned": versioned}
1717
1758
 
1718
- if isinstance(feature_set, schemas.FeatureSet):
1759
+ if isinstance(feature_set, mlrun.common.schemas.FeatureSet):
1719
1760
  feature_set = feature_set.dict()
1720
1761
  elif isinstance(feature_set, FeatureSet):
1721
1762
  feature_set = feature_set.to_dict()
@@ -1738,7 +1779,9 @@ class HTTPRunDB(RunDBInterface):
1738
1779
  project="",
1739
1780
  tag=None,
1740
1781
  uid=None,
1741
- patch_mode: Union[str, schemas.PatchMode] = schemas.PatchMode.replace,
1782
+ patch_mode: Union[
1783
+ str, mlrun.common.schemas.PatchMode
1784
+ ] = mlrun.common.schemas.PatchMode.replace,
1742
1785
  ):
1743
1786
  """Modify (patch) an existing :py:class:`~mlrun.feature_store.FeatureSet` object.
1744
1787
  The object is identified by its name (and project it belongs to), as well as optionally a ``tag`` or its
@@ -1761,7 +1804,7 @@ class HTTPRunDB(RunDBInterface):
1761
1804
  """
1762
1805
  project = project or config.default_project
1763
1806
  reference = self._resolve_reference(tag, uid)
1764
- headers = {schemas.HeaderNames.patch_mode: patch_mode}
1807
+ headers = {mlrun.common.schemas.HeaderNames.patch_mode: patch_mode}
1765
1808
  path = f"projects/{project}/feature-sets/{name}/references/{reference}"
1766
1809
  error_message = f"Failed updating feature-set {project}/{name}"
1767
1810
  self.api_call(
@@ -1790,7 +1833,7 @@ class HTTPRunDB(RunDBInterface):
1790
1833
 
1791
1834
  def create_feature_vector(
1792
1835
  self,
1793
- feature_vector: Union[dict, schemas.FeatureVector, FeatureVector],
1836
+ feature_vector: Union[dict, mlrun.common.schemas.FeatureVector, FeatureVector],
1794
1837
  project="",
1795
1838
  versioned=True,
1796
1839
  ) -> dict:
@@ -1802,7 +1845,7 @@ class HTTPRunDB(RunDBInterface):
1802
1845
  will be kept in the DB and can be retrieved until explicitly deleted.
1803
1846
  :returns: The :py:class:`~mlrun.feature_store.FeatureVector` object (as dict).
1804
1847
  """
1805
- if isinstance(feature_vector, schemas.FeatureVector):
1848
+ if isinstance(feature_vector, mlrun.common.schemas.FeatureVector):
1806
1849
  feature_vector = feature_vector.dict()
1807
1850
  elif isinstance(feature_vector, FeatureVector):
1808
1851
  feature_vector = feature_vector.to_dict()
@@ -1846,10 +1889,14 @@ class HTTPRunDB(RunDBInterface):
1846
1889
  tag: str = None,
1847
1890
  state: str = None,
1848
1891
  labels: List[str] = None,
1849
- partition_by: Union[schemas.FeatureStorePartitionByField, str] = None,
1892
+ partition_by: Union[
1893
+ mlrun.common.schemas.FeatureStorePartitionByField, str
1894
+ ] = None,
1850
1895
  rows_per_partition: int = 1,
1851
- partition_sort_by: Union[schemas.SortField, str] = None,
1852
- partition_order: Union[schemas.OrderType, str] = schemas.OrderType.desc,
1896
+ partition_sort_by: Union[mlrun.common.schemas.SortField, str] = None,
1897
+ partition_order: Union[
1898
+ mlrun.common.schemas.OrderType, str
1899
+ ] = mlrun.common.schemas.OrderType.desc,
1853
1900
  ) -> List[FeatureVector]:
1854
1901
  """Retrieve a list of feature-vectors matching the criteria provided.
1855
1902
 
@@ -1879,7 +1926,7 @@ class HTTPRunDB(RunDBInterface):
1879
1926
  if partition_by:
1880
1927
  params.update(
1881
1928
  self._generate_partition_by_params(
1882
- schemas.FeatureStorePartitionByField,
1929
+ mlrun.common.schemas.FeatureStorePartitionByField,
1883
1930
  partition_by,
1884
1931
  rows_per_partition,
1885
1932
  partition_sort_by,
@@ -1899,7 +1946,7 @@ class HTTPRunDB(RunDBInterface):
1899
1946
 
1900
1947
  def store_feature_vector(
1901
1948
  self,
1902
- feature_vector: Union[dict, schemas.FeatureVector, FeatureVector],
1949
+ feature_vector: Union[dict, mlrun.common.schemas.FeatureVector, FeatureVector],
1903
1950
  name=None,
1904
1951
  project="",
1905
1952
  tag=None,
@@ -1924,7 +1971,7 @@ class HTTPRunDB(RunDBInterface):
1924
1971
  reference = self._resolve_reference(tag, uid)
1925
1972
  params = {"versioned": versioned}
1926
1973
 
1927
- if isinstance(feature_vector, schemas.FeatureVector):
1974
+ if isinstance(feature_vector, mlrun.common.schemas.FeatureVector):
1928
1975
  feature_vector = feature_vector.dict()
1929
1976
  elif isinstance(feature_vector, FeatureVector):
1930
1977
  feature_vector = feature_vector.to_dict()
@@ -1949,7 +1996,9 @@ class HTTPRunDB(RunDBInterface):
1949
1996
  project="",
1950
1997
  tag=None,
1951
1998
  uid=None,
1952
- patch_mode: Union[str, schemas.PatchMode] = schemas.PatchMode.replace,
1999
+ patch_mode: Union[
2000
+ str, mlrun.common.schemas.PatchMode
2001
+ ] = mlrun.common.schemas.PatchMode.replace,
1953
2002
  ):
1954
2003
  """Modify (patch) an existing :py:class:`~mlrun.feature_store.FeatureVector` object.
1955
2004
  The object is identified by its name (and project it belongs to), as well as optionally a ``tag`` or its
@@ -1967,7 +2016,7 @@ class HTTPRunDB(RunDBInterface):
1967
2016
  """
1968
2017
  reference = self._resolve_reference(tag, uid)
1969
2018
  project = project or config.default_project
1970
- headers = {schemas.HeaderNames.patch_mode: patch_mode}
2019
+ headers = {mlrun.common.schemas.HeaderNames.patch_mode: patch_mode}
1971
2020
  path = f"projects/{project}/feature-vectors/{name}/references/{reference}"
1972
2021
  error_message = f"Failed updating feature-vector {project}/{name}"
1973
2022
  self.api_call(
@@ -1997,7 +2046,7 @@ class HTTPRunDB(RunDBInterface):
1997
2046
  self,
1998
2047
  project: str,
1999
2048
  tag_name: str,
2000
- objects: Union[mlrun.api.schemas.TagObjects, dict],
2049
+ objects: Union[mlrun.common.schemas.TagObjects, dict],
2001
2050
  replace: bool = False,
2002
2051
  ):
2003
2052
  """Tag a list of objects.
@@ -2017,7 +2066,7 @@ class HTTPRunDB(RunDBInterface):
2017
2066
  error_message,
2018
2067
  body=dict_to_json(
2019
2068
  objects.dict()
2020
- if isinstance(objects, mlrun.api.schemas.TagObjects)
2069
+ if isinstance(objects, mlrun.common.schemas.TagObjects)
2021
2070
  else objects
2022
2071
  ),
2023
2072
  )
@@ -2026,7 +2075,7 @@ class HTTPRunDB(RunDBInterface):
2026
2075
  self,
2027
2076
  project: str,
2028
2077
  tag_name: str,
2029
- tag_objects: Union[mlrun.api.schemas.TagObjects, dict],
2078
+ tag_objects: Union[mlrun.common.schemas.TagObjects, dict],
2030
2079
  ):
2031
2080
  """Delete a tag from a list of objects.
2032
2081
 
@@ -2043,7 +2092,7 @@ class HTTPRunDB(RunDBInterface):
2043
2092
  error_message,
2044
2093
  body=dict_to_json(
2045
2094
  tag_objects.dict()
2046
- if isinstance(tag_objects, mlrun.api.schemas.TagObjects)
2095
+ if isinstance(tag_objects, mlrun.common.schemas.TagObjects)
2047
2096
  else tag_objects
2048
2097
  ),
2049
2098
  )
@@ -2086,10 +2135,10 @@ class HTTPRunDB(RunDBInterface):
2086
2135
  self,
2087
2136
  owner: str = None,
2088
2137
  format_: Union[
2089
- str, mlrun.api.schemas.ProjectsFormat
2090
- ] = mlrun.api.schemas.ProjectsFormat.full,
2138
+ str, mlrun.common.schemas.ProjectsFormat
2139
+ ] = mlrun.common.schemas.ProjectsFormat.full,
2091
2140
  labels: List[str] = None,
2092
- state: Union[str, mlrun.api.schemas.ProjectState] = None,
2141
+ state: Union[str, mlrun.common.schemas.ProjectState] = None,
2093
2142
  ) -> List[Union[mlrun.projects.MlrunProject, str]]:
2094
2143
  """Return a list of the existing projects, potentially filtered by specific criteria.
2095
2144
 
@@ -2113,20 +2162,17 @@ class HTTPRunDB(RunDBInterface):
2113
2162
 
2114
2163
  error_message = f"Failed listing projects, query: {params}"
2115
2164
  response = self.api_call("GET", "projects", error_message, params=params)
2116
- if format_ == mlrun.api.schemas.ProjectsFormat.name_only:
2165
+ if format_ == mlrun.common.schemas.ProjectsFormat.name_only:
2166
+
2167
+ # projects is just a list of strings
2117
2168
  return response.json()["projects"]
2118
- elif format_ in [
2119
- mlrun.api.schemas.ProjectsFormat.full,
2120
- mlrun.api.schemas.ProjectsFormat.minimal,
2121
- ]:
2122
- return [
2123
- mlrun.projects.MlrunProject.from_dict(project_dict)
2124
- for project_dict in response.json()["projects"]
2125
- ]
2126
- else:
2127
- raise NotImplementedError(
2128
- f"Provided format is not supported. format={format_}"
2129
- )
2169
+
2170
+ # forwards compatibility - we want to be able to handle new formats that might be added in the future
2171
+ # if format is not known to the api, it is up to the server to return either an error or a default format
2172
+ return [
2173
+ mlrun.projects.MlrunProject.from_dict(project_dict)
2174
+ for project_dict in response.json()["projects"]
2175
+ ]
2130
2176
 
2131
2177
  def get_project(self, name: str) -> mlrun.projects.MlrunProject:
2132
2178
  """Get details for a specific project."""
@@ -2143,8 +2189,8 @@ class HTTPRunDB(RunDBInterface):
2143
2189
  self,
2144
2190
  name: str,
2145
2191
  deletion_strategy: Union[
2146
- str, mlrun.api.schemas.DeletionStrategy
2147
- ] = mlrun.api.schemas.DeletionStrategy.default(),
2192
+ str, mlrun.common.schemas.DeletionStrategy
2193
+ ] = mlrun.common.schemas.DeletionStrategy.default(),
2148
2194
  ):
2149
2195
  """Delete a project.
2150
2196
 
@@ -2157,7 +2203,9 @@ class HTTPRunDB(RunDBInterface):
2157
2203
  """
2158
2204
 
2159
2205
  path = f"projects/{name}"
2160
- headers = {schemas.HeaderNames.deletion_strategy: deletion_strategy}
2206
+ headers = {
2207
+ mlrun.common.schemas.HeaderNames.deletion_strategy: deletion_strategy
2208
+ }
2161
2209
  error_message = f"Failed deleting project {name}"
2162
2210
  response = self.api_call("DELETE", path, error_message, headers=headers)
2163
2211
  if response.status_code == http.HTTPStatus.ACCEPTED:
@@ -2166,13 +2214,13 @@ class HTTPRunDB(RunDBInterface):
2166
2214
  def store_project(
2167
2215
  self,
2168
2216
  name: str,
2169
- project: Union[dict, mlrun.projects.MlrunProject, mlrun.api.schemas.Project],
2217
+ project: Union[dict, mlrun.projects.MlrunProject, mlrun.common.schemas.Project],
2170
2218
  ) -> mlrun.projects.MlrunProject:
2171
2219
  """Store a project in the DB. This operation will overwrite existing project of the same name if exists."""
2172
2220
 
2173
2221
  path = f"projects/{name}"
2174
2222
  error_message = f"Failed storing project {name}"
2175
- if isinstance(project, mlrun.api.schemas.Project):
2223
+ if isinstance(project, mlrun.common.schemas.Project):
2176
2224
  project = project.dict()
2177
2225
  elif isinstance(project, mlrun.projects.MlrunProject):
2178
2226
  project = project.to_dict()
@@ -2190,7 +2238,9 @@ class HTTPRunDB(RunDBInterface):
2190
2238
  self,
2191
2239
  name: str,
2192
2240
  project: dict,
2193
- patch_mode: Union[str, schemas.PatchMode] = schemas.PatchMode.replace,
2241
+ patch_mode: Union[
2242
+ str, mlrun.common.schemas.PatchMode
2243
+ ] = mlrun.common.schemas.PatchMode.replace,
2194
2244
  ) -> mlrun.projects.MlrunProject:
2195
2245
  """Patch an existing project object.
2196
2246
 
@@ -2201,7 +2251,7 @@ class HTTPRunDB(RunDBInterface):
2201
2251
  """
2202
2252
 
2203
2253
  path = f"projects/{name}"
2204
- headers = {schemas.HeaderNames.patch_mode: patch_mode}
2254
+ headers = {mlrun.common.schemas.HeaderNames.patch_mode: patch_mode}
2205
2255
  error_message = f"Failed patching project {name}"
2206
2256
  response = self.api_call(
2207
2257
  "PATCH", path, error_message, body=dict_to_json(project), headers=headers
@@ -2210,11 +2260,11 @@ class HTTPRunDB(RunDBInterface):
2210
2260
 
2211
2261
  def create_project(
2212
2262
  self,
2213
- project: Union[dict, mlrun.projects.MlrunProject, mlrun.api.schemas.Project],
2263
+ project: Union[dict, mlrun.projects.MlrunProject, mlrun.common.schemas.Project],
2214
2264
  ) -> mlrun.projects.MlrunProject:
2215
2265
  """Create a new project. A project with the same name must not exist prior to creation."""
2216
2266
 
2217
- if isinstance(project, mlrun.api.schemas.Project):
2267
+ if isinstance(project, mlrun.common.schemas.Project):
2218
2268
  project = project.dict()
2219
2269
  elif isinstance(project, mlrun.projects.MlrunProject):
2220
2270
  project = project.to_dict()
@@ -2237,7 +2287,7 @@ class HTTPRunDB(RunDBInterface):
2237
2287
  project = self.get_project(project_name)
2238
2288
  if (
2239
2289
  project.status.state
2240
- not in mlrun.api.schemas.ProjectState.terminal_states()
2290
+ not in mlrun.common.schemas.ProjectState.terminal_states()
2241
2291
  ):
2242
2292
  raise Exception(
2243
2293
  f"Project not in terminal state. State: {project.status.state}"
@@ -2254,11 +2304,11 @@ class HTTPRunDB(RunDBInterface):
2254
2304
 
2255
2305
  def _wait_for_background_task_to_reach_terminal_state(
2256
2306
  self, name: str
2257
- ) -> schemas.BackgroundTask:
2307
+ ) -> mlrun.common.schemas.BackgroundTask:
2258
2308
  def _verify_background_task_in_terminal_state():
2259
2309
  background_task = self.get_background_task(name)
2260
2310
  state = background_task.status.state
2261
- if state not in mlrun.api.schemas.BackgroundTaskState.terminal_states():
2311
+ if state not in mlrun.common.schemas.BackgroundTaskState.terminal_states():
2262
2312
  raise Exception(
2263
2313
  f"Background task not in terminal state. name={name}, state={state}"
2264
2314
  )
@@ -2275,10 +2325,10 @@ class HTTPRunDB(RunDBInterface):
2275
2325
  def _wait_for_project_to_be_deleted(self, project_name: str):
2276
2326
  def _verify_project_deleted():
2277
2327
  projects = self.list_projects(
2278
- format_=mlrun.api.schemas.ProjectsFormat.name_only
2328
+ format_=mlrun.common.schemas.ProjectsFormat.name_only
2279
2329
  )
2280
2330
  if project_name in projects:
2281
- raise Exception("Project still exists")
2331
+ raise Exception(f"Project {project_name} still exists")
2282
2332
 
2283
2333
  return mlrun.utils.helpers.retry_until_successful(
2284
2334
  self._wait_for_project_deletion_interval,
@@ -2292,8 +2342,8 @@ class HTTPRunDB(RunDBInterface):
2292
2342
  self,
2293
2343
  project: str,
2294
2344
  provider: Union[
2295
- str, schemas.SecretProviderName
2296
- ] = schemas.SecretProviderName.kubernetes,
2345
+ str, mlrun.common.schemas.SecretProviderName
2346
+ ] = mlrun.common.schemas.SecretProviderName.kubernetes,
2297
2347
  secrets: dict = None,
2298
2348
  ):
2299
2349
  """Create project-context secrets using either ``vault`` or ``kubernetes`` provider.
@@ -2311,19 +2361,21 @@ class HTTPRunDB(RunDBInterface):
2311
2361
 
2312
2362
  :param project: The project context for which to generate the infra and store secrets.
2313
2363
  :param provider: The name of the secrets-provider to work with. Accepts a
2314
- :py:class:`~mlrun.api.schemas.secret.SecretProviderName` enum.
2364
+ :py:class:`~mlrun.common.schemas.secret.SecretProviderName` enum.
2315
2365
  :param secrets: A set of secret values to store.
2316
2366
  Example::
2317
2367
 
2318
2368
  secrets = {'password': 'myPassw0rd', 'aws_key': '111222333'}
2319
2369
  db.create_project_secrets(
2320
2370
  "project1",
2321
- provider=mlrun.api.schemas.SecretProviderName.kubernetes,
2371
+ provider=mlrun.common.schemas.SecretProviderName.kubernetes,
2322
2372
  secrets=secrets
2323
2373
  )
2324
2374
  """
2325
2375
  path = f"projects/{project}/secrets"
2326
- secrets_input = schemas.SecretsData(secrets=secrets, provider=provider)
2376
+ secrets_input = mlrun.common.schemas.SecretsData(
2377
+ secrets=secrets, provider=provider
2378
+ )
2327
2379
  body = secrets_input.dict()
2328
2380
  error_message = f"Failed creating secret provider {project}/{provider}"
2329
2381
  self.api_call(
@@ -2338,10 +2390,10 @@ class HTTPRunDB(RunDBInterface):
2338
2390
  project: str,
2339
2391
  token: str = None,
2340
2392
  provider: Union[
2341
- str, schemas.SecretProviderName
2342
- ] = schemas.SecretProviderName.kubernetes,
2393
+ str, mlrun.common.schemas.SecretProviderName
2394
+ ] = mlrun.common.schemas.SecretProviderName.kubernetes,
2343
2395
  secrets: List[str] = None,
2344
- ) -> schemas.SecretsData:
2396
+ ) -> mlrun.common.schemas.SecretsData:
2345
2397
  """Retrieve project-context secrets from Vault.
2346
2398
 
2347
2399
  Note:
@@ -2356,14 +2408,17 @@ class HTTPRunDB(RunDBInterface):
2356
2408
  to this specific project. ``kubernetes`` provider only supports an empty list.
2357
2409
  """
2358
2410
 
2359
- if provider == schemas.SecretProviderName.vault.value and not token:
2411
+ if (
2412
+ provider == mlrun.common.schemas.SecretProviderName.vault.value
2413
+ and not token
2414
+ ):
2360
2415
  raise MLRunInvalidArgumentError(
2361
2416
  "A vault token must be provided when accessing vault secrets"
2362
2417
  )
2363
2418
 
2364
2419
  path = f"projects/{project}/secrets"
2365
2420
  params = {"provider": provider, "secret": secrets}
2366
- headers = {schemas.HeaderNames.secret_store_token: token}
2421
+ headers = {mlrun.common.schemas.HeaderNames.secret_store_token: token}
2367
2422
  error_message = f"Failed retrieving secrets {project}/{provider}"
2368
2423
  result = self.api_call(
2369
2424
  "GET",
@@ -2372,16 +2427,16 @@ class HTTPRunDB(RunDBInterface):
2372
2427
  params=params,
2373
2428
  headers=headers,
2374
2429
  )
2375
- return schemas.SecretsData(**result.json())
2430
+ return mlrun.common.schemas.SecretsData(**result.json())
2376
2431
 
2377
2432
  def list_project_secret_keys(
2378
2433
  self,
2379
2434
  project: str,
2380
2435
  provider: Union[
2381
- str, schemas.SecretProviderName
2382
- ] = schemas.SecretProviderName.kubernetes,
2436
+ str, mlrun.common.schemas.SecretProviderName
2437
+ ] = mlrun.common.schemas.SecretProviderName.kubernetes,
2383
2438
  token: str = None,
2384
- ) -> schemas.SecretKeysData:
2439
+ ) -> mlrun.common.schemas.SecretKeysData:
2385
2440
  """Retrieve project-context secret keys from Vault or Kubernetes.
2386
2441
 
2387
2442
  Note:
@@ -2390,12 +2445,15 @@ class HTTPRunDB(RunDBInterface):
2390
2445
 
2391
2446
  :param project: The project name.
2392
2447
  :param provider: The name of the secrets-provider to work with. Accepts a
2393
- :py:class:`~mlrun.api.schemas.secret.SecretProviderName` enum.
2448
+ :py:class:`~mlrun.common.schemas.secret.SecretProviderName` enum.
2394
2449
  :param token: Vault token to use for retrieving secrets. Only in use if ``provider`` is ``vault``.
2395
2450
  Must be a valid Vault token, with permissions to retrieve secrets of the project in question.
2396
2451
  """
2397
2452
 
2398
- if provider == schemas.SecretProviderName.vault.value and not token:
2453
+ if (
2454
+ provider == mlrun.common.schemas.SecretProviderName.vault.value
2455
+ and not token
2456
+ ):
2399
2457
  raise MLRunInvalidArgumentError(
2400
2458
  "A vault token must be provided when accessing vault secrets"
2401
2459
  )
@@ -2403,8 +2461,8 @@ class HTTPRunDB(RunDBInterface):
2403
2461
  path = f"projects/{project}/secret-keys"
2404
2462
  params = {"provider": provider}
2405
2463
  headers = (
2406
- {schemas.HeaderNames.secret_store_token: token}
2407
- if provider == schemas.SecretProviderName.vault.value
2464
+ {mlrun.common.schemas.HeaderNames.secret_store_token: token}
2465
+ if provider == mlrun.common.schemas.SecretProviderName.vault.value
2408
2466
  else None
2409
2467
  )
2410
2468
  error_message = f"Failed retrieving secret keys {project}/{provider}"
@@ -2415,14 +2473,14 @@ class HTTPRunDB(RunDBInterface):
2415
2473
  params=params,
2416
2474
  headers=headers,
2417
2475
  )
2418
- return schemas.SecretKeysData(**result.json())
2476
+ return mlrun.common.schemas.SecretKeysData(**result.json())
2419
2477
 
2420
2478
  def delete_project_secrets(
2421
2479
  self,
2422
2480
  project: str,
2423
2481
  provider: Union[
2424
- str, schemas.SecretProviderName
2425
- ] = schemas.SecretProviderName.kubernetes,
2482
+ str, mlrun.common.schemas.SecretProviderName
2483
+ ] = mlrun.common.schemas.SecretProviderName.kubernetes,
2426
2484
  secrets: List[str] = None,
2427
2485
  ):
2428
2486
  """Delete project-context secrets from Kubernetes.
@@ -2447,8 +2505,8 @@ class HTTPRunDB(RunDBInterface):
2447
2505
  self,
2448
2506
  user: str,
2449
2507
  provider: Union[
2450
- str, schemas.SecretProviderName
2451
- ] = schemas.SecretProviderName.vault,
2508
+ str, mlrun.common.schemas.SecretProviderName
2509
+ ] = mlrun.common.schemas.SecretProviderName.vault,
2452
2510
  secrets: dict = None,
2453
2511
  ):
2454
2512
  """Create user-context secret in Vault. Please refer to :py:func:`create_project_secrets` for more details
@@ -2463,7 +2521,7 @@ class HTTPRunDB(RunDBInterface):
2463
2521
  :param secrets: A set of secret values to store within the Vault.
2464
2522
  """
2465
2523
  path = "user-secrets"
2466
- secrets_creation_request = schemas.UserSecretCreationRequest(
2524
+ secrets_creation_request = mlrun.common.schemas.UserSecretCreationRequest(
2467
2525
  user=user,
2468
2526
  provider=provider,
2469
2527
  secrets=secrets,
@@ -2533,7 +2591,9 @@ class HTTPRunDB(RunDBInterface):
2533
2591
  self,
2534
2592
  project: str,
2535
2593
  endpoint_id: str,
2536
- model_endpoint: ModelEndpoint,
2594
+ model_endpoint: Union[
2595
+ mlrun.model_monitoring.model_endpoint.ModelEndpoint, dict
2596
+ ],
2537
2597
  ):
2538
2598
  """
2539
2599
  Creates a DB record with the given model_endpoint record.
@@ -2543,11 +2603,16 @@ class HTTPRunDB(RunDBInterface):
2543
2603
  :param model_endpoint: An object representing the model endpoint.
2544
2604
  """
2545
2605
 
2606
+ if isinstance(
2607
+ model_endpoint, mlrun.model_monitoring.model_endpoint.ModelEndpoint
2608
+ ):
2609
+ model_endpoint = model_endpoint.to_dict()
2610
+
2546
2611
  path = f"projects/{project}/model-endpoints/{endpoint_id}"
2547
2612
  self.api_call(
2548
2613
  method="POST",
2549
2614
  path=path,
2550
- body=model_endpoint.json(),
2615
+ body=dict_to_json(model_endpoint),
2551
2616
  )
2552
2617
 
2553
2618
  def delete_model_endpoint(
@@ -2556,7 +2621,7 @@ class HTTPRunDB(RunDBInterface):
2556
2621
  endpoint_id: str,
2557
2622
  ):
2558
2623
  """
2559
- Deletes the KV record of a given model endpoint, project and endpoint_id are used for lookup
2624
+ Deletes the DB record of a given model endpoint, project and endpoint_id are used for lookup
2560
2625
 
2561
2626
  :param project: The name of the project
2562
2627
  :param endpoint_id: The id of the endpoint
@@ -2579,13 +2644,15 @@ class HTTPRunDB(RunDBInterface):
2579
2644
  metrics: Optional[List[str]] = None,
2580
2645
  top_level: bool = False,
2581
2646
  uids: Optional[List[str]] = None,
2582
- ) -> schemas.ModelEndpointList:
2647
+ ) -> List[mlrun.model_monitoring.model_endpoint.ModelEndpoint]:
2583
2648
  """
2584
- Returns a list of ModelEndpointState objects. Each object represents the current state of a model endpoint.
2585
- This functions supports filtering by the following parameters:
2649
+ Returns a list of `ModelEndpoint` objects. Each `ModelEndpoint` object represents the current state of a
2650
+ model endpoint. This functions supports filtering by the following parameters:
2586
2651
  1) model
2587
2652
  2) function
2588
2653
  3) labels
2654
+ 4) top level
2655
+ 5) uids
2589
2656
  By default, when no filters are applied, all available endpoints for the given project will be listed.
2590
2657
 
2591
2658
  In addition, this functions provides a facade for listing endpoint related metrics. This facade is time-based
@@ -2595,8 +2662,8 @@ class HTTPRunDB(RunDBInterface):
2595
2662
  :param project: The name of the project
2596
2663
  :param model: The name of the model to filter by
2597
2664
  :param function: The name of the function to filter by
2598
- :param labels: A list of labels to filter by. Label filters work by either filtering a specific value of a label
2599
- (i.e. list("key==value")) or by looking for the existence of a given key (i.e. "key")
2665
+ :param labels: A list of labels to filter by. Label filters work by either filtering a specific value of a
2666
+ label (i.e. list("key=value")) or by looking for the existence of a given key (i.e. "key")
2600
2667
  :param metrics: A list of metrics to return for each endpoint, read more in 'TimeMetric'
2601
2668
  :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
2602
2669
  time, a Unix timestamp in milliseconds, a relative time (`'now'` or
@@ -2607,10 +2674,14 @@ class HTTPRunDB(RunDBInterface):
2607
2674
  `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` =
2608
2675
  days), or 0 for the earliest time.
2609
2676
  :param top_level: if true will return only routers and endpoint that are NOT children of any router
2610
- :param uids: if passed will return ModelEndpointList of endpoints with uid in uids
2677
+ :param uids: if passed will return a list `ModelEndpoint` object with uid in uids
2611
2678
  """
2612
2679
 
2613
2680
  path = f"projects/{project}/model-endpoints"
2681
+
2682
+ if labels and isinstance(labels, dict):
2683
+ labels = [f"{key}={value}" for key, value in labels.items()]
2684
+
2614
2685
  response = self.api_call(
2615
2686
  method="GET",
2616
2687
  path=path,
@@ -2625,7 +2696,15 @@ class HTTPRunDB(RunDBInterface):
2625
2696
  "uid": uids,
2626
2697
  },
2627
2698
  )
2628
- return schemas.ModelEndpointList(**response.json())
2699
+
2700
+ # Generate a list of a model endpoint dictionaries
2701
+ model_endpoints = response.json()["endpoints"]
2702
+ if model_endpoints:
2703
+ return [
2704
+ mlrun.model_monitoring.model_endpoint.ModelEndpoint.from_dict(obj)
2705
+ for obj in model_endpoints
2706
+ ]
2707
+ return []
2629
2708
 
2630
2709
  def get_model_endpoint(
2631
2710
  self,
@@ -2635,21 +2714,29 @@ class HTTPRunDB(RunDBInterface):
2635
2714
  end: Optional[str] = None,
2636
2715
  metrics: Optional[List[str]] = None,
2637
2716
  feature_analysis: bool = False,
2638
- ) -> schemas.ModelEndpoint:
2639
- """
2640
- Returns a ModelEndpoint object with additional metrics and feature related data.
2641
-
2642
- :param project: The name of the project
2643
- :param endpoint_id: The id of the model endpoint
2644
- :param metrics: A list of metrics to return for each endpoint, read more in 'TimeMetric'
2645
- :param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
2646
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`,
2647
- where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the earliest time.
2648
- :param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
2649
- time, a Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`,
2650
- where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the earliest time.
2651
- :param feature_analysis: When True, the base feature statistics and current feature statistics will be added to
2652
- the output of the resulting object
2717
+ ) -> mlrun.model_monitoring.model_endpoint.ModelEndpoint:
2718
+ """
2719
+ Returns a single `ModelEndpoint` object with additional metrics and feature related data.
2720
+
2721
+ :param project: The name of the project
2722
+ :param endpoint_id: The unique id of the model endpoint.
2723
+ :param start: The start time of the metrics. Can be represented by a string containing an
2724
+ RFC 3339 time, a Unix timestamp in milliseconds, a relative time (`'now'` or
2725
+ `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or
2726
+ 0 for the earliest time.
2727
+ :param end: The end time of the metrics. Can be represented by a string containing an
2728
+ RFC 3339 time, a Unix timestamp in milliseconds, a relative time (`'now'` or
2729
+ `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or
2730
+ 0 for the earliest time.
2731
+ :param metrics: A list of metrics to return for the model endpoint. There are pre-defined
2732
+ metrics for model endpoints such as predictions_per_second and
2733
+ latency_avg_5m but also custom metrics defined by the user. Please note that
2734
+ these metrics are stored in the time series DB and the results will be
2735
+ appeared under model_endpoint.spec.metrics.
2736
+ :param feature_analysis: When True, the base feature statistics and current feature statistics will
2737
+ be added to the output of the resulting object.
2738
+
2739
+ :return: A `ModelEndpoint` object.
2653
2740
  """
2654
2741
 
2655
2742
  path = f"projects/{project}/model-endpoints/{endpoint_id}"
@@ -2663,7 +2750,10 @@ class HTTPRunDB(RunDBInterface):
2663
2750
  "feature_analysis": feature_analysis,
2664
2751
  },
2665
2752
  )
2666
- return schemas.ModelEndpoint(**response.json())
2753
+
2754
+ return mlrun.model_monitoring.model_endpoint.ModelEndpoint.from_dict(
2755
+ response.json()
2756
+ )
2667
2757
 
2668
2758
  def patch_model_endpoint(
2669
2759
  self,
@@ -2677,10 +2767,10 @@ class HTTPRunDB(RunDBInterface):
2677
2767
  :param project: The name of the project.
2678
2768
  :param endpoint_id: The id of the endpoint.
2679
2769
  :param attributes: Dictionary of attributes that will be used for update the model endpoint. The keys
2680
- of this dictionary should exist in the target table. The values should be
2681
- from type string or from a valid numerical type such as int or float. More details
2682
- about the model endpoint available attributes can be found under
2683
- :py:class:`~mlrun.api.schemas.ModelEndpoint`.
2770
+ of this dictionary should exist in the target table. Note that the values should be
2771
+ from type string or from a valid numerical type such as int or float.
2772
+ More details about the model endpoint available attributes can be found under
2773
+ :py:class:`~mlrun.common.schemas.ModelEndpoint`.
2684
2774
 
2685
2775
  Example::
2686
2776
 
@@ -2708,18 +2798,18 @@ class HTTPRunDB(RunDBInterface):
2708
2798
  params=attributes,
2709
2799
  )
2710
2800
 
2711
- def create_marketplace_source(
2712
- self, source: Union[dict, schemas.IndexedMarketplaceSource]
2801
+ def create_hub_source(
2802
+ self, source: Union[dict, mlrun.common.schemas.IndexedHubSource]
2713
2803
  ):
2714
2804
  """
2715
- Add a new marketplace source.
2805
+ Add a new hub source.
2716
2806
 
2717
- MLRun maintains an ordered list of marketplace sources (“sources”) Each source has
2807
+ MLRun maintains an ordered list of hub sources (“sources”) Each source has
2718
2808
  its details registered and its order within the list. When creating a new source, the special order ``-1``
2719
2809
  can be used to mark this source as last in the list. However, once the source is in the MLRun list,
2720
2810
  its order will always be ``>0``.
2721
2811
 
2722
- The global marketplace source always exists in the list, and is always the last source
2812
+ The global hub source always exists in the list, and is always the last source
2723
2813
  (``order = -1``). It cannot be modified nor can it be moved to another order in the list.
2724
2814
 
2725
2815
  The source object may contain credentials which are needed to access the datastore where the source is stored.
@@ -2728,49 +2818,55 @@ class HTTPRunDB(RunDBInterface):
2728
2818
 
2729
2819
  Example::
2730
2820
 
2731
- import mlrun.api.schemas
2821
+ import mlrun.common.schemas
2732
2822
 
2733
2823
  # Add a private source as the last one (will be #1 in the list)
2734
- private_source = mlrun.api.schemas.IndexedMarketplaceSource(
2824
+ private_source = mlrun.common.schemas.IndexedHubeSource(
2735
2825
  order=-1,
2736
- source=mlrun.api.schemas.MarketplaceSource(
2737
- metadata=mlrun.api.schemas.MarketplaceObjectMetadata(name="priv", description="a private source"),
2738
- spec=mlrun.api.schemas.MarketplaceSourceSpec(path="/local/path/to/source", channel="development")
2826
+ source=mlrun.common.schemas.HubSource(
2827
+ metadata=mlrun.common.schemas.HubObjectMetadata(
2828
+ name="priv", description="a private source"
2829
+ ),
2830
+ spec=mlrun.common.schemas.HubSourceSpec(path="/local/path/to/source", channel="development")
2739
2831
  )
2740
2832
  )
2741
- db.create_marketplace_source(private_source)
2833
+ db.create_hub_source(private_source)
2742
2834
 
2743
2835
  # Add another source as 1st in the list - will push previous one to be #2
2744
- another_source = mlrun.api.schemas.IndexedMarketplaceSource(
2836
+ another_source = mlrun.common.schemas.IndexedHubSource(
2745
2837
  order=1,
2746
- source=mlrun.api.schemas.MarketplaceSource(
2747
- metadata=mlrun.api.schemas.MarketplaceObjectMetadata(name="priv-2", description="another source"),
2748
- spec=mlrun.api.schemas.MarketplaceSourceSpec(
2838
+ source=mlrun.common.schemas.HubSource(
2839
+ metadata=mlrun.common.schemas.HubObjectMetadata(
2840
+ name="priv-2", description="another source"
2841
+ ),
2842
+ spec=mlrun.common.schemas.HubSourceSpec(
2749
2843
  path="/local/path/to/source/2",
2750
2844
  channel="development",
2751
2845
  credentials={...}
2752
2846
  )
2753
2847
  )
2754
2848
  )
2755
- db.create_marketplace_source(another_source)
2849
+ db.create_hub_source(another_source)
2756
2850
 
2757
2851
  :param source: The source and its order, of type
2758
- :py:class:`~mlrun.api.schemas.marketplace.IndexedMarketplaceSource`, or in dictionary form.
2852
+ :py:class:`~mlrun.common.schemas.hub.IndexedHubSource`, or in dictionary form.
2759
2853
  :returns: The source object as inserted into the database, with credentials stripped.
2760
2854
  """
2761
- path = "marketplace/sources"
2762
- if isinstance(source, schemas.IndexedMarketplaceSource):
2855
+ path = "hub/sources"
2856
+ if isinstance(source, mlrun.common.schemas.IndexedHubSource):
2763
2857
  source = source.dict()
2764
2858
  response = self.api_call(method="POST", path=path, json=source)
2765
- return schemas.IndexedMarketplaceSource(**response.json())
2859
+ return mlrun.common.schemas.IndexedHubSource(**response.json())
2766
2860
 
2767
- def store_marketplace_source(
2768
- self, source_name: str, source: Union[dict, schemas.IndexedMarketplaceSource]
2861
+ def store_hub_source(
2862
+ self,
2863
+ source_name: str,
2864
+ source: Union[dict, mlrun.common.schemas.IndexedHubSource],
2769
2865
  ):
2770
2866
  """
2771
- Create or replace a marketplace source.
2867
+ Create or replace a hub source.
2772
2868
  For an example of the source format and explanation of the source order logic,
2773
- please see :py:func:`~create_marketplace_source`. This method can be used to modify the source itself or its
2869
+ please see :py:func:`~create_hub_source`. This method can be used to modify the source itself or its
2774
2870
  order in the list of sources.
2775
2871
 
2776
2872
  :param source_name: Name of the source object to modify/create. It must match the ``source.metadata.name``
@@ -2778,118 +2874,140 @@ class HTTPRunDB(RunDBInterface):
2778
2874
  :param source: Source object to store in the database.
2779
2875
  :returns: The source object as stored in the DB.
2780
2876
  """
2781
- path = f"marketplace/sources/{source_name}"
2782
- if isinstance(source, schemas.IndexedMarketplaceSource):
2877
+ path = f"hub/sources/{source_name}"
2878
+ if isinstance(source, mlrun.common.schemas.IndexedHubSource):
2783
2879
  source = source.dict()
2784
2880
 
2785
2881
  response = self.api_call(method="PUT", path=path, json=source)
2786
- return schemas.IndexedMarketplaceSource(**response.json())
2882
+ return mlrun.common.schemas.IndexedHubSource(**response.json())
2787
2883
 
2788
- def list_marketplace_sources(self):
2884
+ def list_hub_sources(self):
2789
2885
  """
2790
- List marketplace sources in the MLRun DB.
2886
+ List hub sources in the MLRun DB.
2791
2887
  """
2792
- path = "marketplace/sources"
2888
+ path = "hub/sources"
2793
2889
  response = self.api_call(method="GET", path=path).json()
2794
2890
  results = []
2795
2891
  for item in response:
2796
- results.append(schemas.IndexedMarketplaceSource(**item))
2892
+ results.append(mlrun.common.schemas.IndexedHubSource(**item))
2797
2893
  return results
2798
2894
 
2799
- def get_marketplace_source(self, source_name: str):
2895
+ def get_hub_source(self, source_name: str):
2800
2896
  """
2801
- Retrieve a marketplace source from the DB.
2897
+ Retrieve a hub source from the DB.
2802
2898
 
2803
- :param source_name: Name of the marketplace source to retrieve.
2899
+ :param source_name: Name of the hub source to retrieve.
2804
2900
  """
2805
- path = f"marketplace/sources/{source_name}"
2901
+ path = f"hub/sources/{source_name}"
2806
2902
  response = self.api_call(method="GET", path=path)
2807
- return schemas.IndexedMarketplaceSource(**response.json())
2903
+ return mlrun.common.schemas.IndexedHubSource(**response.json())
2808
2904
 
2809
- def delete_marketplace_source(self, source_name: str):
2905
+ def delete_hub_source(self, source_name: str):
2810
2906
  """
2811
- Delete a marketplace source from the DB.
2907
+ Delete a hub source from the DB.
2812
2908
  The source will be deleted from the list, and any following sources will be promoted - for example, if the
2813
2909
  1st source is deleted, the 2nd source will become #1 in the list.
2814
- The global marketplace source cannot be deleted.
2910
+ The global hub source cannot be deleted.
2815
2911
 
2816
- :param source_name: Name of the marketplace source to delete.
2912
+ :param source_name: Name of the hub source to delete.
2817
2913
  """
2818
- path = f"marketplace/sources/{source_name}"
2914
+ path = f"hub/sources/{source_name}"
2819
2915
  self.api_call(method="DELETE", path=path)
2820
2916
 
2821
- def get_marketplace_catalog(
2917
+ def get_hub_catalog(
2822
2918
  self,
2823
2919
  source_name: str,
2824
- channel: str = None,
2825
2920
  version: str = None,
2826
2921
  tag: str = None,
2827
2922
  force_refresh: bool = False,
2828
2923
  ):
2829
2924
  """
2830
- Retrieve the item catalog for a specified marketplace source.
2925
+ Retrieve the item catalog for a specified hub source.
2831
2926
  The list of items can be filtered according to various filters, using item's metadata to filter.
2832
2927
 
2833
2928
  :param source_name: Name of the source.
2834
- :param channel: Filter items according to their channel. For example ``development``.
2835
2929
  :param version: Filter items according to their version.
2836
2930
  :param tag: Filter items based on tag.
2837
- :param force_refresh: Make the server fetch the catalog from the actual marketplace source,
2931
+ :param force_refresh: Make the server fetch the catalog from the actual hub source,
2838
2932
  rather than rely on cached information which may exist from previous get requests. For example,
2839
2933
  if the source was re-built,
2840
2934
  this will make the server get the updated information. Default is ``False``.
2841
- :returns: :py:class:`~mlrun.api.schemas.marketplace.MarketplaceCatalog` object, which is essentially a list
2842
- of :py:class:`~mlrun.api.schemas.marketplace.MarketplaceItem` entries.
2935
+ :returns: :py:class:`~mlrun.common.schemas.hub.HubCatalog` object, which is essentially a list
2936
+ of :py:class:`~mlrun.common.schemas.hub.HubItem` entries.
2843
2937
  """
2844
- path = (f"marketplace/sources/{source_name}/items",)
2938
+ path = (f"hub/sources/{source_name}/items",)
2845
2939
  params = {
2846
- "channel": channel,
2847
2940
  "version": version,
2848
2941
  "tag": tag,
2849
2942
  "force-refresh": force_refresh,
2850
2943
  }
2851
2944
  response = self.api_call(method="GET", path=path, params=params)
2852
- return schemas.MarketplaceCatalog(**response.json())
2945
+ return mlrun.common.schemas.HubCatalog(**response.json())
2853
2946
 
2854
- def get_marketplace_item(
2947
+ def get_hub_item(
2855
2948
  self,
2856
2949
  source_name: str,
2857
2950
  item_name: str,
2858
- channel: str = "development",
2859
2951
  version: str = None,
2860
2952
  tag: str = "latest",
2861
2953
  force_refresh: bool = False,
2862
2954
  ):
2863
2955
  """
2864
- Retrieve a specific marketplace item.
2956
+ Retrieve a specific hub item.
2865
2957
 
2866
2958
  :param source_name: Name of source.
2867
2959
  :param item_name: Name of the item to retrieve, as it appears in the catalog.
2868
- :param channel: Get the item from the specified channel. Default is ``development``.
2869
2960
  :param version: Get a specific version of the item. Default is ``None``.
2870
2961
  :param tag: Get a specific version of the item identified by tag. Default is ``latest``.
2871
- :param force_refresh: Make the server fetch the information from the actual marketplace
2962
+ :param force_refresh: Make the server fetch the information from the actual hub
2872
2963
  source, rather than
2873
2964
  rely on cached information. Default is ``False``.
2874
- :returns: :py:class:`~mlrun.api.schemas.marketplace.MarketplaceItem`.
2965
+ :returns: :py:class:`~mlrun.common.schemas.hub.HubItem`.
2875
2966
  """
2876
- path = (f"marketplace/sources/{source_name}/items/{item_name}",)
2967
+ path = (f"hub/sources/{source_name}/items/{item_name}",)
2877
2968
  params = {
2878
- "channel": channel,
2879
2969
  "version": version,
2880
2970
  "tag": tag,
2881
2971
  "force-refresh": force_refresh,
2882
2972
  }
2883
2973
  response = self.api_call(method="GET", path=path, params=params)
2884
- return schemas.MarketplaceItem(**response.json())
2974
+ return mlrun.common.schemas.HubItem(**response.json())
2975
+
2976
+ def get_hub_asset(
2977
+ self,
2978
+ source_name: str,
2979
+ item_name: str,
2980
+ asset_name: str,
2981
+ version: str = None,
2982
+ tag: str = "latest",
2983
+ ):
2984
+ """
2985
+ Get hub asset from item.
2986
+
2987
+ :param source_name: Name of source.
2988
+ :param item_name: Name of the item which holds the asset.
2989
+ :param asset_name: Name of the asset to retrieve.
2990
+ :param version: Get a specific version of the item. Default is ``None``.
2991
+ :param tag: Get a specific version of the item identified by tag. Default is ``latest``.
2992
+
2993
+ :return: http response with the asset in the content attribute
2994
+ """
2995
+ path = (f"hub/sources/{source_name}/items/{item_name}/assets/{asset_name}",)
2996
+ params = {
2997
+ "version": version,
2998
+ "tag": tag,
2999
+ }
3000
+ response = self.api_call(method="GET", path=path, params=params)
3001
+ return response
2885
3002
 
2886
3003
  def verify_authorization(
2887
- self, authorization_verification_input: schemas.AuthorizationVerificationInput
3004
+ self,
3005
+ authorization_verification_input: mlrun.common.schemas.AuthorizationVerificationInput,
2888
3006
  ):
2889
3007
  """Verifies authorization for the provided action on the provided resource.
2890
3008
 
2891
3009
  :param authorization_verification_input: Instance of
2892
- :py:class:`~mlrun.api.schemas.AuthorizationVerificationInput` that includes all the needed parameters for
3010
+ :py:class:`~mlrun.common.schemas.AuthorizationVerificationInput` that includes all the needed parameters for
2893
3011
  the auth verification
2894
3012
  """
2895
3013
  error_message = "Authorization check failed"
@@ -2900,10 +3018,10 @@ class HTTPRunDB(RunDBInterface):
2900
3018
  body=dict_to_json(authorization_verification_input.dict()),
2901
3019
  )
2902
3020
 
2903
- def trigger_migrations(self) -> Optional[schemas.BackgroundTask]:
3021
+ def trigger_migrations(self) -> Optional[mlrun.common.schemas.BackgroundTask]:
2904
3022
  """Trigger migrations (will do nothing if no migrations are needed) and wait for them to finish if actually
2905
3023
  triggered
2906
- :returns: :py:class:`~mlrun.api.schemas.BackgroundTask`.
3024
+ :returns: :py:class:`~mlrun.common.schemas.BackgroundTask`.
2907
3025
  """
2908
3026
  response = self.api_call(
2909
3027
  "POST",
@@ -2911,12 +3029,62 @@ class HTTPRunDB(RunDBInterface):
2911
3029
  "Failed triggering migrations",
2912
3030
  )
2913
3031
  if response.status_code == http.HTTPStatus.ACCEPTED:
2914
- background_task = schemas.BackgroundTask(**response.json())
3032
+ background_task = mlrun.common.schemas.BackgroundTask(**response.json())
2915
3033
  return self._wait_for_background_task_to_reach_terminal_state(
2916
3034
  background_task.metadata.name
2917
3035
  )
2918
3036
  return None
2919
3037
 
3038
+ def set_run_notifications(
3039
+ self,
3040
+ project: str,
3041
+ run_uid: str,
3042
+ notifications: typing.List[mlrun.model.Notification] = None,
3043
+ ):
3044
+ """
3045
+ Set notifications on a run. This will override any existing notifications on the run.
3046
+ :param project: Project containing the run.
3047
+ :param run_uid: UID of the run.
3048
+ :param notifications: List of notifications to set on the run. Default is an empty list.
3049
+ """
3050
+ notifications = notifications or []
3051
+
3052
+ self.api_call(
3053
+ "PUT",
3054
+ f"projects/{project}/runs/{run_uid}/notifications",
3055
+ f"Failed to set notifications on run. uid={run_uid}, project={project}",
3056
+ json={
3057
+ "notifications": [
3058
+ notification.to_dict() for notification in notifications
3059
+ ],
3060
+ },
3061
+ )
3062
+
3063
+ def set_schedule_notifications(
3064
+ self,
3065
+ project: str,
3066
+ schedule_name: str,
3067
+ notifications: typing.List[mlrun.model.Notification] = None,
3068
+ ):
3069
+ """
3070
+ Set notifications on a schedule. This will override any existing notifications on the schedule.
3071
+ :param project: Project containing the schedule.
3072
+ :param schedule_name: Name of the schedule.
3073
+ :param notifications: List of notifications to set on the schedule. Default is an empty list.
3074
+ """
3075
+ notifications = notifications or []
3076
+
3077
+ self.api_call(
3078
+ "PUT",
3079
+ f"projects/{project}/schedules/{schedule_name}/notifications",
3080
+ f"Failed to set notifications on schedule. schedule={schedule_name}, project={project}",
3081
+ json={
3082
+ "notifications": [
3083
+ notification.to_dict() for notification in notifications
3084
+ ],
3085
+ },
3086
+ )
3087
+
2920
3088
 
2921
3089
  def _as_json(obj):
2922
3090
  fn = getattr(obj, "to_json", None)