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

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

Potentially problematic release.


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

Files changed (444) hide show
  1. mlrun/__init__.py +3 -3
  2. mlrun/__main__.py +79 -37
  3. mlrun/api/__init__.py +1 -1
  4. mlrun/api/api/__init__.py +1 -1
  5. mlrun/api/api/api.py +4 -4
  6. mlrun/api/api/deps.py +10 -21
  7. mlrun/api/api/endpoints/__init__.py +1 -1
  8. mlrun/api/api/endpoints/artifacts.py +64 -36
  9. mlrun/api/api/endpoints/auth.py +4 -4
  10. mlrun/api/api/endpoints/background_tasks.py +11 -11
  11. mlrun/api/api/endpoints/client_spec.py +5 -5
  12. mlrun/api/api/endpoints/clusterization_spec.py +6 -4
  13. mlrun/api/api/endpoints/feature_store.py +124 -115
  14. mlrun/api/api/endpoints/files.py +22 -14
  15. mlrun/api/api/endpoints/frontend_spec.py +28 -21
  16. mlrun/api/api/endpoints/functions.py +142 -87
  17. mlrun/api/api/endpoints/grafana_proxy.py +89 -442
  18. mlrun/api/api/endpoints/healthz.py +20 -7
  19. mlrun/api/api/endpoints/hub.py +320 -0
  20. mlrun/api/api/endpoints/internal/__init__.py +1 -1
  21. mlrun/api/api/endpoints/internal/config.py +1 -1
  22. mlrun/api/api/endpoints/internal/memory_reports.py +9 -9
  23. mlrun/api/api/endpoints/logs.py +11 -11
  24. mlrun/api/api/endpoints/model_endpoints.py +74 -70
  25. mlrun/api/api/endpoints/operations.py +13 -9
  26. mlrun/api/api/endpoints/pipelines.py +93 -88
  27. mlrun/api/api/endpoints/projects.py +35 -35
  28. mlrun/api/api/endpoints/runs.py +69 -27
  29. mlrun/api/api/endpoints/runtime_resources.py +28 -28
  30. mlrun/api/api/endpoints/schedules.py +98 -41
  31. mlrun/api/api/endpoints/secrets.py +37 -32
  32. mlrun/api/api/endpoints/submit.py +12 -12
  33. mlrun/api/api/endpoints/tags.py +20 -22
  34. mlrun/api/api/utils.py +251 -42
  35. mlrun/api/constants.py +1 -1
  36. mlrun/api/crud/__init__.py +18 -15
  37. mlrun/api/crud/artifacts.py +10 -10
  38. mlrun/api/crud/client_spec.py +4 -4
  39. mlrun/api/crud/clusterization_spec.py +3 -3
  40. mlrun/api/crud/feature_store.py +54 -46
  41. mlrun/api/crud/functions.py +3 -3
  42. mlrun/api/crud/hub.py +312 -0
  43. mlrun/api/crud/logs.py +11 -9
  44. mlrun/api/crud/model_monitoring/__init__.py +3 -3
  45. mlrun/api/crud/model_monitoring/grafana.py +435 -0
  46. mlrun/api/crud/model_monitoring/model_endpoints.py +352 -129
  47. mlrun/api/crud/notifications.py +149 -0
  48. mlrun/api/crud/pipelines.py +67 -52
  49. mlrun/api/crud/projects.py +51 -23
  50. mlrun/api/crud/runs.py +7 -5
  51. mlrun/api/crud/runtime_resources.py +13 -13
  52. mlrun/api/{db/filedb → crud/runtimes}/__init__.py +1 -1
  53. mlrun/api/crud/runtimes/nuclio/__init__.py +14 -0
  54. mlrun/api/crud/runtimes/nuclio/function.py +505 -0
  55. mlrun/api/crud/runtimes/nuclio/helpers.py +310 -0
  56. mlrun/api/crud/secrets.py +88 -46
  57. mlrun/api/crud/tags.py +5 -5
  58. mlrun/api/db/__init__.py +1 -1
  59. mlrun/api/db/base.py +102 -54
  60. mlrun/api/db/init_db.py +2 -3
  61. mlrun/api/db/session.py +4 -12
  62. mlrun/api/db/sqldb/__init__.py +1 -1
  63. mlrun/api/db/sqldb/db.py +439 -196
  64. mlrun/api/db/sqldb/helpers.py +1 -1
  65. mlrun/api/db/sqldb/models/__init__.py +3 -3
  66. mlrun/api/db/sqldb/models/models_mysql.py +82 -64
  67. mlrun/api/db/sqldb/models/models_sqlite.py +76 -64
  68. mlrun/api/db/sqldb/session.py +27 -20
  69. mlrun/api/initial_data.py +82 -24
  70. mlrun/api/launcher.py +196 -0
  71. mlrun/api/main.py +91 -22
  72. mlrun/api/middlewares.py +6 -5
  73. mlrun/api/migrations_mysql/env.py +1 -1
  74. mlrun/api/migrations_mysql/versions/28383af526f3_market_place_to_hub.py +40 -0
  75. mlrun/api/migrations_mysql/versions/32bae1b0e29c_increase_timestamp_fields_precision.py +1 -1
  76. mlrun/api/migrations_mysql/versions/4903aef6a91d_tag_foreign_key_and_cascades.py +1 -1
  77. mlrun/api/migrations_mysql/versions/5f1351c88a19_adding_background_tasks_table.py +1 -1
  78. mlrun/api/migrations_mysql/versions/88e656800d6a_add_requested_logs_column_and_index_to_.py +1 -1
  79. mlrun/api/migrations_mysql/versions/9d16de5f03a7_adding_data_versions_table.py +1 -1
  80. mlrun/api/migrations_mysql/versions/b86f5b53f3d7_adding_name_and_updated_to_runs_table.py +1 -1
  81. mlrun/api/migrations_mysql/versions/c4af40b0bf61_init.py +1 -1
  82. mlrun/api/migrations_mysql/versions/c905d15bd91d_notifications.py +72 -0
  83. mlrun/api/migrations_mysql/versions/ee041e8fdaa0_adding_next_run_time_column_to_schedule_.py +1 -1
  84. mlrun/api/migrations_sqlite/env.py +1 -1
  85. mlrun/api/migrations_sqlite/versions/11f8dd2dc9fe_init.py +1 -1
  86. mlrun/api/migrations_sqlite/versions/1c954f8cb32d_schedule_last_run_uri.py +1 -1
  87. mlrun/api/migrations_sqlite/versions/2b6d23c715aa_adding_feature_sets.py +1 -1
  88. mlrun/api/migrations_sqlite/versions/4acd9430b093_market_place_to_hub.py +77 -0
  89. mlrun/api/migrations_sqlite/versions/6401142f2d7c_adding_next_run_time_column_to_schedule_.py +1 -1
  90. mlrun/api/migrations_sqlite/versions/64d90a1a69bc_adding_background_tasks_table.py +1 -1
  91. mlrun/api/migrations_sqlite/versions/803438ecd005_add_requested_logs_column_to_runs.py +1 -1
  92. mlrun/api/migrations_sqlite/versions/863114f0c659_refactoring_feature_set.py +1 -1
  93. mlrun/api/migrations_sqlite/versions/959ae00528ad_notifications.py +63 -0
  94. mlrun/api/migrations_sqlite/versions/accf9fc83d38_adding_data_versions_table.py +1 -1
  95. mlrun/api/migrations_sqlite/versions/b68e8e897a28_schedule_labels.py +1 -1
  96. mlrun/api/migrations_sqlite/versions/bcd0c1f9720c_adding_project_labels.py +1 -1
  97. mlrun/api/migrations_sqlite/versions/cf21882f938e_schedule_id.py +1 -1
  98. mlrun/api/migrations_sqlite/versions/d781f58f607f_tag_object_name_string.py +1 -1
  99. mlrun/api/migrations_sqlite/versions/deac06871ace_adding_marketplace_sources_table.py +1 -1
  100. mlrun/api/migrations_sqlite/versions/e1dd5983c06b_schedule_concurrency_limit.py +1 -1
  101. mlrun/api/migrations_sqlite/versions/e5594ed3ab53_adding_name_and_updated_to_runs_table.py +1 -1
  102. mlrun/api/migrations_sqlite/versions/f4249b4ba6fa_adding_feature_vectors.py +1 -1
  103. mlrun/api/migrations_sqlite/versions/f7b5a1a03629_adding_feature_labels.py +1 -1
  104. mlrun/api/schemas/__init__.py +216 -138
  105. mlrun/api/utils/__init__.py +1 -1
  106. mlrun/api/utils/asyncio.py +1 -1
  107. mlrun/api/utils/auth/__init__.py +1 -1
  108. mlrun/api/utils/auth/providers/__init__.py +1 -1
  109. mlrun/api/utils/auth/providers/base.py +7 -7
  110. mlrun/api/utils/auth/providers/nop.py +6 -7
  111. mlrun/api/utils/auth/providers/opa.py +17 -17
  112. mlrun/api/utils/auth/verifier.py +36 -34
  113. mlrun/api/utils/background_tasks.py +24 -24
  114. mlrun/{builder.py → api/utils/builder.py} +216 -123
  115. mlrun/api/utils/clients/__init__.py +1 -1
  116. mlrun/api/utils/clients/chief.py +19 -4
  117. mlrun/api/utils/clients/iguazio.py +106 -60
  118. mlrun/api/utils/clients/log_collector.py +1 -1
  119. mlrun/api/utils/clients/nuclio.py +23 -23
  120. mlrun/api/utils/clients/protocols/grpc.py +2 -2
  121. mlrun/api/utils/db/__init__.py +1 -1
  122. mlrun/api/utils/db/alembic.py +1 -1
  123. mlrun/api/utils/db/backup.py +1 -1
  124. mlrun/api/utils/db/mysql.py +24 -25
  125. mlrun/api/utils/db/sql_collation.py +1 -1
  126. mlrun/api/utils/db/sqlite_migration.py +2 -2
  127. mlrun/api/utils/events/__init__.py +14 -0
  128. mlrun/api/utils/events/base.py +57 -0
  129. mlrun/api/utils/events/events_factory.py +41 -0
  130. mlrun/api/utils/events/iguazio.py +217 -0
  131. mlrun/api/utils/events/nop.py +55 -0
  132. mlrun/api/utils/helpers.py +16 -13
  133. mlrun/api/utils/memory_reports.py +1 -1
  134. mlrun/api/utils/periodic.py +6 -3
  135. mlrun/api/utils/projects/__init__.py +1 -1
  136. mlrun/api/utils/projects/follower.py +33 -33
  137. mlrun/api/utils/projects/leader.py +36 -34
  138. mlrun/api/utils/projects/member.py +27 -27
  139. mlrun/api/utils/projects/remotes/__init__.py +1 -1
  140. mlrun/api/utils/projects/remotes/follower.py +13 -13
  141. mlrun/api/utils/projects/remotes/leader.py +10 -10
  142. mlrun/api/utils/projects/remotes/nop_follower.py +27 -21
  143. mlrun/api/utils/projects/remotes/nop_leader.py +17 -16
  144. mlrun/api/utils/scheduler.py +140 -51
  145. mlrun/api/utils/singletons/__init__.py +1 -1
  146. mlrun/api/utils/singletons/db.py +9 -15
  147. mlrun/api/utils/singletons/k8s.py +677 -5
  148. mlrun/api/utils/singletons/logs_dir.py +1 -1
  149. mlrun/api/utils/singletons/project_member.py +1 -1
  150. mlrun/api/utils/singletons/scheduler.py +1 -1
  151. mlrun/artifacts/__init__.py +2 -2
  152. mlrun/artifacts/base.py +8 -2
  153. mlrun/artifacts/dataset.py +5 -3
  154. mlrun/artifacts/manager.py +7 -1
  155. mlrun/artifacts/model.py +15 -4
  156. mlrun/artifacts/plots.py +1 -1
  157. mlrun/common/__init__.py +1 -1
  158. mlrun/common/constants.py +15 -0
  159. mlrun/common/model_monitoring.py +209 -0
  160. mlrun/common/schemas/__init__.py +167 -0
  161. mlrun/{api → common}/schemas/artifact.py +13 -14
  162. mlrun/{api → common}/schemas/auth.py +10 -8
  163. mlrun/{api → common}/schemas/background_task.py +3 -3
  164. mlrun/{api → common}/schemas/client_spec.py +1 -1
  165. mlrun/{api → common}/schemas/clusterization_spec.py +3 -3
  166. mlrun/{api → common}/schemas/constants.py +21 -8
  167. mlrun/common/schemas/events.py +36 -0
  168. mlrun/{api → common}/schemas/feature_store.py +2 -1
  169. mlrun/{api → common}/schemas/frontend_spec.py +7 -6
  170. mlrun/{api → common}/schemas/function.py +5 -5
  171. mlrun/{api → common}/schemas/http.py +3 -3
  172. mlrun/common/schemas/hub.py +134 -0
  173. mlrun/{api → common}/schemas/k8s.py +3 -3
  174. mlrun/{api → common}/schemas/memory_reports.py +1 -1
  175. mlrun/common/schemas/model_endpoints.py +342 -0
  176. mlrun/common/schemas/notification.py +57 -0
  177. mlrun/{api → common}/schemas/object.py +6 -6
  178. mlrun/{api → common}/schemas/pipeline.py +3 -3
  179. mlrun/{api → common}/schemas/project.py +6 -5
  180. mlrun/common/schemas/regex.py +24 -0
  181. mlrun/common/schemas/runs.py +30 -0
  182. mlrun/{api → common}/schemas/runtime_resource.py +3 -3
  183. mlrun/{api → common}/schemas/schedule.py +19 -7
  184. mlrun/{api → common}/schemas/secret.py +3 -3
  185. mlrun/{api → common}/schemas/tag.py +2 -2
  186. mlrun/common/types.py +25 -0
  187. mlrun/config.py +152 -20
  188. mlrun/data_types/__init__.py +7 -2
  189. mlrun/data_types/data_types.py +4 -2
  190. mlrun/data_types/infer.py +1 -1
  191. mlrun/data_types/spark.py +10 -3
  192. mlrun/datastore/__init__.py +10 -3
  193. mlrun/datastore/azure_blob.py +1 -1
  194. mlrun/datastore/base.py +185 -53
  195. mlrun/datastore/datastore.py +1 -1
  196. mlrun/datastore/filestore.py +1 -1
  197. mlrun/datastore/google_cloud_storage.py +1 -1
  198. mlrun/datastore/inmem.py +4 -1
  199. mlrun/datastore/redis.py +1 -1
  200. mlrun/datastore/s3.py +1 -1
  201. mlrun/datastore/sources.py +192 -70
  202. mlrun/datastore/spark_udf.py +44 -0
  203. mlrun/datastore/store_resources.py +4 -4
  204. mlrun/datastore/targets.py +115 -45
  205. mlrun/datastore/utils.py +127 -5
  206. mlrun/datastore/v3io.py +1 -1
  207. mlrun/datastore/wasbfs/__init__.py +1 -1
  208. mlrun/datastore/wasbfs/fs.py +1 -1
  209. mlrun/db/__init__.py +7 -5
  210. mlrun/db/base.py +112 -68
  211. mlrun/db/httpdb.py +445 -277
  212. mlrun/db/nopdb.py +491 -0
  213. mlrun/db/sqldb.py +112 -65
  214. mlrun/errors.py +6 -1
  215. mlrun/execution.py +44 -22
  216. mlrun/feature_store/__init__.py +1 -1
  217. mlrun/feature_store/api.py +143 -95
  218. mlrun/feature_store/common.py +16 -20
  219. mlrun/feature_store/feature_set.py +42 -12
  220. mlrun/feature_store/feature_vector.py +32 -21
  221. mlrun/feature_store/ingestion.py +9 -12
  222. mlrun/feature_store/retrieval/__init__.py +3 -2
  223. mlrun/feature_store/retrieval/base.py +388 -66
  224. mlrun/feature_store/retrieval/dask_merger.py +63 -151
  225. mlrun/feature_store/retrieval/job.py +30 -12
  226. mlrun/feature_store/retrieval/local_merger.py +40 -133
  227. mlrun/feature_store/retrieval/spark_merger.py +129 -127
  228. mlrun/feature_store/retrieval/storey_merger.py +173 -0
  229. mlrun/feature_store/steps.py +132 -15
  230. mlrun/features.py +8 -3
  231. mlrun/frameworks/__init__.py +1 -1
  232. mlrun/frameworks/_common/__init__.py +1 -1
  233. mlrun/frameworks/_common/artifacts_library.py +1 -1
  234. mlrun/frameworks/_common/mlrun_interface.py +1 -1
  235. mlrun/frameworks/_common/model_handler.py +1 -1
  236. mlrun/frameworks/_common/plan.py +1 -1
  237. mlrun/frameworks/_common/producer.py +1 -1
  238. mlrun/frameworks/_common/utils.py +1 -1
  239. mlrun/frameworks/_dl_common/__init__.py +1 -1
  240. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -1
  241. mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
  242. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +1 -1
  243. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +1 -1
  244. mlrun/frameworks/_dl_common/model_handler.py +1 -1
  245. mlrun/frameworks/_dl_common/utils.py +1 -1
  246. mlrun/frameworks/_ml_common/__init__.py +1 -1
  247. mlrun/frameworks/_ml_common/artifacts_library.py +1 -1
  248. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -1
  249. mlrun/frameworks/_ml_common/loggers/logger.py +1 -1
  250. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
  251. mlrun/frameworks/_ml_common/model_handler.py +1 -1
  252. mlrun/frameworks/_ml_common/pkl_model_server.py +13 -1
  253. mlrun/frameworks/_ml_common/plan.py +1 -1
  254. mlrun/frameworks/_ml_common/plans/__init__.py +1 -1
  255. mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +1 -6
  256. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +1 -1
  257. mlrun/frameworks/_ml_common/plans/dataset_plan.py +1 -1
  258. mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +1 -1
  259. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +1 -1
  260. mlrun/frameworks/_ml_common/producer.py +1 -1
  261. mlrun/frameworks/_ml_common/utils.py +1 -1
  262. mlrun/frameworks/auto_mlrun/__init__.py +1 -1
  263. mlrun/frameworks/auto_mlrun/auto_mlrun.py +1 -1
  264. mlrun/frameworks/huggingface/__init__.py +1 -1
  265. mlrun/frameworks/huggingface/model_server.py +1 -1
  266. mlrun/frameworks/lgbm/__init__.py +1 -1
  267. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -1
  268. mlrun/frameworks/lgbm/callbacks/callback.py +1 -1
  269. mlrun/frameworks/lgbm/callbacks/logging_callback.py +1 -1
  270. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +1 -1
  271. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -1
  272. mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -1
  273. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +1 -1
  274. mlrun/frameworks/lgbm/mlrun_interfaces/model_mlrun_interface.py +1 -1
  275. mlrun/frameworks/lgbm/model_handler.py +1 -1
  276. mlrun/frameworks/lgbm/model_server.py +1 -1
  277. mlrun/frameworks/lgbm/utils.py +1 -1
  278. mlrun/frameworks/onnx/__init__.py +1 -1
  279. mlrun/frameworks/onnx/dataset.py +1 -1
  280. mlrun/frameworks/onnx/mlrun_interface.py +1 -1
  281. mlrun/frameworks/onnx/model_handler.py +1 -1
  282. mlrun/frameworks/onnx/model_server.py +1 -1
  283. mlrun/frameworks/parallel_coordinates.py +1 -1
  284. mlrun/frameworks/pytorch/__init__.py +1 -1
  285. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -1
  286. mlrun/frameworks/pytorch/callbacks/callback.py +1 -1
  287. mlrun/frameworks/pytorch/callbacks/logging_callback.py +1 -1
  288. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +1 -1
  289. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +1 -1
  290. mlrun/frameworks/pytorch/callbacks_handler.py +1 -1
  291. mlrun/frameworks/pytorch/mlrun_interface.py +1 -1
  292. mlrun/frameworks/pytorch/model_handler.py +1 -1
  293. mlrun/frameworks/pytorch/model_server.py +1 -1
  294. mlrun/frameworks/pytorch/utils.py +1 -1
  295. mlrun/frameworks/sklearn/__init__.py +1 -1
  296. mlrun/frameworks/sklearn/estimator.py +1 -1
  297. mlrun/frameworks/sklearn/metric.py +1 -1
  298. mlrun/frameworks/sklearn/metrics_library.py +1 -1
  299. mlrun/frameworks/sklearn/mlrun_interface.py +1 -1
  300. mlrun/frameworks/sklearn/model_handler.py +1 -1
  301. mlrun/frameworks/sklearn/utils.py +1 -1
  302. mlrun/frameworks/tf_keras/__init__.py +1 -1
  303. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -1
  304. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  305. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +1 -1
  306. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +1 -1
  307. mlrun/frameworks/tf_keras/mlrun_interface.py +1 -1
  308. mlrun/frameworks/tf_keras/model_handler.py +1 -1
  309. mlrun/frameworks/tf_keras/model_server.py +1 -1
  310. mlrun/frameworks/tf_keras/utils.py +1 -1
  311. mlrun/frameworks/xgboost/__init__.py +1 -1
  312. mlrun/frameworks/xgboost/mlrun_interface.py +1 -1
  313. mlrun/frameworks/xgboost/model_handler.py +1 -1
  314. mlrun/frameworks/xgboost/utils.py +1 -1
  315. mlrun/k8s_utils.py +14 -765
  316. mlrun/kfpops.py +14 -17
  317. mlrun/launcher/__init__.py +13 -0
  318. mlrun/launcher/base.py +406 -0
  319. mlrun/launcher/client.py +159 -0
  320. mlrun/launcher/factory.py +50 -0
  321. mlrun/launcher/local.py +276 -0
  322. mlrun/launcher/remote.py +178 -0
  323. mlrun/lists.py +10 -2
  324. mlrun/mlutils/__init__.py +1 -1
  325. mlrun/mlutils/data.py +1 -1
  326. mlrun/mlutils/models.py +1 -1
  327. mlrun/mlutils/plots.py +1 -1
  328. mlrun/model.py +252 -14
  329. mlrun/model_monitoring/__init__.py +41 -0
  330. mlrun/model_monitoring/features_drift_table.py +1 -1
  331. mlrun/model_monitoring/helpers.py +123 -38
  332. mlrun/model_monitoring/model_endpoint.py +144 -0
  333. mlrun/model_monitoring/model_monitoring_batch.py +310 -259
  334. mlrun/model_monitoring/stores/__init__.py +106 -0
  335. mlrun/model_monitoring/stores/kv_model_endpoint_store.py +448 -0
  336. mlrun/model_monitoring/stores/model_endpoint_store.py +147 -0
  337. mlrun/model_monitoring/stores/models/__init__.py +23 -0
  338. mlrun/model_monitoring/stores/models/base.py +18 -0
  339. mlrun/model_monitoring/stores/models/mysql.py +100 -0
  340. mlrun/model_monitoring/stores/models/sqlite.py +98 -0
  341. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +370 -0
  342. mlrun/model_monitoring/stream_processing_fs.py +239 -271
  343. mlrun/package/__init__.py +163 -0
  344. mlrun/package/context_handler.py +325 -0
  345. mlrun/package/errors.py +47 -0
  346. mlrun/package/packager.py +298 -0
  347. mlrun/{runtimes/package → package/packagers}/__init__.py +3 -1
  348. mlrun/package/packagers/default_packager.py +422 -0
  349. mlrun/package/packagers/numpy_packagers.py +612 -0
  350. mlrun/package/packagers/pandas_packagers.py +968 -0
  351. mlrun/package/packagers/python_standard_library_packagers.py +616 -0
  352. mlrun/package/packagers_manager.py +786 -0
  353. mlrun/package/utils/__init__.py +53 -0
  354. mlrun/package/utils/_archiver.py +226 -0
  355. mlrun/package/utils/_formatter.py +211 -0
  356. mlrun/package/utils/_pickler.py +234 -0
  357. mlrun/package/utils/_supported_format.py +71 -0
  358. mlrun/package/utils/log_hint_utils.py +93 -0
  359. mlrun/package/utils/type_hint_utils.py +298 -0
  360. mlrun/platforms/__init__.py +1 -1
  361. mlrun/platforms/iguazio.py +34 -2
  362. mlrun/platforms/other.py +1 -1
  363. mlrun/projects/__init__.py +1 -1
  364. mlrun/projects/operations.py +14 -9
  365. mlrun/projects/pipelines.py +31 -13
  366. mlrun/projects/project.py +762 -238
  367. mlrun/render.py +49 -19
  368. mlrun/run.py +57 -326
  369. mlrun/runtimes/__init__.py +3 -9
  370. mlrun/runtimes/base.py +247 -784
  371. mlrun/runtimes/constants.py +1 -1
  372. mlrun/runtimes/daskjob.py +45 -41
  373. mlrun/runtimes/funcdoc.py +43 -7
  374. mlrun/runtimes/function.py +66 -656
  375. mlrun/runtimes/function_reference.py +1 -1
  376. mlrun/runtimes/generators.py +1 -1
  377. mlrun/runtimes/kubejob.py +99 -116
  378. mlrun/runtimes/local.py +59 -66
  379. mlrun/runtimes/mpijob/__init__.py +1 -1
  380. mlrun/runtimes/mpijob/abstract.py +13 -15
  381. mlrun/runtimes/mpijob/v1.py +3 -1
  382. mlrun/runtimes/mpijob/v1alpha1.py +1 -1
  383. mlrun/runtimes/nuclio.py +1 -1
  384. mlrun/runtimes/pod.py +51 -26
  385. mlrun/runtimes/remotesparkjob.py +3 -1
  386. mlrun/runtimes/serving.py +12 -4
  387. mlrun/runtimes/sparkjob/__init__.py +1 -2
  388. mlrun/runtimes/sparkjob/abstract.py +44 -31
  389. mlrun/runtimes/sparkjob/spark3job.py +11 -9
  390. mlrun/runtimes/utils.py +61 -42
  391. mlrun/secrets.py +16 -18
  392. mlrun/serving/__init__.py +3 -2
  393. mlrun/serving/merger.py +1 -1
  394. mlrun/serving/remote.py +1 -1
  395. mlrun/serving/routers.py +39 -42
  396. mlrun/serving/server.py +23 -13
  397. mlrun/serving/serving_wrapper.py +1 -1
  398. mlrun/serving/states.py +172 -39
  399. mlrun/serving/utils.py +1 -1
  400. mlrun/serving/v1_serving.py +1 -1
  401. mlrun/serving/v2_serving.py +29 -21
  402. mlrun/utils/__init__.py +1 -2
  403. mlrun/utils/async_http.py +8 -1
  404. mlrun/utils/azure_vault.py +1 -1
  405. mlrun/utils/clones.py +2 -2
  406. mlrun/utils/condition_evaluator.py +65 -0
  407. mlrun/utils/db.py +52 -0
  408. mlrun/utils/helpers.py +188 -13
  409. mlrun/utils/http.py +89 -54
  410. mlrun/utils/logger.py +48 -8
  411. mlrun/utils/model_monitoring.py +132 -100
  412. mlrun/utils/notifications/__init__.py +1 -1
  413. mlrun/utils/notifications/notification/__init__.py +8 -6
  414. mlrun/utils/notifications/notification/base.py +20 -14
  415. mlrun/utils/notifications/notification/console.py +7 -4
  416. mlrun/utils/notifications/notification/git.py +36 -19
  417. mlrun/utils/notifications/notification/ipython.py +10 -8
  418. mlrun/utils/notifications/notification/slack.py +18 -13
  419. mlrun/utils/notifications/notification_pusher.py +377 -56
  420. mlrun/utils/regex.py +6 -1
  421. mlrun/utils/singleton.py +1 -1
  422. mlrun/utils/v3io_clients.py +1 -1
  423. mlrun/utils/vault.py +270 -269
  424. mlrun/utils/version/__init__.py +1 -1
  425. mlrun/utils/version/version.json +2 -2
  426. mlrun/utils/version/version.py +1 -1
  427. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/METADATA +16 -10
  428. mlrun-1.4.0.dist-info/RECORD +434 -0
  429. mlrun/api/api/endpoints/marketplace.py +0 -257
  430. mlrun/api/crud/marketplace.py +0 -221
  431. mlrun/api/crud/model_monitoring/model_endpoint_store.py +0 -847
  432. mlrun/api/db/filedb/db.py +0 -518
  433. mlrun/api/schemas/marketplace.py +0 -128
  434. mlrun/api/schemas/model_endpoints.py +0 -185
  435. mlrun/db/filedb.py +0 -891
  436. mlrun/feature_store/retrieval/online.py +0 -92
  437. mlrun/model_monitoring/constants.py +0 -67
  438. mlrun/runtimes/package/context_handler.py +0 -711
  439. mlrun/runtimes/sparkjob/spark2job.py +0 -59
  440. mlrun-1.3.3rc1.dist-info/RECORD +0 -381
  441. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
  442. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
  443. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
  444. {mlrun-1.3.3rc1.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
@@ -1,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.
@@ -16,10 +16,10 @@ import typing
16
16
 
17
17
  import sqlalchemy.orm
18
18
 
19
- import mlrun.api.schemas
20
19
  import mlrun.api.utils.projects.remotes.follower
21
20
  import mlrun.api.utils.singletons.db
22
21
  import mlrun.api.utils.singletons.project_member
22
+ import mlrun.common.schemas
23
23
  import mlrun.config
24
24
  import mlrun.errors
25
25
  import mlrun.utils.singleton
@@ -32,9 +32,12 @@ class FeatureStore(
32
32
  self,
33
33
  db_session: sqlalchemy.orm.Session,
34
34
  project: str,
35
- feature_set: mlrun.api.schemas.FeatureSet,
35
+ feature_set: mlrun.common.schemas.FeatureSet,
36
36
  versioned: bool = True,
37
37
  ) -> str:
38
+ if not feature_set.spec.engine:
39
+ feature_set.spec.engine = "storey"
40
+
38
41
  return self._create_object(
39
42
  db_session,
40
43
  project,
@@ -47,11 +50,14 @@ class FeatureStore(
47
50
  db_session: sqlalchemy.orm.Session,
48
51
  project: str,
49
52
  name: str,
50
- feature_set: mlrun.api.schemas.FeatureSet,
53
+ feature_set: mlrun.common.schemas.FeatureSet,
51
54
  tag: typing.Optional[str] = None,
52
55
  uid: typing.Optional[str] = None,
53
56
  versioned: bool = True,
54
57
  ) -> str:
58
+ if not feature_set.spec.engine:
59
+ feature_set.spec.engine = "storey"
60
+
55
61
  return self._store_object(
56
62
  db_session,
57
63
  project,
@@ -70,11 +76,11 @@ class FeatureStore(
70
76
  feature_set_patch: dict,
71
77
  tag: typing.Optional[str] = None,
72
78
  uid: typing.Optional[str] = None,
73
- patch_mode: mlrun.api.schemas.PatchMode = mlrun.api.schemas.PatchMode.replace,
79
+ patch_mode: mlrun.common.schemas.PatchMode = mlrun.common.schemas.PatchMode.replace,
74
80
  ) -> str:
75
81
  return self._patch_object(
76
82
  db_session,
77
- mlrun.api.schemas.FeatureSet,
83
+ mlrun.common.schemas.FeatureSet,
78
84
  project,
79
85
  name,
80
86
  feature_set_patch,
@@ -90,9 +96,9 @@ class FeatureStore(
90
96
  name: str,
91
97
  tag: typing.Optional[str] = None,
92
98
  uid: typing.Optional[str] = None,
93
- ) -> mlrun.api.schemas.FeatureSet:
99
+ ) -> mlrun.common.schemas.FeatureSet:
94
100
  return self._get_object(
95
- db_session, mlrun.api.schemas.FeatureSet, project, name, tag, uid
101
+ db_session, mlrun.common.schemas.FeatureSet, project, name, tag, uid
96
102
  )
97
103
 
98
104
  def list_feature_sets_tags(
@@ -104,7 +110,7 @@ class FeatureStore(
104
110
  :return: a list of Tuple of (project, feature_set.name, tag)
105
111
  """
106
112
  return self._list_object_type_tags(
107
- db_session, mlrun.api.schemas.FeatureSet, project
113
+ db_session, mlrun.common.schemas.FeatureSet, project
108
114
  )
109
115
 
110
116
  def list_feature_sets(
@@ -117,11 +123,11 @@ class FeatureStore(
117
123
  entities: typing.List[str] = None,
118
124
  features: typing.List[str] = None,
119
125
  labels: typing.List[str] = None,
120
- partition_by: mlrun.api.schemas.FeatureStorePartitionByField = None,
126
+ partition_by: mlrun.common.schemas.FeatureStorePartitionByField = None,
121
127
  rows_per_partition: int = 1,
122
- partition_sort_by: mlrun.api.schemas.SortField = None,
123
- partition_order: mlrun.api.schemas.OrderType = mlrun.api.schemas.OrderType.desc,
124
- ) -> mlrun.api.schemas.FeatureSetsOutput:
128
+ partition_sort_by: mlrun.common.schemas.SortField = None,
129
+ partition_order: mlrun.common.schemas.OrderType = mlrun.common.schemas.OrderType.desc,
130
+ ) -> mlrun.common.schemas.FeatureSetsOutput:
125
131
  project = project or mlrun.mlconf.default_project
126
132
  return mlrun.api.utils.singletons.db.get_db().list_feature_sets(
127
133
  db_session,
@@ -148,7 +154,7 @@ class FeatureStore(
148
154
  ):
149
155
  self._delete_object(
150
156
  db_session,
151
- mlrun.api.schemas.FeatureSet,
157
+ mlrun.common.schemas.FeatureSet,
152
158
  project,
153
159
  name,
154
160
  tag,
@@ -163,7 +169,7 @@ class FeatureStore(
163
169
  tag: typing.Optional[str] = None,
164
170
  entities: typing.List[str] = None,
165
171
  labels: typing.List[str] = None,
166
- ) -> mlrun.api.schemas.FeaturesOutput:
172
+ ) -> mlrun.common.schemas.FeaturesOutput:
167
173
  project = project or mlrun.mlconf.default_project
168
174
  return mlrun.api.utils.singletons.db.get_db().list_features(
169
175
  db_session,
@@ -181,7 +187,7 @@ class FeatureStore(
181
187
  name: str,
182
188
  tag: typing.Optional[str] = None,
183
189
  labels: typing.List[str] = None,
184
- ) -> mlrun.api.schemas.EntitiesOutput:
190
+ ) -> mlrun.common.schemas.EntitiesOutput:
185
191
  project = project or mlrun.mlconf.default_project
186
192
  return mlrun.api.utils.singletons.db.get_db().list_entities(
187
193
  db_session,
@@ -195,7 +201,7 @@ class FeatureStore(
195
201
  self,
196
202
  db_session: sqlalchemy.orm.Session,
197
203
  project: str,
198
- feature_vector: mlrun.api.schemas.FeatureVector,
204
+ feature_vector: mlrun.common.schemas.FeatureVector,
199
205
  versioned: bool = True,
200
206
  ) -> str:
201
207
  return self._create_object(db_session, project, feature_vector, versioned)
@@ -205,7 +211,7 @@ class FeatureStore(
205
211
  db_session: sqlalchemy.orm.Session,
206
212
  project: str,
207
213
  name: str,
208
- feature_vector: mlrun.api.schemas.FeatureVector,
214
+ feature_vector: mlrun.common.schemas.FeatureVector,
209
215
  tag: typing.Optional[str] = None,
210
216
  uid: typing.Optional[str] = None,
211
217
  versioned: bool = True,
@@ -228,11 +234,11 @@ class FeatureStore(
228
234
  feature_vector_patch: dict,
229
235
  tag: typing.Optional[str] = None,
230
236
  uid: typing.Optional[str] = None,
231
- patch_mode: mlrun.api.schemas.PatchMode = mlrun.api.schemas.PatchMode.replace,
237
+ patch_mode: mlrun.common.schemas.PatchMode = mlrun.common.schemas.PatchMode.replace,
232
238
  ) -> str:
233
239
  return self._patch_object(
234
240
  db_session,
235
- mlrun.api.schemas.FeatureVector,
241
+ mlrun.common.schemas.FeatureVector,
236
242
  project,
237
243
  name,
238
244
  feature_vector_patch,
@@ -248,10 +254,10 @@ class FeatureStore(
248
254
  name: str,
249
255
  tag: typing.Optional[str] = None,
250
256
  uid: typing.Optional[str] = None,
251
- ) -> mlrun.api.schemas.FeatureVector:
257
+ ) -> mlrun.common.schemas.FeatureVector:
252
258
  return self._get_object(
253
259
  db_session,
254
- mlrun.api.schemas.FeatureVector,
260
+ mlrun.common.schemas.FeatureVector,
255
261
  project,
256
262
  name,
257
263
  tag,
@@ -267,7 +273,7 @@ class FeatureStore(
267
273
  :return: a list of Tuple of (project, feature_vector.name, tag)
268
274
  """
269
275
  return self._list_object_type_tags(
270
- db_session, mlrun.api.schemas.FeatureVector, project
276
+ db_session, mlrun.common.schemas.FeatureVector, project
271
277
  )
272
278
 
273
279
  def list_feature_vectors(
@@ -278,11 +284,11 @@ class FeatureStore(
278
284
  tag: typing.Optional[str] = None,
279
285
  state: str = None,
280
286
  labels: typing.List[str] = None,
281
- partition_by: mlrun.api.schemas.FeatureStorePartitionByField = None,
287
+ partition_by: mlrun.common.schemas.FeatureStorePartitionByField = None,
282
288
  rows_per_partition: int = 1,
283
- partition_sort_by: mlrun.api.schemas.SortField = None,
284
- partition_order: mlrun.api.schemas.OrderType = mlrun.api.schemas.OrderType.desc,
285
- ) -> mlrun.api.schemas.FeatureVectorsOutput:
289
+ partition_sort_by: mlrun.common.schemas.SortField = None,
290
+ partition_order: mlrun.common.schemas.OrderType = mlrun.common.schemas.OrderType.desc,
291
+ ) -> mlrun.common.schemas.FeatureVectorsOutput:
286
292
  project = project or mlrun.mlconf.default_project
287
293
  return mlrun.api.utils.singletons.db.get_db().list_feature_vectors(
288
294
  db_session,
@@ -307,7 +313,7 @@ class FeatureStore(
307
313
  ):
308
314
  self._delete_object(
309
315
  db_session,
310
- mlrun.api.schemas.FeatureVector,
316
+ mlrun.common.schemas.FeatureVector,
311
317
  project,
312
318
  name,
313
319
  tag,
@@ -319,17 +325,17 @@ class FeatureStore(
319
325
  db_session: sqlalchemy.orm.Session,
320
326
  project: str,
321
327
  object_: typing.Union[
322
- mlrun.api.schemas.FeatureSet, mlrun.api.schemas.FeatureVector
328
+ mlrun.common.schemas.FeatureSet, mlrun.common.schemas.FeatureVector
323
329
  ],
324
330
  versioned: bool = True,
325
331
  ) -> str:
326
332
  project = project or mlrun.mlconf.default_project
327
333
  self._validate_and_enrich_identity_for_object_creation(project, object_)
328
- if isinstance(object_, mlrun.api.schemas.FeatureSet):
334
+ if isinstance(object_, mlrun.common.schemas.FeatureSet):
329
335
  return mlrun.api.utils.singletons.db.get_db().create_feature_set(
330
336
  db_session, project, object_, versioned
331
337
  )
332
- elif isinstance(object_, mlrun.api.schemas.FeatureVector):
338
+ elif isinstance(object_, mlrun.common.schemas.FeatureVector):
333
339
  return mlrun.api.utils.singletons.db.get_db().create_feature_vector(
334
340
  db_session, project, object_, versioned
335
341
  )
@@ -344,7 +350,7 @@ class FeatureStore(
344
350
  project: str,
345
351
  name: str,
346
352
  object_: typing.Union[
347
- mlrun.api.schemas.FeatureSet, mlrun.api.schemas.FeatureVector
353
+ mlrun.common.schemas.FeatureSet, mlrun.common.schemas.FeatureVector
348
354
  ],
349
355
  tag: typing.Optional[str] = None,
350
356
  uid: typing.Optional[str] = None,
@@ -354,7 +360,7 @@ class FeatureStore(
354
360
  self._validate_and_enrich_identity_for_object_store(
355
361
  object_, project, name, tag, uid
356
362
  )
357
- if isinstance(object_, mlrun.api.schemas.FeatureSet):
363
+ if isinstance(object_, mlrun.common.schemas.FeatureSet):
358
364
  return mlrun.api.utils.singletons.db.get_db().store_feature_set(
359
365
  db_session,
360
366
  project,
@@ -364,7 +370,7 @@ class FeatureStore(
364
370
  uid,
365
371
  versioned,
366
372
  )
367
- elif isinstance(object_, mlrun.api.schemas.FeatureVector):
373
+ elif isinstance(object_, mlrun.common.schemas.FeatureVector):
368
374
  return mlrun.api.utils.singletons.db.get_db().store_feature_vector(
369
375
  db_session,
370
376
  project,
@@ -388,7 +394,7 @@ class FeatureStore(
388
394
  object_patch: dict,
389
395
  tag: typing.Optional[str] = None,
390
396
  uid: typing.Optional[str] = None,
391
- patch_mode: mlrun.api.schemas.PatchMode = mlrun.api.schemas.PatchMode.replace,
397
+ patch_mode: mlrun.common.schemas.PatchMode = mlrun.common.schemas.PatchMode.replace,
392
398
  ) -> str:
393
399
  project = project or mlrun.mlconf.default_project
394
400
  self._validate_identity_for_object_patch(
@@ -399,7 +405,7 @@ class FeatureStore(
399
405
  tag,
400
406
  uid,
401
407
  )
402
- if object_schema.__name__ == mlrun.api.schemas.FeatureSet.__name__:
408
+ if object_schema.__name__ == mlrun.common.schemas.FeatureSet.__name__:
403
409
  return mlrun.api.utils.singletons.db.get_db().patch_feature_set(
404
410
  db_session,
405
411
  project,
@@ -409,7 +415,7 @@ class FeatureStore(
409
415
  uid,
410
416
  patch_mode,
411
417
  )
412
- elif object_schema.__name__ == mlrun.api.schemas.FeatureVector.__name__:
418
+ elif object_schema.__name__ == mlrun.common.schemas.FeatureVector.__name__:
413
419
  return mlrun.api.utils.singletons.db.get_db().patch_feature_vector(
414
420
  db_session,
415
421
  project,
@@ -432,13 +438,15 @@ class FeatureStore(
432
438
  name: str,
433
439
  tag: typing.Optional[str] = None,
434
440
  uid: typing.Optional[str] = None,
435
- ) -> typing.Union[mlrun.api.schemas.FeatureSet, mlrun.api.schemas.FeatureVector]:
441
+ ) -> typing.Union[
442
+ mlrun.common.schemas.FeatureSet, mlrun.common.schemas.FeatureVector
443
+ ]:
436
444
  project = project or mlrun.mlconf.default_project
437
- if object_schema.__name__ == mlrun.api.schemas.FeatureSet.__name__:
445
+ if object_schema.__name__ == mlrun.common.schemas.FeatureSet.__name__:
438
446
  return mlrun.api.utils.singletons.db.get_db().get_feature_set(
439
447
  db_session, project, name, tag, uid
440
448
  )
441
- elif object_schema.__name__ == mlrun.api.schemas.FeatureVector.__name__:
449
+ elif object_schema.__name__ == mlrun.common.schemas.FeatureVector.__name__:
442
450
  return mlrun.api.utils.singletons.db.get_db().get_feature_vector(
443
451
  db_session, project, name, tag, uid
444
452
  )
@@ -454,11 +462,11 @@ class FeatureStore(
454
462
  project: str,
455
463
  ) -> typing.List[typing.Tuple[str, str, str]]:
456
464
  project = project or mlrun.mlconf.default_project
457
- if object_schema.__name__ == mlrun.api.schemas.FeatureSet.__name__:
465
+ if object_schema.__name__ == mlrun.common.schemas.FeatureSet.__name__:
458
466
  return mlrun.api.utils.singletons.db.get_db().list_feature_sets_tags(
459
467
  db_session, project
460
468
  )
461
- elif object_schema.__name__ == mlrun.api.schemas.FeatureVector.__name__:
469
+ elif object_schema.__name__ == mlrun.common.schemas.FeatureVector.__name__:
462
470
  return mlrun.api.utils.singletons.db.get_db().list_feature_vectors_tags(
463
471
  db_session, project
464
472
  )
@@ -477,11 +485,11 @@ class FeatureStore(
477
485
  uid: typing.Optional[str] = None,
478
486
  ):
479
487
  project = project or mlrun.mlconf.default_project
480
- if object_schema.__name__ == mlrun.api.schemas.FeatureSet.__name__:
488
+ if object_schema.__name__ == mlrun.common.schemas.FeatureSet.__name__:
481
489
  mlrun.api.utils.singletons.db.get_db().delete_feature_set(
482
490
  db_session, project, name, tag, uid
483
491
  )
484
- elif object_schema.__name__ == mlrun.api.schemas.FeatureVector.__name__:
492
+ elif object_schema.__name__ == mlrun.common.schemas.FeatureVector.__name__:
485
493
  mlrun.api.utils.singletons.db.get_db().delete_feature_vector(
486
494
  db_session, project, name, tag, uid
487
495
  )
@@ -519,7 +527,7 @@ class FeatureStore(
519
527
  @staticmethod
520
528
  def _validate_and_enrich_identity_for_object_store(
521
529
  object_: typing.Union[
522
- mlrun.api.schemas.FeatureSet, mlrun.api.schemas.FeatureVector
530
+ mlrun.common.schemas.FeatureSet, mlrun.common.schemas.FeatureVector
523
531
  ],
524
532
  project: str,
525
533
  name: str,
@@ -550,7 +558,7 @@ class FeatureStore(
550
558
  def _validate_and_enrich_identity_for_object_creation(
551
559
  project: str,
552
560
  object_: typing.Union[
553
- mlrun.api.schemas.FeatureSet, mlrun.api.schemas.FeatureVector
561
+ mlrun.common.schemas.FeatureSet, mlrun.common.schemas.FeatureVector
554
562
  ],
555
563
  ):
556
564
  object_type = object_.__class__.__name__
@@ -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.
@@ -17,10 +17,10 @@ import typing
17
17
  import sqlalchemy.orm
18
18
 
19
19
  import mlrun.api.api.utils
20
- import mlrun.api.schemas
21
20
  import mlrun.api.utils.projects.remotes.follower
22
21
  import mlrun.api.utils.singletons.db
23
22
  import mlrun.api.utils.singletons.project_member
23
+ import mlrun.common.schemas
24
24
  import mlrun.config
25
25
  import mlrun.errors
26
26
  import mlrun.utils.singleton
@@ -37,7 +37,7 @@ class Functions(
37
37
  project: str = mlrun.mlconf.default_project,
38
38
  tag: str = "",
39
39
  versioned: bool = False,
40
- auth_info: mlrun.api.schemas.AuthInfo = None,
40
+ auth_info: mlrun.common.schemas.AuthInfo = None,
41
41
  ) -> str:
42
42
  project = project or mlrun.mlconf.default_project
43
43
  if auth_info:
mlrun/api/crud/hub.py ADDED
@@ -0,0 +1,312 @@
1
+ # Copyright 2023 Iguazio
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+ import json
16
+ from typing import Any, Dict, List, Optional, Tuple
17
+
18
+ import mlrun.api.utils.singletons.k8s
19
+ import mlrun.common.schemas
20
+ import mlrun.common.schemas.hub
21
+ import mlrun.errors
22
+ import mlrun.utils.singleton
23
+ from mlrun.config import config
24
+ from mlrun.datastore import store_manager
25
+
26
+ from .secrets import Secrets, SecretsClientType
27
+
28
+ # Using a complex separator, as it's less likely someone will use it in a real secret name
29
+ secret_name_separator = "-__-"
30
+
31
+
32
+ class Hub(metaclass=mlrun.utils.singleton.Singleton):
33
+ def __init__(self):
34
+ self._internal_project_name = config.hub.k8s_secrets_project_name
35
+ self._catalogs = {}
36
+
37
+ @staticmethod
38
+ def _in_k8s():
39
+ k8s_helper = mlrun.api.utils.singletons.k8s.get_k8s_helper()
40
+ return (
41
+ k8s_helper is not None and k8s_helper.is_running_inside_kubernetes_cluster()
42
+ )
43
+
44
+ @staticmethod
45
+ def _generate_credentials_secret_key(source, key=""):
46
+ full_key = source + secret_name_separator + key
47
+ return Secrets().generate_client_project_secret_key(
48
+ SecretsClientType.hub, full_key
49
+ )
50
+
51
+ def add_source(self, source: mlrun.common.schemas.hub.HubSource):
52
+ source_name = source.metadata.name
53
+ credentials = source.spec.credentials
54
+ if credentials:
55
+ self._store_source_credentials(source_name, credentials)
56
+
57
+ def remove_source(self, source_name):
58
+ self._catalogs.pop(source_name, None)
59
+ if not self._in_k8s():
60
+ return
61
+
62
+ source_credentials = self._get_source_credentials(source_name)
63
+ if not source_credentials:
64
+ return
65
+ secrets_to_delete = [
66
+ self._generate_credentials_secret_key(source_name, key)
67
+ for key in source_credentials
68
+ ]
69
+ Secrets().delete_project_secrets(
70
+ self._internal_project_name,
71
+ mlrun.common.schemas.SecretProviderName.kubernetes,
72
+ secrets_to_delete,
73
+ allow_internal_secrets=True,
74
+ )
75
+
76
+ def _store_source_credentials(self, source_name, credentials: dict):
77
+ if not self._in_k8s():
78
+ raise mlrun.errors.MLRunInvalidArgumentError(
79
+ "MLRun is not configured with k8s, hub source credentials cannot be stored securely"
80
+ )
81
+
82
+ adjusted_credentials = {
83
+ self._generate_credentials_secret_key(source_name, key): value
84
+ for key, value in credentials.items()
85
+ }
86
+ Secrets().store_project_secrets(
87
+ self._internal_project_name,
88
+ mlrun.common.schemas.SecretsData(
89
+ provider=mlrun.common.schemas.SecretProviderName.kubernetes,
90
+ secrets=adjusted_credentials,
91
+ ),
92
+ allow_internal_secrets=True,
93
+ )
94
+
95
+ def _get_source_credentials(self, source_name):
96
+ if not self._in_k8s():
97
+ return {}
98
+
99
+ secret_prefix = self._generate_credentials_secret_key(source_name)
100
+ secrets = (
101
+ Secrets()
102
+ .list_project_secrets(
103
+ self._internal_project_name,
104
+ mlrun.common.schemas.SecretProviderName.kubernetes,
105
+ allow_secrets_from_k8s=True,
106
+ allow_internal_secrets=True,
107
+ )
108
+ .secrets
109
+ )
110
+
111
+ source_secrets = {}
112
+ for key, value in secrets.items():
113
+ if key.startswith(secret_prefix):
114
+ source_secrets[key[len(secret_prefix) :]] = value
115
+
116
+ return source_secrets
117
+
118
+ @staticmethod
119
+ def _get_asset_full_path(
120
+ source: mlrun.common.schemas.hub.HubSource,
121
+ item: mlrun.common.schemas.hub.HubItem,
122
+ asset: str,
123
+ ):
124
+ """
125
+ Combining the item path with the asset path.
126
+
127
+ :param source: Hub source object.
128
+ :param item: The relevant item to get the asset from.
129
+ :param asset: The asset name
130
+ :return: Full path to the asset, relative to the item directory.
131
+ """
132
+ asset_path = item.spec.assets.get(asset, None)
133
+ if not asset_path:
134
+ raise mlrun.errors.MLRunNotFoundError(
135
+ f"Asset={asset} not found. "
136
+ f"item={item.metadata.name}, version={item.metadata.version}, tag={item.metadata.tag}"
137
+ )
138
+ item_path = item.metadata.get_relative_path()
139
+ return source.get_full_uri(item_path + asset_path)
140
+
141
+ @staticmethod
142
+ def _transform_catalog_dict_to_schema(
143
+ source: mlrun.common.schemas.hub.HubSource, catalog_dict: Dict[str, Any]
144
+ ) -> mlrun.common.schemas.hub.HubCatalog:
145
+ """
146
+ Transforms catalog dictionary to HubCatalog schema
147
+ :param source: Hub source object.
148
+ :param catalog_dict: raw catalog dict, top level keys are item names,
149
+ second level keys are version tags ("latest, "1.1.0", ...) and
150
+ bottom level keys include spec as a dict and all the rest is considered as metadata.
151
+ :return: catalog object
152
+ """
153
+ catalog = mlrun.common.schemas.hub.HubCatalog(
154
+ catalog=[], channel=source.spec.channel
155
+ )
156
+ # Loop over objects, then over object versions.
157
+ for object_name, object_dict in catalog_dict.items():
158
+ for version_tag, version_dict in object_dict.items():
159
+ object_details_dict = version_dict.copy()
160
+ spec_dict = object_details_dict.pop("spec", {})
161
+ assets = object_details_dict.pop("assets", {})
162
+ metadata = mlrun.common.schemas.hub.HubItemMetadata(
163
+ tag=version_tag, **object_details_dict
164
+ )
165
+ item_uri = source.get_full_uri(metadata.get_relative_path())
166
+ spec = mlrun.common.schemas.hub.HubItemSpec(
167
+ item_uri=item_uri, assets=assets, **spec_dict
168
+ )
169
+ item = mlrun.common.schemas.hub.HubItem(
170
+ metadata=metadata,
171
+ spec=spec,
172
+ status=mlrun.common.schemas.ObjectStatus(),
173
+ )
174
+ catalog.catalog.append(item)
175
+
176
+ return catalog
177
+
178
+ def get_source_catalog(
179
+ self,
180
+ source: mlrun.common.schemas.hub.HubSource,
181
+ version: Optional[str] = None,
182
+ tag: Optional[str] = None,
183
+ force_refresh: bool = False,
184
+ ) -> mlrun.common.schemas.hub.HubCatalog:
185
+ """
186
+ Getting the catalog object by source.
187
+ If version and/or tag are given, the catalog will be filtered accordingly.
188
+
189
+ :param source: Hub source object.
190
+ :param version: version of items to filter by
191
+ :param tag: tag of items to filter by
192
+ :param force_refresh: if True, the catalog will be loaded from source always,
193
+ otherwise will be pulled from db (if loaded before)
194
+ :return: catalog object
195
+ """
196
+ source_name = source.metadata.name
197
+ if not self._catalogs.get(source_name) or force_refresh:
198
+ url = source.get_catalog_uri()
199
+ credentials = self._get_source_credentials(source_name)
200
+ catalog_data = mlrun.run.get_object(url=url, secrets=credentials)
201
+ catalog_dict = json.loads(catalog_data)
202
+ catalog = self._transform_catalog_dict_to_schema(source, catalog_dict)
203
+ self._catalogs[source_name] = catalog
204
+ else:
205
+ catalog = self._catalogs[source_name]
206
+
207
+ result_catalog = mlrun.common.schemas.hub.HubCatalog(
208
+ catalog=[], channel=source.spec.channel
209
+ )
210
+ for item in catalog.catalog:
211
+ # Because tag and version are optionals,
212
+ # we filter the catalog by one of them with priority to tag
213
+ if (tag is None or item.metadata.tag == tag) and (
214
+ version is None or item.metadata.version == version
215
+ ):
216
+ result_catalog.catalog.append(item)
217
+
218
+ return result_catalog
219
+
220
+ def get_item(
221
+ self,
222
+ source: mlrun.common.schemas.hub.HubSource,
223
+ item_name: str,
224
+ version: Optional[str] = None,
225
+ tag: Optional[str] = None,
226
+ force_refresh: bool = False,
227
+ ) -> mlrun.common.schemas.hub.HubItem:
228
+ """
229
+ Retrieve item from source. The item is filtered by tag and version.
230
+
231
+ :param source: Hub source object
232
+ :param item_name: name of the item to retrieve
233
+ :param version: version of the item
234
+ :param tag: tag of the item
235
+ :param force_refresh: if True, the catalog will be loaded from source always,
236
+ otherwise will be pulled from db (if loaded before)
237
+
238
+ :return: hub item object
239
+
240
+ :raise if the number of collected items from catalog is not exactly one.
241
+ """
242
+ catalog = self.get_source_catalog(source, version, tag, force_refresh)
243
+ items = self._get_catalog_items_filtered_by_name(catalog.catalog, item_name)
244
+ num_items = len(items)
245
+
246
+ if not num_items:
247
+ raise mlrun.errors.MLRunNotFoundError(
248
+ f"Item not found. source={item_name}, version={version}"
249
+ )
250
+ if num_items > 1:
251
+ raise mlrun.errors.MLRunInvalidArgumentError(
252
+ "Query resulted in more than 1 catalog items. "
253
+ + f"source={item_name}, version={version}, tag={tag}"
254
+ )
255
+ return items[0]
256
+
257
+ @staticmethod
258
+ def _get_catalog_items_filtered_by_name(
259
+ catalog: List[mlrun.common.schemas.hub.HubItem],
260
+ item_name: str,
261
+ ) -> List[mlrun.common.schemas.hub.HubItem]:
262
+ """
263
+ Retrieve items from catalog filtered by name
264
+
265
+ :param catalog: list of items
266
+ :param item_name: item name to filter by
267
+
268
+ :return: list of item objects from catalog
269
+ """
270
+ return [item for item in catalog if item.metadata.name == item_name]
271
+
272
+ def get_item_object_using_source_credentials(
273
+ self, source: mlrun.common.schemas.hub.HubSource, url
274
+ ):
275
+ credentials = self._get_source_credentials(source.metadata.name)
276
+
277
+ if not url.startswith(source.spec.path):
278
+ raise mlrun.errors.MLRunInvalidArgumentError(
279
+ "URL to retrieve must be located in the source filesystem tree"
280
+ )
281
+
282
+ if url.endswith("/"):
283
+ obj = store_manager.object(url=url, secrets=credentials)
284
+ listdir = obj.listdir()
285
+ return {
286
+ "listdir": listdir,
287
+ }
288
+ else:
289
+ catalog_data = mlrun.run.get_object(url=url, secrets=credentials)
290
+ return catalog_data
291
+
292
+ def get_asset(
293
+ self,
294
+ source: mlrun.common.schemas.hub.HubSource,
295
+ item: mlrun.common.schemas.hub.HubItem,
296
+ asset_name: str,
297
+ ) -> Tuple[bytes, str]:
298
+ """
299
+ Retrieve asset object from hub source.
300
+
301
+ :param source: hub source
302
+ :param item: hub item which contains the assets
303
+ :param asset_name: asset name, like source, example, etc.
304
+
305
+ :return: tuple of asset as bytes and url of asset
306
+ """
307
+ credentials = self._get_source_credentials(source.metadata.name)
308
+ asset_path = self._get_asset_full_path(source, item, asset_name)
309
+ return (
310
+ mlrun.run.get_object(url=asset_path, secrets=credentials),
311
+ asset_path,
312
+ )