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.
@@ -11,38 +11,36 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
-
14
+ import os.path
15
15
  import pathlib
16
16
  import re
17
- import tarfile
18
17
  import tempfile
18
+ import typing
19
19
  from base64 import b64decode, b64encode
20
20
  from os import path
21
21
  from urllib.parse import urlparse
22
22
 
23
23
  from kubernetes import client
24
24
 
25
- import mlrun.api.schemas
25
+ import mlrun.api.utils.singletons.k8s
26
+ import mlrun.common.constants
27
+ import mlrun.common.schemas
26
28
  import mlrun.errors
27
29
  import mlrun.runtimes.utils
28
-
29
- from .config import config
30
- from .datastore import store_manager
31
- from .k8s_utils import BasePod, get_k8s_helper
32
- from .utils import enrich_image_url, get_parsed_docker_registry, logger, normalize_name
33
-
34
- IMAGE_NAME_ENRICH_REGISTRY_PREFIX = "."
30
+ import mlrun.utils
31
+ from mlrun.config import config
32
+ from mlrun.utils.helpers import remove_image_protocol_prefix
35
33
 
36
34
 
37
35
  def make_dockerfile(
38
- base_image,
39
- commands=None,
40
- source=None,
41
- requirements=None,
42
- workdir="/mlrun",
43
- extra="",
44
- user_unix_id=None,
45
- enriched_group_id=None,
36
+ base_image: str,
37
+ commands: list = None,
38
+ source: str = None,
39
+ requirements_path: str = None,
40
+ workdir: str = "/mlrun",
41
+ extra: str = "",
42
+ user_unix_id: int = None,
43
+ enriched_group_id: int = None,
46
44
  ):
47
45
  dock = f"FROM {base_image}\n"
48
46
 
@@ -55,20 +53,20 @@ def make_dockerfile(
55
53
  dock += f"ARG {build_arg_key}={build_arg_value}\n"
56
54
 
57
55
  if source:
58
- dock += f"RUN mkdir -p {workdir}\n"
59
56
  dock += f"WORKDIR {workdir}\n"
60
57
  # 'ADD' command does not extract zip files - add extraction stage to the dockerfile
61
58
  if source.endswith(".zip"):
59
+ source_dir = os.path.join(workdir, "source")
62
60
  stage1 = f"""
63
61
  FROM {base_image} AS extractor
64
62
  RUN apt-get update -qqy && apt install --assume-yes unzip
65
- RUN mkdir -p /source
66
- COPY {source} /source
67
- RUN cd /source && unzip {source} && rm {source}
63
+ RUN mkdir -p {source_dir}
64
+ COPY {source} {source_dir}
65
+ RUN cd {source_dir} && unzip {source} && rm {source}
68
66
  """
69
67
  dock = stage1 + "\n" + dock
70
68
 
71
- dock += f"COPY --from=extractor /source/ {workdir}\n"
69
+ dock += f"COPY --from=extractor {source_dir}/ {workdir}\n"
72
70
  else:
73
71
  dock += f"ADD {source} {workdir}\n"
74
72
 
@@ -76,13 +74,16 @@ def make_dockerfile(
76
74
  dock += f"RUN chown -R {user_unix_id}:{enriched_group_id} {workdir}\n"
77
75
 
78
76
  dock += f"ENV PYTHONPATH {workdir}\n"
79
- if requirements:
80
- dock += f"RUN python -m pip install -r {requirements}\n"
81
77
  if commands:
82
78
  dock += "".join([f"RUN {command}\n" for command in commands])
79
+ if requirements_path:
80
+ dock += (
81
+ f"RUN echo 'Installing {requirements_path}...'; cat {requirements_path}\n"
82
+ )
83
+ dock += f"RUN python -m pip install -r {requirements_path}\n"
83
84
  if extra:
84
85
  dock += extra
85
- logger.debug("Resolved dockerfile", dockfile_contents=dock)
86
+ mlrun.utils.logger.debug("Resolved dockerfile", dockfile_contents=dock)
86
87
  return dock
87
88
 
88
89
 
@@ -95,6 +96,7 @@ def make_kaniko_pod(
95
96
  inline_code=None,
96
97
  inline_path=None,
97
98
  requirements=None,
99
+ requirements_path=None,
98
100
  secret_name=None,
99
101
  name="",
100
102
  verbose=False,
@@ -134,7 +136,16 @@ def make_kaniko_pod(
134
136
  if dockertext:
135
137
  dockerfile = "/empty/Dockerfile"
136
138
 
137
- args = ["--dockerfile", dockerfile, "--context", context, "--destination", dest]
139
+ args = [
140
+ "--dockerfile",
141
+ dockerfile,
142
+ "--context",
143
+ context,
144
+ "--destination",
145
+ dest,
146
+ "--image-fs-extract-retry",
147
+ config.httpdb.builder.kaniko_image_fs_extraction_retries,
148
+ ]
138
149
  for value, flag in [
139
150
  (config.httpdb.builder.insecure_pull_registry_mode, "--insecure-pull"),
140
151
  (config.httpdb.builder.insecure_push_registry_mode, "--insecure"),
@@ -158,7 +169,7 @@ def make_kaniko_pod(
158
169
  mem=default_requests.get("memory"), cpu=default_requests.get("cpu")
159
170
  )
160
171
  }
161
- kpod = BasePod(
172
+ kpod = mlrun.api.utils.singletons.k8s.BasePod(
162
173
  name or "mlrun-build",
163
174
  config.httpdb.builder.kaniko_image,
164
175
  args=args,
@@ -193,19 +204,23 @@ def make_kaniko_pod(
193
204
  commands = []
194
205
  env = {}
195
206
  if dockertext:
196
- commands.append("echo ${DOCKERFILE} | base64 -d > /empty/Dockerfile")
207
+ # set and encode docker content to the DOCKERFILE environment variable in the kaniko pod
197
208
  env["DOCKERFILE"] = b64encode(dockertext.encode("utf-8")).decode("utf-8")
209
+ # dump dockerfile content and decode to Dockerfile destination
210
+ commands.append("echo ${DOCKERFILE} | base64 -d > /empty/Dockerfile")
198
211
  if inline_code:
199
212
  name = inline_path or "main.py"
200
- commands.append("echo ${CODE} | base64 -d > /empty/" + name)
201
213
  env["CODE"] = b64encode(inline_code.encode("utf-8")).decode("utf-8")
214
+ commands.append("echo ${CODE} | base64 -d > /empty/" + name)
202
215
  if requirements:
203
- commands.append(
204
- "echo ${REQUIREMENTS} | base64 -d > /empty/requirements.txt"
205
- )
216
+ # set and encode requirements to the REQUIREMENTS environment variable in the kaniko pod
206
217
  env["REQUIREMENTS"] = b64encode(
207
218
  "\n".join(requirements).encode("utf-8")
208
219
  ).decode("utf-8")
220
+ # dump requirement content and decode to the requirement.txt destination
221
+ commands.append(
222
+ "echo ${REQUIREMENTS}" + " | " + f"base64 -d > {requirements_path}"
223
+ )
209
224
 
210
225
  kpod.append_init_container(
211
226
  config.httpdb.builder.kaniko_init_container_image,
@@ -221,7 +236,21 @@ def make_kaniko_pod(
221
236
  if end == -1:
222
237
  end = len(dest)
223
238
  repo = dest[dest.find("/") + 1 : end]
224
- configure_kaniko_ecr_init_container(kpod, registry, repo)
239
+
240
+ # if no secret is given, assume ec2 instance has attached role which provides read/write access to ECR
241
+ assume_instance_role = not config.httpdb.builder.docker_registry_secret
242
+ configure_kaniko_ecr_init_container(kpod, registry, repo, assume_instance_role)
243
+
244
+ # project secret might conflict with the attached instance role
245
+ # ensure "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY" have no values or else kaniko will fail
246
+ # due to credentials conflict / lack of permission on given credentials
247
+ if assume_instance_role:
248
+ kpod.pod.spec.containers[0].env.extend(
249
+ [
250
+ client.V1EnvVar(name="AWS_ACCESS_KEY_ID", value=""),
251
+ client.V1EnvVar(name="AWS_SECRET_ACCESS_KEY", value=""),
252
+ ]
253
+ )
225
254
 
226
255
  # mount regular docker config secret
227
256
  elif secret_name:
@@ -231,7 +260,9 @@ def make_kaniko_pod(
231
260
  return kpod
232
261
 
233
262
 
234
- def configure_kaniko_ecr_init_container(kpod, registry, repo):
263
+ def configure_kaniko_ecr_init_container(
264
+ kpod, registry, repo, assume_instance_role=True
265
+ ):
235
266
  region = registry.split(".")[3]
236
267
 
237
268
  # fail silently in order to ignore "repository already exists" errors
@@ -242,12 +273,13 @@ def configure_kaniko_ecr_init_container(kpod, registry, repo):
242
273
  )
243
274
  init_container_env = {}
244
275
 
245
- if not config.httpdb.builder.docker_registry_secret:
276
+ if assume_instance_role:
246
277
 
247
278
  # assume instance role has permissions to register and store a container image
248
279
  # https://github.com/GoogleContainerTools/kaniko#pushing-to-amazon-ecr
249
280
  # we only need this in the kaniko container
250
281
  kpod.env.append(client.V1EnvVar(name="AWS_SDK_LOAD_CONFIG", value="true"))
282
+
251
283
  else:
252
284
  aws_credentials_file_env_key = "AWS_SHARED_CREDENTIALS_FILE"
253
285
  aws_credentials_file_env_value = "/tmp/credentials"
@@ -278,24 +310,12 @@ def configure_kaniko_ecr_init_container(kpod, registry, repo):
278
310
  )
279
311
 
280
312
 
281
- def upload_tarball(source_dir, target, secrets=None):
282
-
283
- # will delete the temp file
284
- with tempfile.NamedTemporaryFile(suffix=".tar.gz") as temp_fh:
285
- with tarfile.open(mode="w:gz", fileobj=temp_fh) as tar:
286
- tar.add(source_dir, arcname="")
287
- stores = store_manager.set(secrets)
288
- datastore, subpath = stores.get_or_create_store(target)
289
- datastore.upload(subpath, temp_fh.name)
290
-
291
-
292
313
  def build_image(
293
- auth_info: mlrun.api.schemas.AuthInfo,
314
+ auth_info: mlrun.common.schemas.AuthInfo,
294
315
  project: str,
295
316
  image_target,
296
317
  commands=None,
297
318
  source="",
298
- mounter="v3io",
299
319
  base_image=None,
300
320
  requirements=None,
301
321
  inline_code=None,
@@ -315,43 +335,24 @@ def build_image(
315
335
  ):
316
336
  runtime_spec = runtime.spec if runtime else None
317
337
  builder_env = builder_env or {}
318
- image_target, secret_name = _resolve_image_target_and_registry_secret(
338
+ image_target, secret_name = resolve_image_target_and_registry_secret(
319
339
  image_target, registry, secret_name
320
340
  )
321
341
 
322
- if isinstance(requirements, list):
323
- requirements_list = requirements
324
- requirements_path = "requirements.txt"
325
- if source:
326
- raise ValueError("requirements list only works with inline code")
327
- else:
328
- requirements_list = None
329
- requirements_path = requirements
330
-
331
- commands = commands or []
332
- if with_mlrun:
333
- # mlrun prerequisite - upgrade pip
334
- upgrade_pip_command = resolve_upgrade_pip_command(commands)
335
- if upgrade_pip_command:
336
- commands.append(upgrade_pip_command)
337
-
338
- mlrun_command = resolve_mlrun_install_command(
339
- mlrun_version_specifier, client_version, commands
340
- )
341
- if mlrun_command:
342
- commands.append(mlrun_command)
342
+ commands, requirements_list, requirements_path = _resolve_build_requirements(
343
+ requirements, commands, with_mlrun, mlrun_version_specifier, client_version
344
+ )
343
345
 
344
- if not inline_code and not source and not commands:
345
- logger.info("skipping build, nothing to add")
346
+ if not inline_code and not source and not commands and not requirements:
347
+ mlrun.utils.logger.info("skipping build, nothing to add")
346
348
  return "skipped"
347
349
 
348
350
  context = "/context"
349
351
  to_mount = False
350
- v3io = (
351
- source.startswith("v3io://") or source.startswith("v3ios://")
352
- if source
353
- else None
354
- )
352
+ is_v3io_source = False
353
+ if source:
354
+ is_v3io_source = source.startswith("v3io://") or source.startswith("v3ios://")
355
+
355
356
  access_key = builder_env.get(
356
357
  "V3IO_ACCESS_KEY", auth_info.data_session or auth_info.access_key
357
358
  )
@@ -365,7 +366,8 @@ def build_image(
365
366
  if inline_code or runtime_spec.build.load_source_on_run or not source:
366
367
  context = "/empty"
367
368
 
368
- elif source and "://" in source and not v3io:
369
+ # source is remote
370
+ elif source and "://" in source and not is_v3io_source:
369
371
  if source.startswith("git://"):
370
372
  # if the user provided branch (w/o refs/..) we add the "refs/.."
371
373
  fragment = parsed_url.fragment or ""
@@ -376,19 +378,34 @@ def build_image(
376
378
  context = source
377
379
  source_to_copy = "."
378
380
 
381
+ # source is local / v3io
379
382
  else:
380
- if v3io:
383
+ if is_v3io_source:
381
384
  source = parsed_url.path
382
385
  to_mount = True
383
386
  source_dir_to_mount, source_to_copy = path.split(source)
384
- else:
387
+
388
+ # source is a path without a scheme, we allow to copy absolute paths assuming they are valid paths
389
+ # in the image, however, it is recommended to use `workdir` instead in such cases
390
+ # which is set during runtime (mlrun.runtimes.local.LocalRuntime._pre_run).
391
+ # relative paths are not supported at build time
392
+ # "." and "./" are considered as 'project context'
393
+ # TODO: enrich with project context if pulling on build time
394
+ elif path.isabs(source):
385
395
  source_to_copy = source
386
396
 
397
+ else:
398
+ raise mlrun.errors.MLRunInvalidArgumentError(
399
+ f"Load of relative source ({source}) is not supported at build time "
400
+ "see 'mlrun.runtimes.kubejob.KubejobRuntime.with_source_archive' or "
401
+ "'mlrun.projects.project.MlrunProject.set_source' for more details"
402
+ )
403
+
387
404
  user_unix_id = None
388
405
  enriched_group_id = None
389
406
  if (
390
407
  mlrun.mlconf.function.spec.security_context.enrichment_mode
391
- != mlrun.api.schemas.SecurityContextEnrichmentModes.disabled.value
408
+ != mlrun.common.schemas.SecurityContextEnrichmentModes.disabled.value
392
409
  ):
393
410
  from mlrun.api.api.utils import ensure_function_security_context
394
411
 
@@ -396,14 +413,29 @@ def build_image(
396
413
  user_unix_id = runtime.spec.security_context.run_as_user
397
414
  enriched_group_id = runtime.spec.security_context.run_as_group
398
415
 
416
+ if source_to_copy and (
417
+ not runtime.spec.clone_target_dir
418
+ or not os.path.isabs(runtime.spec.clone_target_dir)
419
+ ):
420
+ # use a temp dir for permissions and set it as the workdir
421
+ tmpdir = tempfile.mkdtemp()
422
+ relative_workdir = runtime.spec.clone_target_dir or ""
423
+ if relative_workdir.startswith("./"):
424
+ # TODO: use 'removeprefix' when we drop python 3.7 support
425
+ # relative_workdir.removeprefix("./")
426
+ relative_workdir = relative_workdir[2:]
427
+
428
+ runtime.spec.clone_target_dir = path.join(tmpdir, "mlrun", relative_workdir)
429
+
399
430
  dock = make_dockerfile(
400
431
  base_image,
401
432
  commands,
402
433
  source=source_to_copy,
403
- requirements=requirements_path,
434
+ requirements_path=requirements_path,
404
435
  extra=extra,
405
436
  user_unix_id=user_unix_id,
406
437
  enriched_group_id=enriched_group_id,
438
+ workdir=runtime.spec.clone_target_dir,
407
439
  )
408
440
 
409
441
  kpod = make_kaniko_pod(
@@ -414,6 +446,7 @@ def build_image(
414
446
  inline_code=inline_code,
415
447
  inline_path=inline_path,
416
448
  requirements=requirements_list,
449
+ requirements_path=requirements_path,
417
450
  secret_name=secret_name,
418
451
  name=name,
419
452
  verbose=verbose,
@@ -430,14 +463,16 @@ def build_image(
430
463
  user=username,
431
464
  )
432
465
 
433
- k8s = get_k8s_helper()
466
+ k8s = mlrun.api.utils.singletons.k8s.get_k8s_helper(silent=False)
434
467
  kpod.namespace = k8s.resolve_namespace(namespace)
435
468
 
436
469
  if interactive:
437
470
  return k8s.run_job(kpod)
438
471
  else:
439
472
  pod, ns = k8s.create_pod(kpod)
440
- logger.info(f'started build, to watch build logs use "mlrun watch {pod} {ns}"')
473
+ mlrun.utils.logger.info(
474
+ "Build started", pod=pod, namespace=ns, project=project, image=image_target
475
+ )
441
476
  return f"build:{pod}"
442
477
 
443
478
 
@@ -453,7 +488,7 @@ def get_kaniko_spec_attributes_from_runtime():
453
488
  ]
454
489
 
455
490
 
456
- def resolve_mlrun_install_command(
491
+ def resolve_mlrun_install_command_version(
457
492
  mlrun_version_specifier=None, client_version=None, commands=None
458
493
  ):
459
494
  commands = commands or []
@@ -483,7 +518,7 @@ def resolve_mlrun_install_command(
483
518
  mlrun_version_specifier = (
484
519
  f"{config.package_path}[complete]=={config.version}"
485
520
  )
486
- return f'python -m pip install "{mlrun_version_specifier}"'
521
+ return mlrun_version_specifier
487
522
 
488
523
 
489
524
  def resolve_upgrade_pip_command(commands=None):
@@ -497,7 +532,7 @@ def resolve_upgrade_pip_command(commands=None):
497
532
 
498
533
 
499
534
  def build_runtime(
500
- auth_info: mlrun.api.schemas.AuthInfo,
535
+ auth_info: mlrun.common.schemas.AuthInfo,
501
536
  runtime,
502
537
  with_mlrun=True,
503
538
  mlrun_version_specifier=None,
@@ -511,7 +546,7 @@ def build_runtime(
511
546
  namespace = runtime.metadata.namespace
512
547
  project = runtime.metadata.project
513
548
  if skip_deployed and runtime.is_deployed():
514
- runtime.status.state = mlrun.api.schemas.FunctionState.ready
549
+ runtime.status.state = mlrun.common.schemas.FunctionState.ready
515
550
  return True
516
551
  if build.base_image:
517
552
  mlrun_images = [
@@ -523,7 +558,13 @@ def build_runtime(
523
558
  # if the base is one of mlrun images - no need to install mlrun
524
559
  if any([image in build.base_image for image in mlrun_images]):
525
560
  with_mlrun = False
526
- if not build.source and not build.commands and not build.extra and not with_mlrun:
561
+ if (
562
+ not build.source
563
+ and not build.commands
564
+ and not build.requirements
565
+ and not build.extra
566
+ and not with_mlrun
567
+ ):
527
568
  if not runtime.spec.image:
528
569
  if build.base_image:
529
570
  runtime.spec.image = build.base_image
@@ -536,7 +577,7 @@ def build_runtime(
536
577
  "The deployment was not successful because no image was specified or there are missing build parameters"
537
578
  " (commands/source)"
538
579
  )
539
- runtime.status.state = mlrun.api.schemas.FunctionState.ready
580
+ runtime.status.state = mlrun.common.schemas.FunctionState.ready
540
581
  return True
541
582
 
542
583
  build.image = mlrun.runtimes.utils.resolve_function_image_name(runtime, build.image)
@@ -549,17 +590,23 @@ def build_runtime(
549
590
  raise mlrun.errors.MLRunInvalidArgumentError(
550
591
  "build spec must have a target image, set build.image = <target image>"
551
592
  )
552
- logger.info(f"building image ({build.image})")
593
+ name = mlrun.utils.normalize_name(f"mlrun-build-{runtime.metadata.name}")
553
594
 
554
- name = normalize_name(f"mlrun-build-{runtime.metadata.name}")
555
595
  base_image: str = (
556
596
  build.base_image or runtime.spec.image or config.default_base_image
557
597
  )
558
- enriched_base_image = enrich_image_url(
598
+ enriched_base_image = mlrun.utils.enrich_image_url(
559
599
  base_image,
560
600
  client_version,
561
601
  client_python_version,
562
602
  )
603
+ mlrun.utils.logger.info(
604
+ "Building runtime image",
605
+ base_image=enriched_base_image,
606
+ image=build.image,
607
+ project=project,
608
+ name=name,
609
+ )
563
610
 
564
611
  status = build_image(
565
612
  auth_info,
@@ -567,8 +614,8 @@ def build_runtime(
567
614
  image_target=build.image,
568
615
  base_image=enriched_base_image,
569
616
  commands=build.commands,
617
+ requirements=build.requirements,
570
618
  namespace=namespace,
571
- # inline_code=inline,
572
619
  source=build.source,
573
620
  secret_name=build.secret,
574
621
  interactive=interactive,
@@ -586,11 +633,11 @@ def build_runtime(
586
633
  # using enriched base image for the runtime spec image, because this will be the image that the function will
587
634
  # run with
588
635
  runtime.spec.image = enriched_base_image
589
- runtime.status.state = mlrun.api.schemas.FunctionState.ready
636
+ runtime.status.state = mlrun.common.schemas.FunctionState.ready
590
637
  return True
591
638
 
592
639
  if status.startswith("build:"):
593
- runtime.status.state = mlrun.api.schemas.FunctionState.deploying
640
+ runtime.status.state = mlrun.common.schemas.FunctionState.deploying
594
641
  runtime.status.build_pod = status[6:]
595
642
  # using the base_image, and not the enriched one so we won't have the client version in the image, useful for
596
643
  # exports and other cases where we don't want to have the client version in the image, but rather enriched on
@@ -598,48 +645,34 @@ def build_runtime(
598
645
  runtime.spec.build.base_image = base_image
599
646
  return False
600
647
 
601
- logger.info(f"build completed with {status}")
648
+ mlrun.utils.logger.info(f"build completed with {status}")
602
649
  if status in ["failed", "error"]:
603
- runtime.status.state = mlrun.api.schemas.FunctionState.error
650
+ runtime.status.state = mlrun.common.schemas.FunctionState.error
604
651
  return False
605
652
 
606
653
  local = "" if build.secret or build.image.startswith(".") else "."
607
654
  runtime.spec.image = local + build.image
608
- runtime.status.state = mlrun.api.schemas.FunctionState.ready
655
+ runtime.status.state = mlrun.common.schemas.FunctionState.ready
609
656
  return True
610
657
 
611
658
 
612
- def _generate_builder_env(project, builder_env):
613
- k8s = get_k8s_helper()
614
- secret_name = k8s.get_project_secret_name(project)
615
- existing_secret_keys = k8s.get_project_secret_keys(project, filter_internal=True)
616
-
617
- # generate env list from builder env and project secrets
618
- env = []
619
- for key in existing_secret_keys:
620
- if key not in builder_env:
621
- value_from = client.V1EnvVarSource(
622
- secret_key_ref=client.V1SecretKeySelector(name=secret_name, key=key)
623
- )
624
- env.append(client.V1EnvVar(name=key, value_from=value_from))
625
- for key, value in builder_env.items():
626
- env.append(client.V1EnvVar(name=key, value=value))
627
- return env
628
-
629
-
630
- def _resolve_image_target_and_registry_secret(
659
+ def resolve_image_target_and_registry_secret(
631
660
  image_target: str, registry: str = None, secret_name: str = None
632
661
  ) -> (str, str):
633
662
  if registry:
634
663
  return "/".join([registry, image_target]), secret_name
635
664
 
636
665
  # if dest starts with a dot, we add the configured registry to the start of the dest
637
- if image_target.startswith(IMAGE_NAME_ENRICH_REGISTRY_PREFIX):
666
+ if image_target.startswith(
667
+ mlrun.common.constants.IMAGE_NAME_ENRICH_REGISTRY_PREFIX
668
+ ):
638
669
 
639
670
  # remove prefix from image name
640
- image_target = image_target[len(IMAGE_NAME_ENRICH_REGISTRY_PREFIX) :]
671
+ image_target = image_target[
672
+ len(mlrun.common.constants.IMAGE_NAME_ENRICH_REGISTRY_PREFIX) :
673
+ ]
641
674
 
642
- registry, repository = get_parsed_docker_registry()
675
+ registry, repository = mlrun.utils.get_parsed_docker_registry()
643
676
  secret_name = secret_name or config.httpdb.builder.docker_registry_secret
644
677
  if not registry:
645
678
  raise ValueError(
@@ -652,4 +685,64 @@ def _resolve_image_target_and_registry_secret(
652
685
 
653
686
  return "/".join(image_target_components), secret_name
654
687
 
688
+ image_target = remove_image_protocol_prefix(image_target)
689
+
655
690
  return image_target, secret_name
691
+
692
+
693
+ def _generate_builder_env(project, builder_env):
694
+ k8s = mlrun.api.utils.singletons.k8s.get_k8s_helper(silent=False)
695
+ secret_name = k8s.get_project_secret_name(project)
696
+ existing_secret_keys = k8s.get_project_secret_keys(project, filter_internal=True)
697
+
698
+ # generate env list from builder env and project secrets
699
+ env = []
700
+ for key in existing_secret_keys:
701
+ if key not in builder_env:
702
+ value_from = client.V1EnvVarSource(
703
+ secret_key_ref=client.V1SecretKeySelector(name=secret_name, key=key)
704
+ )
705
+ env.append(client.V1EnvVar(name=key, value_from=value_from))
706
+ for key, value in builder_env.items():
707
+ env.append(client.V1EnvVar(name=key, value=value))
708
+ return env
709
+
710
+
711
+ def _resolve_build_requirements(
712
+ requirements: typing.Union[typing.List, str],
713
+ commands: typing.List,
714
+ with_mlrun: bool,
715
+ mlrun_version_specifier: typing.Optional[str],
716
+ client_version: typing.Optional[str],
717
+ ):
718
+ """
719
+ Resolve build requirements list, requirements path and commands.
720
+ If mlrun requirement is needed, we add a pip upgrade command to the commands list (prerequisite).
721
+ """
722
+ requirements_path = "/empty/requirements.txt"
723
+ if requirements and isinstance(requirements, list):
724
+ requirements_list = requirements
725
+ else:
726
+ requirements_list = []
727
+ requirements_path = requirements or requirements_path
728
+ commands = commands or []
729
+
730
+ if with_mlrun:
731
+ # mlrun prerequisite - upgrade pip
732
+ upgrade_pip_command = resolve_upgrade_pip_command(commands)
733
+ if upgrade_pip_command:
734
+ commands.append(upgrade_pip_command)
735
+
736
+ mlrun_version = resolve_mlrun_install_command_version(
737
+ mlrun_version_specifier, client_version, commands
738
+ )
739
+
740
+ # mlrun must be installed with other python requirements in the same pip command to avoid version conflicts
741
+ if mlrun_version:
742
+ requirements_list.insert(0, mlrun_version)
743
+
744
+ if not requirements_list:
745
+ # no requirements, we don't need a requirements file
746
+ requirements_path = ""
747
+
748
+ return commands, requirements_list, requirements_path
@@ -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.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -21,8 +21,8 @@ import urllib.parse
21
21
  import aiohttp
22
22
  import fastapi
23
23
 
24
- import mlrun.api.schemas
25
24
  import mlrun.api.utils.projects.remotes.follower
25
+ import mlrun.common.schemas
26
26
  import mlrun.errors
27
27
  import mlrun.utils.singleton
28
28
  from mlrun.utils import logger
@@ -157,7 +157,7 @@ class Client(
157
157
 
158
158
  async def get_clusterization_spec(
159
159
  self, return_fastapi_response: bool = True, raise_on_failure: bool = False
160
- ) -> typing.Union[fastapi.Response, mlrun.api.schemas.ClusterizationSpec]:
160
+ ) -> typing.Union[fastapi.Response, mlrun.common.schemas.ClusterizationSpec]:
161
161
  """
162
162
  This method is used both for proxying requests from worker to chief and for aligning the worker state
163
163
  with the clusterization spec brought from the chief
@@ -172,7 +172,22 @@ class Client(
172
172
  chief_response
173
173
  )
174
174
 
175
- return mlrun.api.schemas.ClusterizationSpec(**(await chief_response.json()))
175
+ return mlrun.common.schemas.ClusterizationSpec(
176
+ **(await chief_response.json())
177
+ )
178
+
179
+ async def set_schedule_notifications(
180
+ self, project: str, schedule_name: str, request: fastapi.Request, json: dict
181
+ ) -> fastapi.Response:
182
+ """
183
+ Schedules are running only on chief
184
+ """
185
+ return await self._proxy_request_to_chief(
186
+ "PUT",
187
+ f"projects/{project}/schedules/{schedule_name}/notifications",
188
+ request,
189
+ json,
190
+ )
176
191
 
177
192
  async def _proxy_request_to_chief(
178
193
  self,