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 2019 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.
@@ -31,9 +31,10 @@ from sqlalchemy import (
31
31
  UniqueConstraint,
32
32
  )
33
33
  from sqlalchemy.ext.declarative import declarative_base
34
- from sqlalchemy.orm import class_mapper, relationship
34
+ from sqlalchemy.orm import relationship
35
35
 
36
- from mlrun.api import schemas
36
+ import mlrun.common.schemas
37
+ import mlrun.utils.db
37
38
  from mlrun.api.utils.db.sql_collation import SQLCollationUtil
38
39
 
39
40
  Base = declarative_base()
@@ -41,42 +42,8 @@ NULL = None # Avoid flake8 issuing warnings when comparing in filter
41
42
  run_time_fmt = "%Y-%m-%dT%H:%M:%S.%fZ"
42
43
 
43
44
 
44
- class BaseModel:
45
- def to_dict(self, exclude=None):
46
- """
47
- NOTE - this function (currently) does not handle serializing relationships
48
- """
49
- exclude = exclude or []
50
- mapper = class_mapper(self.__class__)
51
- columns = [column.key for column in mapper.columns if column.key not in exclude]
52
- get_key_value = (
53
- lambda c: (c, getattr(self, c).isoformat())
54
- if isinstance(getattr(self, c), datetime)
55
- else (c, getattr(self, c))
56
- )
57
- return dict(map(get_key_value, columns))
58
-
59
-
60
- class HasStruct(BaseModel):
61
- @property
62
- def struct(self):
63
- return pickle.loads(self.body)
64
-
65
- @struct.setter
66
- def struct(self, value):
67
- self.body = pickle.dumps(value)
68
-
69
- def to_dict(self, exclude=None):
70
- """
71
- NOTE - this function (currently) does not handle serializing relationships
72
- """
73
- exclude = exclude or []
74
- exclude.append("body")
75
- return super().to_dict(exclude)
76
-
77
-
78
45
  def make_label(table):
79
- class Label(Base, BaseModel):
46
+ class Label(Base, mlrun.utils.db.BaseModel):
80
47
  __tablename__ = f"{table}_labels"
81
48
  __table_args__ = (
82
49
  UniqueConstraint("name", "parent", name=f"_{table}_labels_uc"),
@@ -91,7 +58,7 @@ def make_label(table):
91
58
 
92
59
 
93
60
  def make_tag(table):
94
- class Tag(Base, BaseModel):
61
+ class Tag(Base, mlrun.utils.db.BaseModel):
95
62
  __tablename__ = f"{table}_tags"
96
63
  __table_args__ = (
97
64
  UniqueConstraint("project", "name", "obj_id", name=f"_{table}_tags_uc"),
@@ -108,7 +75,7 @@ def make_tag(table):
108
75
  # TODO: don't want to refactor everything in one PR so splitting this function to 2 versions - eventually only this one
109
76
  # should be used
110
77
  def make_tag_v2(table):
111
- class Tag(Base, BaseModel):
78
+ class Tag(Base, mlrun.utils.db.BaseModel):
112
79
  __tablename__ = f"{table}_tags"
113
80
  __table_args__ = (
114
81
  UniqueConstraint("project", "name", "obj_name", name=f"_{table}_tags_uc"),
@@ -126,11 +93,51 @@ def make_tag_v2(table):
126
93
  return Tag
127
94
 
128
95
 
96
+ def make_notification(table):
97
+ class Notification(Base, mlrun.utils.db.BaseModel):
98
+ __tablename__ = f"{table}_notifications"
99
+ __table_args__ = (
100
+ UniqueConstraint("name", "parent_id", name=f"_{table}_notifications_uc"),
101
+ )
102
+
103
+ id = Column(Integer, primary_key=True)
104
+ project = Column(String(255, collation=SQLCollationUtil.collation()))
105
+ name = Column(
106
+ String(255, collation=SQLCollationUtil.collation()), nullable=False
107
+ )
108
+ kind = Column(
109
+ String(255, collation=SQLCollationUtil.collation()), nullable=False
110
+ )
111
+ message = Column(
112
+ String(255, collation=SQLCollationUtil.collation()), nullable=False
113
+ )
114
+ severity = Column(
115
+ String(255, collation=SQLCollationUtil.collation()), nullable=False
116
+ )
117
+ when = Column(
118
+ String(255, collation=SQLCollationUtil.collation()), nullable=False
119
+ )
120
+ condition = Column(
121
+ String(255, collation=SQLCollationUtil.collation()), nullable=False
122
+ )
123
+ params = Column("params", JSON)
124
+ parent_id = Column(Integer, ForeignKey(f"{table}.id"))
125
+ sent_time = Column(
126
+ TIMESTAMP(),
127
+ nullable=True,
128
+ )
129
+ status = Column(
130
+ String(255, collation=SQLCollationUtil.collation()), nullable=False
131
+ )
132
+
133
+ return Notification
134
+
135
+
129
136
  # quell SQLAlchemy warnings on duplicate class name (Label)
130
137
  with warnings.catch_warnings():
131
138
  warnings.simplefilter("ignore")
132
139
 
133
- class Artifact(Base, HasStruct):
140
+ class Artifact(Base, mlrun.utils.db.HasStruct):
134
141
  __tablename__ = "artifacts"
135
142
  __table_args__ = (
136
143
  UniqueConstraint("uid", "project", "key", name="_artifacts_uc"),
@@ -144,14 +151,14 @@ with warnings.catch_warnings():
144
151
  project = Column(String(255, collation=SQLCollationUtil.collation()))
145
152
  uid = Column(String(255, collation=SQLCollationUtil.collation()))
146
153
  updated = Column(TIMESTAMP)
147
- # TODO: change to JSON, see mlrun/api/schemas/function.py::FunctionState for reasoning
154
+ # TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
148
155
  body = Column(BLOB)
149
156
  labels = relationship(Label)
150
157
 
151
158
  def get_identifier_string(self) -> str:
152
159
  return f"{self.project}/{self.key}/{self.uid}"
153
160
 
154
- class Function(Base, HasStruct):
161
+ class Function(Base, mlrun.utils.db.HasStruct):
155
162
  __tablename__ = "functions"
156
163
  __table_args__ = (
157
164
  UniqueConstraint("name", "project", "uid", name="_functions_uc"),
@@ -164,7 +171,7 @@ with warnings.catch_warnings():
164
171
  name = Column(String(255, collation=SQLCollationUtil.collation()))
165
172
  project = Column(String(255, collation=SQLCollationUtil.collation()))
166
173
  uid = Column(String(255, collation=SQLCollationUtil.collation()))
167
- # TODO: change to JSON, see mlrun/api/schemas/function.py::FunctionState for reasoning
174
+ # TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
168
175
  body = Column(BLOB)
169
176
  updated = Column(TIMESTAMP)
170
177
  labels = relationship(Label)
@@ -172,19 +179,19 @@ with warnings.catch_warnings():
172
179
  def get_identifier_string(self) -> str:
173
180
  return f"{self.project}/{self.name}/{self.uid}"
174
181
 
175
- class Log(Base, BaseModel):
182
+ class Log(Base, mlrun.utils.db.BaseModel):
176
183
  __tablename__ = "logs"
177
184
 
178
185
  id = Column(Integer, primary_key=True)
179
186
  uid = Column(String(255, collation=SQLCollationUtil.collation()))
180
187
  project = Column(String(255, collation=SQLCollationUtil.collation()))
181
- # TODO: change to JSON, see mlrun/api/schemas/function.py::FunctionState for reasoning
188
+ # TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
182
189
  body = Column(BLOB)
183
190
 
184
191
  def get_identifier_string(self) -> str:
185
192
  return f"{self.project}/{self.uid}"
186
193
 
187
- class Run(Base, HasStruct):
194
+ class Run(Base, mlrun.utils.db.HasStruct):
188
195
  __tablename__ = "runs"
189
196
  __table_args__ = (
190
197
  UniqueConstraint("uid", "project", "iteration", name="_runs_uc"),
@@ -192,6 +199,7 @@ with warnings.catch_warnings():
192
199
 
193
200
  Label = make_label(__tablename__)
194
201
  Tag = make_tag(__tablename__)
202
+ Notification = make_notification(__tablename__)
195
203
 
196
204
  id = Column(Integer, primary_key=True)
197
205
  uid = Column(String(255, collation=SQLCollationUtil.collation()))
@@ -201,7 +209,7 @@ with warnings.catch_warnings():
201
209
  )
202
210
  iteration = Column(Integer)
203
211
  state = Column(String(255, collation=SQLCollationUtil.collation()))
204
- # TODO: change to JSON, see mlrun/api/schemas/function.py::FunctionState for reasoning
212
+ # TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
205
213
  body = Column(BLOB)
206
214
  start_time = Column(TIMESTAMP)
207
215
  # requested logs column indicates whether logs were requested for this run
@@ -211,11 +219,12 @@ with warnings.catch_warnings():
211
219
  requested_logs = Column(BOOLEAN)
212
220
  updated = Column(TIMESTAMP, default=datetime.utcnow)
213
221
  labels = relationship(Label)
222
+ notifications = relationship(Notification, cascade="all, delete-orphan")
214
223
 
215
224
  def get_identifier_string(self) -> str:
216
225
  return f"{self.project}/{self.uid}/{self.iteration}"
217
226
 
218
- class BackgroundTask(Base, BaseModel):
227
+ class BackgroundTask(Base, mlrun.utils.db.BaseModel):
219
228
  __tablename__ = "background_tasks"
220
229
  __table_args__ = (
221
230
  UniqueConstraint("name", "project", name="_background_tasks_uc"),
@@ -233,7 +242,7 @@ with warnings.catch_warnings():
233
242
  state = Column(String(255, collation=SQLCollationUtil.collation()))
234
243
  timeout = Column(Integer)
235
244
 
236
- class Schedule(Base, BaseModel):
245
+ class Schedule(Base, mlrun.utils.db.BaseModel):
237
246
  __tablename__ = "schedules_v2"
238
247
  __table_args__ = (UniqueConstraint("project", "name", name="_schedules_v2_uc"),)
239
248
 
@@ -252,7 +261,7 @@ with warnings.catch_warnings():
252
261
  creation_time = Column(TIMESTAMP)
253
262
  cron_trigger_str = Column(String(255, collation=SQLCollationUtil.collation()))
254
263
  last_run_uri = Column(String(255, collation=SQLCollationUtil.collation()))
255
- # TODO: change to JSON, see mlrun/api/schemas/function.py::FunctionState for reasoning
264
+ # TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
256
265
  struct = Column(BLOB)
257
266
  labels = relationship(Label, cascade="all, delete-orphan")
258
267
  concurrency_limit = Column(Integer, nullable=False)
@@ -270,11 +279,11 @@ with warnings.catch_warnings():
270
279
  self.struct = pickle.dumps(value)
271
280
 
272
281
  @property
273
- def cron_trigger(self) -> schemas.ScheduleCronTrigger:
282
+ def cron_trigger(self) -> mlrun.common.schemas.ScheduleCronTrigger:
274
283
  return orjson.loads(self.cron_trigger_str)
275
284
 
276
285
  @cron_trigger.setter
277
- def cron_trigger(self, trigger: schemas.ScheduleCronTrigger):
286
+ def cron_trigger(self, trigger: mlrun.common.schemas.ScheduleCronTrigger):
278
287
  self.cron_trigger_str = orjson.dumps(trigger.dict(exclude_unset=True))
279
288
 
280
289
  # Define "many to many" users/projects
@@ -285,14 +294,14 @@ with warnings.catch_warnings():
285
294
  Column("user_id", Integer, ForeignKey("users.id")),
286
295
  )
287
296
 
288
- class User(Base, BaseModel):
297
+ class User(Base, mlrun.utils.db.BaseModel):
289
298
  __tablename__ = "users"
290
299
  __table_args__ = (UniqueConstraint("name", name="_users_uc"),)
291
300
 
292
301
  id = Column(Integer, primary_key=True)
293
302
  name = Column(String(255, collation=SQLCollationUtil.collation()))
294
303
 
295
- class Project(Base, BaseModel):
304
+ class Project(Base, mlrun.utils.db.BaseModel):
296
305
  __tablename__ = "projects"
297
306
  # For now since we use project name a lot
298
307
  __table_args__ = (UniqueConstraint("name", name="_projects_uc"),)
@@ -304,7 +313,7 @@ with warnings.catch_warnings():
304
313
  source = Column(String(255, collation=SQLCollationUtil.collation()))
305
314
  # the attribute name used to be _spec which is just a wrong naming, the attribute was renamed to _full_object
306
315
  # leaving the column as is to prevent redundant migration
307
- # TODO: change to JSON, see mlrun/api/schemas/function.py::FunctionState for reasoning
316
+ # TODO: change to JSON, see mlrun/common/schemas/function.py::FunctionState for reasoning
308
317
  _full_object = Column("spec", BLOB)
309
318
  created = Column(TIMESTAMP, default=datetime.utcnow)
310
319
  state = Column(String(255, collation=SQLCollationUtil.collation()))
@@ -326,7 +335,7 @@ with warnings.catch_warnings():
326
335
  def full_object(self, value):
327
336
  self._full_object = pickle.dumps(value)
328
337
 
329
- class Feature(Base, BaseModel):
338
+ class Feature(Base, mlrun.utils.db.BaseModel):
330
339
  __tablename__ = "features"
331
340
  id = Column(Integer, primary_key=True)
332
341
  feature_set_id = Column(Integer, ForeignKey("feature_sets.id"))
@@ -340,7 +349,7 @@ with warnings.catch_warnings():
340
349
  def get_identifier_string(self) -> str:
341
350
  return f"{self.project}/{self.name}"
342
351
 
343
- class Entity(Base, BaseModel):
352
+ class Entity(Base, mlrun.utils.db.BaseModel):
344
353
  __tablename__ = "entities"
345
354
  id = Column(Integer, primary_key=True)
346
355
  feature_set_id = Column(Integer, ForeignKey("feature_sets.id"))
@@ -354,7 +363,7 @@ with warnings.catch_warnings():
354
363
  def get_identifier_string(self) -> str:
355
364
  return f"{self.project}/{self.name}"
356
365
 
357
- class FeatureSet(Base, BaseModel):
366
+ class FeatureSet(Base, mlrun.utils.db.BaseModel):
358
367
  __tablename__ = "feature_sets"
359
368
  __table_args__ = (
360
369
  UniqueConstraint("name", "project", "uid", name="_feature_set_uc"),
@@ -390,7 +399,7 @@ with warnings.catch_warnings():
390
399
  def full_object(self, value):
391
400
  self._full_object = json.dumps(value, default=str)
392
401
 
393
- class FeatureVector(Base, BaseModel):
402
+ class FeatureVector(Base, mlrun.utils.db.BaseModel):
394
403
  __tablename__ = "feature_vectors"
395
404
  __table_args__ = (
396
405
  UniqueConstraint("name", "project", "uid", name="_feature_vectors_uc"),
@@ -423,9 +432,9 @@ with warnings.catch_warnings():
423
432
  def full_object(self, value):
424
433
  self._full_object = json.dumps(value, default=str)
425
434
 
426
- class MarketplaceSource(Base, BaseModel):
427
- __tablename__ = "marketplace_sources"
428
- __table_args__ = (UniqueConstraint("name", name="_marketplace_sources_uc"),)
435
+ class HubSource(Base, mlrun.utils.db.BaseModel):
436
+ __tablename__ = "hub_sources"
437
+ __table_args__ = (UniqueConstraint("name", name="_hub_sources_uc"),)
429
438
 
430
439
  id = Column(Integer, primary_key=True)
431
440
  name = Column(String(255, collation=SQLCollationUtil.collation()))
@@ -447,7 +456,7 @@ with warnings.catch_warnings():
447
456
  def full_object(self, value):
448
457
  self._full_object = json.dumps(value, default=str)
449
458
 
450
- class DataVersion(Base, BaseModel):
459
+ class DataVersion(Base, mlrun.utils.db.BaseModel):
451
460
  __tablename__ = "data_versions"
452
461
  __table_args__ = (UniqueConstraint("version", name="_versions_uc"),)
453
462
 
@@ -459,5 +468,8 @@ with warnings.catch_warnings():
459
468
  # Must be after all table definitions
460
469
  _tagged = [cls for cls in Base.__subclasses__() if hasattr(cls, "Tag")]
461
470
  _labeled = [cls for cls in Base.__subclasses__() if hasattr(cls, "Label")]
471
+ _with_notifications = [
472
+ cls for cls in Base.__subclasses__() if hasattr(cls, "Notification")
473
+ ]
462
474
  _classes = [cls for cls in Base.__subclasses__()]
463
475
  _table2cls = {cls.__table__.name: cls for cls in Base.__subclasses__()}
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,6 +12,9 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  #
15
+
16
+ import typing
17
+
15
18
  from sqlalchemy import create_engine
16
19
  from sqlalchemy.engine import Engine
17
20
  from sqlalchemy.orm import Session
@@ -19,35 +22,38 @@ from sqlalchemy.orm import sessionmaker as SessionMaker
19
22
 
20
23
  from mlrun.config import config
21
24
 
22
- engine: Engine = None
23
- _session_maker: SessionMaker = None
25
+ # TODO: wrap the following functions in a singleton class
26
+ _engines: typing.Dict[str, Engine] = {}
27
+ _session_makers: typing.Dict[str, SessionMaker] = {}
24
28
 
25
29
 
26
30
  # doing lazy load to allow tests to initialize the engine
27
- def get_engine() -> Engine:
28
- global engine
29
- if engine is None:
30
- _init_engine()
31
- return engine
31
+ def get_engine(dsn=None) -> Engine:
32
+ global _engines
33
+ dsn = dsn or config.httpdb.dsn
34
+ if dsn not in _engines:
35
+ _init_engine(dsn=dsn)
36
+ return _engines[dsn]
32
37
 
33
38
 
34
- def create_session() -> Session:
35
- session_maker = _get_session_maker()
39
+ def create_session(dsn=None) -> Session:
40
+ session_maker = _get_session_maker(dsn=dsn)
36
41
  return session_maker()
37
42
 
38
43
 
39
44
  # doing lazy load to allow tests to initialize the engine
40
- def _get_session_maker() -> SessionMaker:
41
- global _session_maker
42
- if _session_maker is None:
43
- _init_session_maker()
44
- return _session_maker
45
+ def _get_session_maker(dsn) -> SessionMaker:
46
+ global _session_makers
47
+ dsn = dsn or config.httpdb.dsn
48
+ if dsn not in _session_makers:
49
+ _init_session_maker(dsn=dsn)
50
+ return _session_makers[dsn]
45
51
 
46
52
 
47
53
  # TODO: we accept the dsn here to enable tests to override it, the "right" thing will be that config will be easily
48
54
  # overridable by tests (today when you import the config it is already being initialized.. should be lazy load)
49
55
  def _init_engine(dsn=None):
50
- global engine
56
+ global _engines
51
57
  dsn = dsn or config.httpdb.dsn
52
58
  kwargs = {}
53
59
  if "mysql" in dsn:
@@ -62,9 +68,10 @@ def _init_engine(dsn=None):
62
68
  "max_overflow": max_overflow,
63
69
  }
64
70
  engine = create_engine(dsn, **kwargs)
65
- _init_session_maker()
71
+ _engines[dsn] = engine
72
+ _init_session_maker(dsn=dsn)
66
73
 
67
74
 
68
- def _init_session_maker():
69
- global _session_maker
70
- _session_maker = SessionMaker(bind=get_engine())
75
+ def _init_session_maker(dsn):
76
+ global _session_makers
77
+ _session_makers[dsn] = SessionMaker(bind=get_engine(dsn=dsn))
mlrun/api/initial_data.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.
@@ -19,6 +19,7 @@ import pathlib
19
19
  import typing
20
20
 
21
21
  import dateutil.parser
22
+ import pydantic.error_wrappers
22
23
  import pymysql.err
23
24
  import sqlalchemy.exc
24
25
  import sqlalchemy.orm
@@ -26,12 +27,12 @@ import sqlalchemy.orm
26
27
  import mlrun.api.db.sqldb.db
27
28
  import mlrun.api.db.sqldb.helpers
28
29
  import mlrun.api.db.sqldb.models
29
- import mlrun.api.schemas
30
30
  import mlrun.api.utils.db.alembic
31
31
  import mlrun.api.utils.db.backup
32
32
  import mlrun.api.utils.db.mysql
33
33
  import mlrun.api.utils.db.sqlite_migration
34
34
  import mlrun.artifacts
35
+ import mlrun.common.schemas
35
36
  from mlrun.api.db.init_db import init_db
36
37
  from mlrun.api.db.session import close_session, create_session
37
38
  from mlrun.config import config
@@ -43,7 +44,20 @@ def init_data(
43
44
  from_scratch: bool = False, perform_migrations_if_needed: bool = False
44
45
  ) -> None:
45
46
  logger.info("Initializing DB data")
46
- mlrun.api.utils.db.mysql.MySQLUtil.wait_for_db_liveness(logger)
47
+
48
+ # create mysql util, and if mlrun is configured to use mysql, wait for it to be live and set its db modes
49
+ mysql_util = mlrun.api.utils.db.mysql.MySQLUtil(logger)
50
+ if mysql_util.get_mysql_dsn_data():
51
+ mysql_util.wait_for_db_liveness()
52
+ mysql_util.set_modes(mlrun.mlconf.httpdb.db.mysql.modes)
53
+ else:
54
+ dsn = mysql_util.get_dsn()
55
+ if "sqlite" in dsn:
56
+ logger.debug("SQLite DB is used, liveness check not needed")
57
+ else:
58
+ logger.warn(
59
+ f"Invalid mysql dsn: {dsn}, assuming live and skipping liveness verification"
60
+ )
47
61
 
48
62
  sqlite_migration_util = None
49
63
  if not from_scratch and config.httpdb.db.database_migration_mode == "enabled":
@@ -62,7 +76,7 @@ def init_data(
62
76
  and not perform_migrations_if_needed
63
77
  and is_migration_needed
64
78
  ):
65
- state = mlrun.api.schemas.APIStates.waiting_for_migrations
79
+ state = mlrun.common.schemas.APIStates.waiting_for_migrations
66
80
  logger.info("Migration is needed, changing API state", state=state)
67
81
  config.httpdb.state = state
68
82
  return
@@ -73,7 +87,7 @@ def init_data(
73
87
  db_backup.backup_database()
74
88
 
75
89
  logger.info("Creating initial data")
76
- config.httpdb.state = mlrun.api.schemas.APIStates.migrations_in_progress
90
+ config.httpdb.state = mlrun.common.schemas.APIStates.migrations_in_progress
77
91
 
78
92
  if is_migration_from_scratch or is_migration_needed:
79
93
  try:
@@ -81,15 +95,15 @@ def init_data(
81
95
 
82
96
  _perform_database_migration(sqlite_migration_util)
83
97
 
98
+ init_db()
84
99
  db_session = create_session()
85
100
  try:
86
- init_db(db_session)
87
101
  _add_initial_data(db_session)
88
102
  _perform_data_migrations(db_session)
89
103
  finally:
90
104
  close_session(db_session)
91
105
  except Exception:
92
- state = mlrun.api.schemas.APIStates.migrations_failed
106
+ state = mlrun.common.schemas.APIStates.migrations_failed
93
107
  logger.warning("Migrations failed, changing API state", state=state)
94
108
  config.httpdb.state = state
95
109
  raise
@@ -97,17 +111,19 @@ def init_data(
97
111
  # should happen - we can't do it here because it requires an asyncio loop which can't be accessible here
98
112
  # therefore moving to migration_completed state, and other component will take care of moving to online
99
113
  if not is_migration_from_scratch and is_migration_needed:
100
- config.httpdb.state = mlrun.api.schemas.APIStates.migrations_completed
114
+ config.httpdb.state = mlrun.common.schemas.APIStates.migrations_completed
101
115
  else:
102
- config.httpdb.state = mlrun.api.schemas.APIStates.online
116
+ config.httpdb.state = mlrun.common.schemas.APIStates.online
103
117
  logger.info("Initial data created")
104
118
 
105
119
 
106
120
  # If the data_table version doesn't exist, we can assume the data version is 1.
107
- # This is because data version 1 points to to a data migration which was added back in 0.6.0, and
121
+ # This is because data version 1 points to a data migration which was added back in 0.6.0, and
108
122
  # upgrading from a version earlier than 0.6.0 to v>=0.8.0 is not supported.
109
123
  data_version_prior_to_table_addition = 1
110
- latest_data_version = 2
124
+
125
+ # NOTE: Bump this number when adding a new data migration
126
+ latest_data_version = 3
111
127
 
112
128
 
113
129
  def _resolve_needed_operations(
@@ -212,13 +228,16 @@ def _perform_data_migrations(db_session: sqlalchemy.orm.Session):
212
228
  _perform_version_1_data_migrations(db, db_session)
213
229
  if current_data_version < 2:
214
230
  _perform_version_2_data_migrations(db, db_session)
231
+ if current_data_version < 3:
232
+ _perform_version_3_data_migrations(db, db_session)
233
+
215
234
  db.create_data_version(db_session, str(latest_data_version))
216
235
 
217
236
 
218
237
  def _add_initial_data(db_session: sqlalchemy.orm.Session):
219
238
  # FileDB is not really a thing anymore, so using SQLDB directly
220
239
  db = mlrun.api.db.sqldb.db.SQLDB("")
221
- _add_default_marketplace_source_if_needed(db, db_session)
240
+ _add_default_hub_source_if_needed(db, db_session)
222
241
  _add_data_version(db, db_session)
223
242
 
224
243
 
@@ -465,6 +484,30 @@ def _align_runs_table(
465
484
  db._upsert(db_session, [run], ignore=True)
466
485
 
467
486
 
487
+ def _perform_version_3_data_migrations(
488
+ db: mlrun.api.db.sqldb.db.SQLDB, db_session: sqlalchemy.orm.Session
489
+ ):
490
+ _rename_marketplace_kind_to_hub(db, db_session)
491
+
492
+
493
+ def _rename_marketplace_kind_to_hub(
494
+ db: mlrun.api.db.sqldb.db.SQLDB, db_session: sqlalchemy.orm.Session
495
+ ):
496
+ logger.info("Renaming 'Marketplace' kinds to 'Hub'")
497
+
498
+ hubs = db._list_hub_sources_without_transform(db_session)
499
+ for hub in hubs:
500
+ hub_dict = hub.full_object
501
+
502
+ # rename kind from "MarketplaceSource" to "HubSource"
503
+ if "Marketplace" in hub_dict.get("kind", ""):
504
+ hub_dict["kind"] = hub_dict["kind"].replace("Marketplace", "Hub")
505
+
506
+ # save the object back to the db
507
+ hub.full_object = hub_dict
508
+ db._upsert(db_session, [hub], ignore=True)
509
+
510
+
468
511
  def _perform_version_1_data_migrations(
469
512
  db: mlrun.api.db.sqldb.db.SQLDB, db_session: sqlalchemy.orm.Session
470
513
  ):
@@ -482,7 +525,7 @@ def _enrich_project_state(
482
525
  changed = False
483
526
  if not project.spec.desired_state:
484
527
  changed = True
485
- project.spec.desired_state = mlrun.api.schemas.ProjectState.online
528
+ project.spec.desired_state = mlrun.common.schemas.ProjectState.online
486
529
  if not project.status.state:
487
530
  changed = True
488
531
  project.status.state = project.spec.desired_state
@@ -494,32 +537,47 @@ def _enrich_project_state(
494
537
  db.store_project(db_session, project.metadata.name, project)
495
538
 
496
539
 
497
- def _add_default_marketplace_source_if_needed(
540
+ def _add_default_hub_source_if_needed(
498
541
  db: mlrun.api.db.sqldb.db.SQLDB, db_session: sqlalchemy.orm.Session
499
542
  ):
500
543
  try:
501
- hub_marketplace_source = db.get_marketplace_source(
502
- db_session, config.marketplace.default_source.name
544
+ hub_marketplace_source = db.get_hub_source(
545
+ db_session, config.hub.default_source.name
503
546
  )
504
547
  except mlrun.errors.MLRunNotFoundError:
505
548
  hub_marketplace_source = None
549
+ except pydantic.error_wrappers.ValidationError as exc:
550
+
551
+ # following the renaming of 'marketplace' to 'hub', validation errors can occur on the old 'marketplace'.
552
+ # this will be handled later in the data migrations, but for now - if a validation error occurs, we assume
553
+ # that a default hub source exists
554
+ if all(
555
+ [
556
+ "validation error for HubSource" in str(exc),
557
+ "value is not a valid enumeration member" in str(exc),
558
+ ]
559
+ ):
560
+ logger.info("Found existing default hub source, data migration needed")
561
+ hub_marketplace_source = True
562
+ else:
563
+ raise exc
506
564
 
507
565
  if not hub_marketplace_source:
508
- hub_source = mlrun.api.schemas.MarketplaceSource.generate_default_source()
509
- # hub_source will be None if the configuration has marketplace.default_source.create=False
566
+ hub_source = mlrun.common.schemas.HubSource.generate_default_source()
567
+ # hub_source will be None if the configuration has hub.default_source.create=False
510
568
  if hub_source:
511
- logger.info("Adding default marketplace source")
512
- # Not using db.store_marketplace_source() since it doesn't allow changing the default marketplace source.
513
- hub_record = db._transform_marketplace_source_schema_to_record(
514
- mlrun.api.schemas.IndexedMarketplaceSource(
515
- index=mlrun.api.schemas.marketplace.last_source_index,
569
+ logger.info("Adding default hub source")
570
+ # Not using db.store_marketplace_source() since it doesn't allow changing the default hub source.
571
+ hub_record = db._transform_hub_source_schema_to_record(
572
+ mlrun.common.schemas.IndexedHubSource(
573
+ index=mlrun.common.schemas.hub.last_source_index,
516
574
  source=hub_source,
517
575
  )
518
576
  )
519
577
  db_session.add(hub_record)
520
578
  db_session.commit()
521
579
  else:
522
- logger.info("Not adding default marketplace source, per configuration")
580
+ logger.info("Not adding default hub source, per configuration")
523
581
  return
524
582
 
525
583