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

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

Potentially problematic release.


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

Files changed (444) hide show
  1. mlrun/__init__.py +3 -3
  2. mlrun/__main__.py +79 -37
  3. mlrun/api/__init__.py +1 -1
  4. mlrun/api/api/__init__.py +1 -1
  5. mlrun/api/api/api.py +4 -4
  6. mlrun/api/api/deps.py +10 -21
  7. mlrun/api/api/endpoints/__init__.py +1 -1
  8. mlrun/api/api/endpoints/artifacts.py +64 -36
  9. mlrun/api/api/endpoints/auth.py +4 -4
  10. mlrun/api/api/endpoints/background_tasks.py +11 -11
  11. mlrun/api/api/endpoints/client_spec.py +5 -5
  12. mlrun/api/api/endpoints/clusterization_spec.py +6 -4
  13. mlrun/api/api/endpoints/feature_store.py +124 -115
  14. mlrun/api/api/endpoints/files.py +22 -14
  15. mlrun/api/api/endpoints/frontend_spec.py +28 -21
  16. mlrun/api/api/endpoints/functions.py +142 -87
  17. mlrun/api/api/endpoints/grafana_proxy.py +89 -442
  18. mlrun/api/api/endpoints/healthz.py +20 -7
  19. mlrun/api/api/endpoints/hub.py +320 -0
  20. mlrun/api/api/endpoints/internal/__init__.py +1 -1
  21. mlrun/api/api/endpoints/internal/config.py +1 -1
  22. mlrun/api/api/endpoints/internal/memory_reports.py +9 -9
  23. mlrun/api/api/endpoints/logs.py +11 -11
  24. mlrun/api/api/endpoints/model_endpoints.py +74 -70
  25. mlrun/api/api/endpoints/operations.py +13 -9
  26. mlrun/api/api/endpoints/pipelines.py +93 -88
  27. mlrun/api/api/endpoints/projects.py +35 -35
  28. mlrun/api/api/endpoints/runs.py +69 -27
  29. mlrun/api/api/endpoints/runtime_resources.py +28 -28
  30. mlrun/api/api/endpoints/schedules.py +98 -41
  31. mlrun/api/api/endpoints/secrets.py +37 -32
  32. mlrun/api/api/endpoints/submit.py +12 -12
  33. mlrun/api/api/endpoints/tags.py +20 -22
  34. mlrun/api/api/utils.py +251 -42
  35. mlrun/api/constants.py +1 -1
  36. mlrun/api/crud/__init__.py +18 -15
  37. mlrun/api/crud/artifacts.py +10 -10
  38. mlrun/api/crud/client_spec.py +4 -4
  39. mlrun/api/crud/clusterization_spec.py +3 -3
  40. mlrun/api/crud/feature_store.py +54 -46
  41. mlrun/api/crud/functions.py +3 -3
  42. mlrun/api/crud/hub.py +312 -0
  43. mlrun/api/crud/logs.py +11 -9
  44. mlrun/api/crud/model_monitoring/__init__.py +3 -3
  45. mlrun/api/crud/model_monitoring/grafana.py +435 -0
  46. mlrun/api/crud/model_monitoring/model_endpoints.py +352 -129
  47. mlrun/api/crud/notifications.py +149 -0
  48. mlrun/api/crud/pipelines.py +67 -52
  49. mlrun/api/crud/projects.py +51 -23
  50. mlrun/api/crud/runs.py +7 -5
  51. mlrun/api/crud/runtime_resources.py +13 -13
  52. mlrun/api/{db/filedb → crud/runtimes}/__init__.py +1 -1
  53. mlrun/api/crud/runtimes/nuclio/__init__.py +14 -0
  54. mlrun/api/crud/runtimes/nuclio/function.py +505 -0
  55. mlrun/api/crud/runtimes/nuclio/helpers.py +310 -0
  56. mlrun/api/crud/secrets.py +88 -46
  57. mlrun/api/crud/tags.py +5 -5
  58. mlrun/api/db/__init__.py +1 -1
  59. mlrun/api/db/base.py +102 -54
  60. mlrun/api/db/init_db.py +2 -3
  61. mlrun/api/db/session.py +4 -12
  62. mlrun/api/db/sqldb/__init__.py +1 -1
  63. mlrun/api/db/sqldb/db.py +439 -196
  64. mlrun/api/db/sqldb/helpers.py +1 -1
  65. mlrun/api/db/sqldb/models/__init__.py +3 -3
  66. mlrun/api/db/sqldb/models/models_mysql.py +82 -64
  67. mlrun/api/db/sqldb/models/models_sqlite.py +76 -64
  68. mlrun/api/db/sqldb/session.py +27 -20
  69. mlrun/api/initial_data.py +82 -24
  70. mlrun/api/launcher.py +196 -0
  71. mlrun/api/main.py +91 -22
  72. mlrun/api/middlewares.py +6 -5
  73. mlrun/api/migrations_mysql/env.py +1 -1
  74. mlrun/api/migrations_mysql/versions/28383af526f3_market_place_to_hub.py +40 -0
  75. mlrun/api/migrations_mysql/versions/32bae1b0e29c_increase_timestamp_fields_precision.py +1 -1
  76. mlrun/api/migrations_mysql/versions/4903aef6a91d_tag_foreign_key_and_cascades.py +1 -1
  77. mlrun/api/migrations_mysql/versions/5f1351c88a19_adding_background_tasks_table.py +1 -1
  78. mlrun/api/migrations_mysql/versions/88e656800d6a_add_requested_logs_column_and_index_to_.py +1 -1
  79. mlrun/api/migrations_mysql/versions/9d16de5f03a7_adding_data_versions_table.py +1 -1
  80. mlrun/api/migrations_mysql/versions/b86f5b53f3d7_adding_name_and_updated_to_runs_table.py +1 -1
  81. mlrun/api/migrations_mysql/versions/c4af40b0bf61_init.py +1 -1
  82. mlrun/api/migrations_mysql/versions/c905d15bd91d_notifications.py +72 -0
  83. mlrun/api/migrations_mysql/versions/ee041e8fdaa0_adding_next_run_time_column_to_schedule_.py +1 -1
  84. mlrun/api/migrations_sqlite/env.py +1 -1
  85. mlrun/api/migrations_sqlite/versions/11f8dd2dc9fe_init.py +1 -1
  86. mlrun/api/migrations_sqlite/versions/1c954f8cb32d_schedule_last_run_uri.py +1 -1
  87. mlrun/api/migrations_sqlite/versions/2b6d23c715aa_adding_feature_sets.py +1 -1
  88. mlrun/api/migrations_sqlite/versions/4acd9430b093_market_place_to_hub.py +77 -0
  89. mlrun/api/migrations_sqlite/versions/6401142f2d7c_adding_next_run_time_column_to_schedule_.py +1 -1
  90. mlrun/api/migrations_sqlite/versions/64d90a1a69bc_adding_background_tasks_table.py +1 -1
  91. mlrun/api/migrations_sqlite/versions/803438ecd005_add_requested_logs_column_to_runs.py +1 -1
  92. mlrun/api/migrations_sqlite/versions/863114f0c659_refactoring_feature_set.py +1 -1
  93. mlrun/api/migrations_sqlite/versions/959ae00528ad_notifications.py +63 -0
  94. mlrun/api/migrations_sqlite/versions/accf9fc83d38_adding_data_versions_table.py +1 -1
  95. mlrun/api/migrations_sqlite/versions/b68e8e897a28_schedule_labels.py +1 -1
  96. mlrun/api/migrations_sqlite/versions/bcd0c1f9720c_adding_project_labels.py +1 -1
  97. mlrun/api/migrations_sqlite/versions/cf21882f938e_schedule_id.py +1 -1
  98. mlrun/api/migrations_sqlite/versions/d781f58f607f_tag_object_name_string.py +1 -1
  99. mlrun/api/migrations_sqlite/versions/deac06871ace_adding_marketplace_sources_table.py +1 -1
  100. mlrun/api/migrations_sqlite/versions/e1dd5983c06b_schedule_concurrency_limit.py +1 -1
  101. mlrun/api/migrations_sqlite/versions/e5594ed3ab53_adding_name_and_updated_to_runs_table.py +1 -1
  102. mlrun/api/migrations_sqlite/versions/f4249b4ba6fa_adding_feature_vectors.py +1 -1
  103. mlrun/api/migrations_sqlite/versions/f7b5a1a03629_adding_feature_labels.py +1 -1
  104. mlrun/api/schemas/__init__.py +216 -138
  105. mlrun/api/utils/__init__.py +1 -1
  106. mlrun/api/utils/asyncio.py +1 -1
  107. mlrun/api/utils/auth/__init__.py +1 -1
  108. mlrun/api/utils/auth/providers/__init__.py +1 -1
  109. mlrun/api/utils/auth/providers/base.py +7 -7
  110. mlrun/api/utils/auth/providers/nop.py +6 -7
  111. mlrun/api/utils/auth/providers/opa.py +17 -17
  112. mlrun/api/utils/auth/verifier.py +36 -34
  113. mlrun/api/utils/background_tasks.py +24 -24
  114. mlrun/{builder.py → api/utils/builder.py} +216 -123
  115. mlrun/api/utils/clients/__init__.py +1 -1
  116. mlrun/api/utils/clients/chief.py +19 -4
  117. mlrun/api/utils/clients/iguazio.py +106 -60
  118. mlrun/api/utils/clients/log_collector.py +1 -1
  119. mlrun/api/utils/clients/nuclio.py +23 -23
  120. mlrun/api/utils/clients/protocols/grpc.py +2 -2
  121. mlrun/api/utils/db/__init__.py +1 -1
  122. mlrun/api/utils/db/alembic.py +1 -1
  123. mlrun/api/utils/db/backup.py +1 -1
  124. mlrun/api/utils/db/mysql.py +24 -25
  125. mlrun/api/utils/db/sql_collation.py +1 -1
  126. mlrun/api/utils/db/sqlite_migration.py +2 -2
  127. mlrun/api/utils/events/__init__.py +14 -0
  128. mlrun/api/utils/events/base.py +57 -0
  129. mlrun/api/utils/events/events_factory.py +41 -0
  130. mlrun/api/utils/events/iguazio.py +217 -0
  131. mlrun/api/utils/events/nop.py +55 -0
  132. mlrun/api/utils/helpers.py +16 -13
  133. mlrun/api/utils/memory_reports.py +1 -1
  134. mlrun/api/utils/periodic.py +6 -3
  135. mlrun/api/utils/projects/__init__.py +1 -1
  136. mlrun/api/utils/projects/follower.py +33 -33
  137. mlrun/api/utils/projects/leader.py +36 -34
  138. mlrun/api/utils/projects/member.py +27 -27
  139. mlrun/api/utils/projects/remotes/__init__.py +1 -1
  140. mlrun/api/utils/projects/remotes/follower.py +13 -13
  141. mlrun/api/utils/projects/remotes/leader.py +10 -10
  142. mlrun/api/utils/projects/remotes/nop_follower.py +27 -21
  143. mlrun/api/utils/projects/remotes/nop_leader.py +17 -16
  144. mlrun/api/utils/scheduler.py +140 -51
  145. mlrun/api/utils/singletons/__init__.py +1 -1
  146. mlrun/api/utils/singletons/db.py +9 -15
  147. mlrun/api/utils/singletons/k8s.py +677 -5
  148. mlrun/api/utils/singletons/logs_dir.py +1 -1
  149. mlrun/api/utils/singletons/project_member.py +1 -1
  150. mlrun/api/utils/singletons/scheduler.py +1 -1
  151. mlrun/artifacts/__init__.py +2 -2
  152. mlrun/artifacts/base.py +8 -2
  153. mlrun/artifacts/dataset.py +5 -3
  154. mlrun/artifacts/manager.py +7 -1
  155. mlrun/artifacts/model.py +15 -4
  156. mlrun/artifacts/plots.py +1 -1
  157. mlrun/common/__init__.py +1 -1
  158. mlrun/common/constants.py +15 -0
  159. mlrun/common/model_monitoring.py +209 -0
  160. mlrun/common/schemas/__init__.py +167 -0
  161. mlrun/{api → common}/schemas/artifact.py +13 -14
  162. mlrun/{api → common}/schemas/auth.py +10 -8
  163. mlrun/{api → common}/schemas/background_task.py +3 -3
  164. mlrun/{api → common}/schemas/client_spec.py +1 -1
  165. mlrun/{api → common}/schemas/clusterization_spec.py +3 -3
  166. mlrun/{api → common}/schemas/constants.py +21 -8
  167. mlrun/common/schemas/events.py +36 -0
  168. mlrun/{api → common}/schemas/feature_store.py +2 -1
  169. mlrun/{api → common}/schemas/frontend_spec.py +7 -6
  170. mlrun/{api → common}/schemas/function.py +5 -5
  171. mlrun/{api → common}/schemas/http.py +3 -3
  172. mlrun/common/schemas/hub.py +134 -0
  173. mlrun/{api → common}/schemas/k8s.py +3 -3
  174. mlrun/{api → common}/schemas/memory_reports.py +1 -1
  175. mlrun/common/schemas/model_endpoints.py +342 -0
  176. mlrun/common/schemas/notification.py +57 -0
  177. mlrun/{api → common}/schemas/object.py +6 -6
  178. mlrun/{api → common}/schemas/pipeline.py +3 -3
  179. mlrun/{api → common}/schemas/project.py +6 -5
  180. mlrun/common/schemas/regex.py +24 -0
  181. mlrun/common/schemas/runs.py +30 -0
  182. mlrun/{api → common}/schemas/runtime_resource.py +3 -3
  183. mlrun/{api → common}/schemas/schedule.py +19 -7
  184. mlrun/{api → common}/schemas/secret.py +3 -3
  185. mlrun/{api → common}/schemas/tag.py +2 -2
  186. mlrun/common/types.py +25 -0
  187. mlrun/config.py +152 -20
  188. mlrun/data_types/__init__.py +7 -2
  189. mlrun/data_types/data_types.py +4 -2
  190. mlrun/data_types/infer.py +1 -1
  191. mlrun/data_types/spark.py +10 -3
  192. mlrun/datastore/__init__.py +10 -3
  193. mlrun/datastore/azure_blob.py +1 -1
  194. mlrun/datastore/base.py +185 -53
  195. mlrun/datastore/datastore.py +1 -1
  196. mlrun/datastore/filestore.py +1 -1
  197. mlrun/datastore/google_cloud_storage.py +1 -1
  198. mlrun/datastore/inmem.py +4 -1
  199. mlrun/datastore/redis.py +1 -1
  200. mlrun/datastore/s3.py +1 -1
  201. mlrun/datastore/sources.py +192 -70
  202. mlrun/datastore/spark_udf.py +44 -0
  203. mlrun/datastore/store_resources.py +4 -4
  204. mlrun/datastore/targets.py +115 -45
  205. mlrun/datastore/utils.py +127 -5
  206. mlrun/datastore/v3io.py +1 -1
  207. mlrun/datastore/wasbfs/__init__.py +1 -1
  208. mlrun/datastore/wasbfs/fs.py +1 -1
  209. mlrun/db/__init__.py +7 -5
  210. mlrun/db/base.py +112 -68
  211. mlrun/db/httpdb.py +445 -277
  212. mlrun/db/nopdb.py +491 -0
  213. mlrun/db/sqldb.py +112 -65
  214. mlrun/errors.py +6 -1
  215. mlrun/execution.py +44 -22
  216. mlrun/feature_store/__init__.py +1 -1
  217. mlrun/feature_store/api.py +143 -95
  218. mlrun/feature_store/common.py +16 -20
  219. mlrun/feature_store/feature_set.py +42 -12
  220. mlrun/feature_store/feature_vector.py +32 -21
  221. mlrun/feature_store/ingestion.py +9 -12
  222. mlrun/feature_store/retrieval/__init__.py +3 -2
  223. mlrun/feature_store/retrieval/base.py +388 -66
  224. mlrun/feature_store/retrieval/dask_merger.py +63 -151
  225. mlrun/feature_store/retrieval/job.py +30 -12
  226. mlrun/feature_store/retrieval/local_merger.py +40 -133
  227. mlrun/feature_store/retrieval/spark_merger.py +129 -127
  228. mlrun/feature_store/retrieval/storey_merger.py +173 -0
  229. mlrun/feature_store/steps.py +132 -15
  230. mlrun/features.py +8 -3
  231. mlrun/frameworks/__init__.py +1 -1
  232. mlrun/frameworks/_common/__init__.py +1 -1
  233. mlrun/frameworks/_common/artifacts_library.py +1 -1
  234. mlrun/frameworks/_common/mlrun_interface.py +1 -1
  235. mlrun/frameworks/_common/model_handler.py +1 -1
  236. mlrun/frameworks/_common/plan.py +1 -1
  237. mlrun/frameworks/_common/producer.py +1 -1
  238. mlrun/frameworks/_common/utils.py +1 -1
  239. mlrun/frameworks/_dl_common/__init__.py +1 -1
  240. mlrun/frameworks/_dl_common/loggers/__init__.py +1 -1
  241. mlrun/frameworks/_dl_common/loggers/logger.py +1 -1
  242. mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +1 -1
  243. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +1 -1
  244. mlrun/frameworks/_dl_common/model_handler.py +1 -1
  245. mlrun/frameworks/_dl_common/utils.py +1 -1
  246. mlrun/frameworks/_ml_common/__init__.py +1 -1
  247. mlrun/frameworks/_ml_common/artifacts_library.py +1 -1
  248. mlrun/frameworks/_ml_common/loggers/__init__.py +1 -1
  249. mlrun/frameworks/_ml_common/loggers/logger.py +1 -1
  250. mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +1 -1
  251. mlrun/frameworks/_ml_common/model_handler.py +1 -1
  252. mlrun/frameworks/_ml_common/pkl_model_server.py +13 -1
  253. mlrun/frameworks/_ml_common/plan.py +1 -1
  254. mlrun/frameworks/_ml_common/plans/__init__.py +1 -1
  255. mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +1 -6
  256. mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +1 -1
  257. mlrun/frameworks/_ml_common/plans/dataset_plan.py +1 -1
  258. mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +1 -1
  259. mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +1 -1
  260. mlrun/frameworks/_ml_common/producer.py +1 -1
  261. mlrun/frameworks/_ml_common/utils.py +1 -1
  262. mlrun/frameworks/auto_mlrun/__init__.py +1 -1
  263. mlrun/frameworks/auto_mlrun/auto_mlrun.py +1 -1
  264. mlrun/frameworks/huggingface/__init__.py +1 -1
  265. mlrun/frameworks/huggingface/model_server.py +1 -1
  266. mlrun/frameworks/lgbm/__init__.py +1 -1
  267. mlrun/frameworks/lgbm/callbacks/__init__.py +1 -1
  268. mlrun/frameworks/lgbm/callbacks/callback.py +1 -1
  269. mlrun/frameworks/lgbm/callbacks/logging_callback.py +1 -1
  270. mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +1 -1
  271. mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -1
  272. mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -1
  273. mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +1 -1
  274. mlrun/frameworks/lgbm/mlrun_interfaces/model_mlrun_interface.py +1 -1
  275. mlrun/frameworks/lgbm/model_handler.py +1 -1
  276. mlrun/frameworks/lgbm/model_server.py +1 -1
  277. mlrun/frameworks/lgbm/utils.py +1 -1
  278. mlrun/frameworks/onnx/__init__.py +1 -1
  279. mlrun/frameworks/onnx/dataset.py +1 -1
  280. mlrun/frameworks/onnx/mlrun_interface.py +1 -1
  281. mlrun/frameworks/onnx/model_handler.py +1 -1
  282. mlrun/frameworks/onnx/model_server.py +1 -1
  283. mlrun/frameworks/parallel_coordinates.py +1 -1
  284. mlrun/frameworks/pytorch/__init__.py +1 -1
  285. mlrun/frameworks/pytorch/callbacks/__init__.py +1 -1
  286. mlrun/frameworks/pytorch/callbacks/callback.py +1 -1
  287. mlrun/frameworks/pytorch/callbacks/logging_callback.py +1 -1
  288. mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +1 -1
  289. mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +1 -1
  290. mlrun/frameworks/pytorch/callbacks_handler.py +1 -1
  291. mlrun/frameworks/pytorch/mlrun_interface.py +1 -1
  292. mlrun/frameworks/pytorch/model_handler.py +1 -1
  293. mlrun/frameworks/pytorch/model_server.py +1 -1
  294. mlrun/frameworks/pytorch/utils.py +1 -1
  295. mlrun/frameworks/sklearn/__init__.py +1 -1
  296. mlrun/frameworks/sklearn/estimator.py +1 -1
  297. mlrun/frameworks/sklearn/metric.py +1 -1
  298. mlrun/frameworks/sklearn/metrics_library.py +1 -1
  299. mlrun/frameworks/sklearn/mlrun_interface.py +1 -1
  300. mlrun/frameworks/sklearn/model_handler.py +1 -1
  301. mlrun/frameworks/sklearn/utils.py +1 -1
  302. mlrun/frameworks/tf_keras/__init__.py +1 -1
  303. mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -1
  304. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  305. mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +1 -1
  306. mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +1 -1
  307. mlrun/frameworks/tf_keras/mlrun_interface.py +1 -1
  308. mlrun/frameworks/tf_keras/model_handler.py +1 -1
  309. mlrun/frameworks/tf_keras/model_server.py +1 -1
  310. mlrun/frameworks/tf_keras/utils.py +1 -1
  311. mlrun/frameworks/xgboost/__init__.py +1 -1
  312. mlrun/frameworks/xgboost/mlrun_interface.py +1 -1
  313. mlrun/frameworks/xgboost/model_handler.py +1 -1
  314. mlrun/frameworks/xgboost/utils.py +1 -1
  315. mlrun/k8s_utils.py +14 -765
  316. mlrun/kfpops.py +14 -17
  317. mlrun/launcher/__init__.py +13 -0
  318. mlrun/launcher/base.py +406 -0
  319. mlrun/launcher/client.py +159 -0
  320. mlrun/launcher/factory.py +50 -0
  321. mlrun/launcher/local.py +276 -0
  322. mlrun/launcher/remote.py +178 -0
  323. mlrun/lists.py +10 -2
  324. mlrun/mlutils/__init__.py +1 -1
  325. mlrun/mlutils/data.py +1 -1
  326. mlrun/mlutils/models.py +1 -1
  327. mlrun/mlutils/plots.py +1 -1
  328. mlrun/model.py +252 -14
  329. mlrun/model_monitoring/__init__.py +41 -0
  330. mlrun/model_monitoring/features_drift_table.py +1 -1
  331. mlrun/model_monitoring/helpers.py +123 -38
  332. mlrun/model_monitoring/model_endpoint.py +144 -0
  333. mlrun/model_monitoring/model_monitoring_batch.py +310 -259
  334. mlrun/model_monitoring/stores/__init__.py +106 -0
  335. mlrun/model_monitoring/stores/kv_model_endpoint_store.py +448 -0
  336. mlrun/model_monitoring/stores/model_endpoint_store.py +147 -0
  337. mlrun/model_monitoring/stores/models/__init__.py +23 -0
  338. mlrun/model_monitoring/stores/models/base.py +18 -0
  339. mlrun/model_monitoring/stores/models/mysql.py +100 -0
  340. mlrun/model_monitoring/stores/models/sqlite.py +98 -0
  341. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +370 -0
  342. mlrun/model_monitoring/stream_processing_fs.py +239 -271
  343. mlrun/package/__init__.py +163 -0
  344. mlrun/package/context_handler.py +325 -0
  345. mlrun/package/errors.py +47 -0
  346. mlrun/package/packager.py +298 -0
  347. mlrun/{runtimes/package → package/packagers}/__init__.py +3 -1
  348. mlrun/package/packagers/default_packager.py +422 -0
  349. mlrun/package/packagers/numpy_packagers.py +612 -0
  350. mlrun/package/packagers/pandas_packagers.py +968 -0
  351. mlrun/package/packagers/python_standard_library_packagers.py +616 -0
  352. mlrun/package/packagers_manager.py +786 -0
  353. mlrun/package/utils/__init__.py +53 -0
  354. mlrun/package/utils/_archiver.py +226 -0
  355. mlrun/package/utils/_formatter.py +211 -0
  356. mlrun/package/utils/_pickler.py +234 -0
  357. mlrun/package/utils/_supported_format.py +71 -0
  358. mlrun/package/utils/log_hint_utils.py +93 -0
  359. mlrun/package/utils/type_hint_utils.py +298 -0
  360. mlrun/platforms/__init__.py +1 -1
  361. mlrun/platforms/iguazio.py +34 -2
  362. mlrun/platforms/other.py +1 -1
  363. mlrun/projects/__init__.py +1 -1
  364. mlrun/projects/operations.py +14 -9
  365. mlrun/projects/pipelines.py +31 -13
  366. mlrun/projects/project.py +762 -238
  367. mlrun/render.py +49 -19
  368. mlrun/run.py +57 -326
  369. mlrun/runtimes/__init__.py +3 -9
  370. mlrun/runtimes/base.py +247 -784
  371. mlrun/runtimes/constants.py +1 -1
  372. mlrun/runtimes/daskjob.py +45 -41
  373. mlrun/runtimes/funcdoc.py +43 -7
  374. mlrun/runtimes/function.py +66 -656
  375. mlrun/runtimes/function_reference.py +1 -1
  376. mlrun/runtimes/generators.py +1 -1
  377. mlrun/runtimes/kubejob.py +99 -116
  378. mlrun/runtimes/local.py +59 -66
  379. mlrun/runtimes/mpijob/__init__.py +1 -1
  380. mlrun/runtimes/mpijob/abstract.py +13 -15
  381. mlrun/runtimes/mpijob/v1.py +3 -1
  382. mlrun/runtimes/mpijob/v1alpha1.py +1 -1
  383. mlrun/runtimes/nuclio.py +1 -1
  384. mlrun/runtimes/pod.py +51 -26
  385. mlrun/runtimes/remotesparkjob.py +3 -1
  386. mlrun/runtimes/serving.py +12 -4
  387. mlrun/runtimes/sparkjob/__init__.py +1 -2
  388. mlrun/runtimes/sparkjob/abstract.py +44 -31
  389. mlrun/runtimes/sparkjob/spark3job.py +11 -9
  390. mlrun/runtimes/utils.py +61 -42
  391. mlrun/secrets.py +16 -18
  392. mlrun/serving/__init__.py +3 -2
  393. mlrun/serving/merger.py +1 -1
  394. mlrun/serving/remote.py +1 -1
  395. mlrun/serving/routers.py +39 -42
  396. mlrun/serving/server.py +23 -13
  397. mlrun/serving/serving_wrapper.py +1 -1
  398. mlrun/serving/states.py +172 -39
  399. mlrun/serving/utils.py +1 -1
  400. mlrun/serving/v1_serving.py +1 -1
  401. mlrun/serving/v2_serving.py +29 -21
  402. mlrun/utils/__init__.py +1 -2
  403. mlrun/utils/async_http.py +8 -1
  404. mlrun/utils/azure_vault.py +1 -1
  405. mlrun/utils/clones.py +2 -2
  406. mlrun/utils/condition_evaluator.py +65 -0
  407. mlrun/utils/db.py +52 -0
  408. mlrun/utils/helpers.py +188 -13
  409. mlrun/utils/http.py +89 -54
  410. mlrun/utils/logger.py +48 -8
  411. mlrun/utils/model_monitoring.py +132 -100
  412. mlrun/utils/notifications/__init__.py +1 -1
  413. mlrun/utils/notifications/notification/__init__.py +8 -6
  414. mlrun/utils/notifications/notification/base.py +20 -14
  415. mlrun/utils/notifications/notification/console.py +7 -4
  416. mlrun/utils/notifications/notification/git.py +36 -19
  417. mlrun/utils/notifications/notification/ipython.py +10 -8
  418. mlrun/utils/notifications/notification/slack.py +18 -13
  419. mlrun/utils/notifications/notification_pusher.py +377 -56
  420. mlrun/utils/regex.py +6 -1
  421. mlrun/utils/singleton.py +1 -1
  422. mlrun/utils/v3io_clients.py +1 -1
  423. mlrun/utils/vault.py +270 -269
  424. mlrun/utils/version/__init__.py +1 -1
  425. mlrun/utils/version/version.json +2 -2
  426. mlrun/utils/version/version.py +1 -1
  427. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/METADATA +16 -10
  428. mlrun-1.4.0.dist-info/RECORD +434 -0
  429. mlrun/api/api/endpoints/marketplace.py +0 -257
  430. mlrun/api/crud/marketplace.py +0 -221
  431. mlrun/api/crud/model_monitoring/model_endpoint_store.py +0 -847
  432. mlrun/api/db/filedb/db.py +0 -518
  433. mlrun/api/schemas/marketplace.py +0 -128
  434. mlrun/api/schemas/model_endpoints.py +0 -185
  435. mlrun/db/filedb.py +0 -891
  436. mlrun/feature_store/retrieval/online.py +0 -92
  437. mlrun/model_monitoring/constants.py +0 -67
  438. mlrun/runtimes/package/context_handler.py +0 -711
  439. mlrun/runtimes/sparkjob/spark2job.py +0 -59
  440. mlrun-1.3.3.dist-info/RECORD +0 -381
  441. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/LICENSE +0 -0
  442. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/WHEEL +0 -0
  443. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/entry_points.txt +0 -0
  444. {mlrun-1.3.3.dist-info → mlrun-1.4.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Iguazio
1
+ # Copyright 2023 Iguazio
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -16,10 +16,8 @@ import asyncio
16
16
  import json
17
17
  import typing
18
18
  import warnings
19
- from base64 import b64encode
20
19
  from datetime import datetime
21
20
  from time import sleep
22
- from urllib.parse import urlparse
23
21
 
24
22
  import nuclio
25
23
  import nuclio.utils
@@ -31,15 +29,13 @@ from nuclio.deploy import find_dashboard_url, get_deploy_status
31
29
  from nuclio.triggers import V3IOStreamTrigger
32
30
 
33
31
  import mlrun.errors
32
+ import mlrun.k8s_utils
34
33
  import mlrun.utils
35
- from mlrun.datastore import parse_s3_bucket_and_key
34
+ from mlrun.common.schemas import AuthInfo
36
35
  from mlrun.db import RunDBError
37
36
 
38
- from ..api.schemas import AuthInfo
39
37
  from ..config import config as mlconf
40
- from ..config import is_running_as_api
41
38
  from ..errors import err_to_str
42
- from ..k8s_utils import get_k8s_helper
43
39
  from ..kfpops import deploy_op
44
40
  from ..lists import RunList
45
41
  from ..model import RunObject
@@ -50,9 +46,8 @@ from ..platforms.iguazio import (
50
46
  split_path,
51
47
  v3io_cred,
52
48
  )
53
- from ..utils import as_number, enrich_image_url, get_in, logger, update_in
49
+ from ..utils import get_in, logger, update_in
54
50
  from .base import FunctionStatus, RunError
55
- from .constants import NuclioIngressAddTemplatedIngressModes
56
51
  from .pod import KubeResource, KubeResourceSpec
57
52
  from .utils import get_item_name, log_std
58
53
 
@@ -138,9 +133,12 @@ class NuclioSpec(KubeResourceSpec):
138
133
  "source",
139
134
  "function_kind",
140
135
  "readiness_timeout",
136
+ "readiness_timeout_before_failure",
141
137
  "function_handler",
142
138
  "nuclio_runtime",
143
139
  "base_image_pull",
140
+ "service_type",
141
+ "add_templated_ingress_host_mode",
144
142
  ]
145
143
 
146
144
  def __init__(
@@ -167,6 +165,7 @@ class NuclioSpec(KubeResourceSpec):
167
165
  build=None,
168
166
  service_account=None,
169
167
  readiness_timeout=None,
168
+ readiness_timeout_before_failure=None,
170
169
  default_handler=None,
171
170
  node_name=None,
172
171
  node_selector=None,
@@ -179,6 +178,9 @@ class NuclioSpec(KubeResourceSpec):
179
178
  tolerations=None,
180
179
  preemption_mode=None,
181
180
  security_context=None,
181
+ service_type=None,
182
+ add_templated_ingress_host_mode=None,
183
+ clone_target_dir=None,
182
184
  ):
183
185
 
184
186
  super().__init__(
@@ -208,6 +210,7 @@ class NuclioSpec(KubeResourceSpec):
208
210
  tolerations=tolerations,
209
211
  preemption_mode=preemption_mode,
210
212
  security_context=security_context,
213
+ clone_target_dir=clone_target_dir,
211
214
  )
212
215
 
213
216
  self.base_spec = base_spec or {}
@@ -218,6 +221,9 @@ class NuclioSpec(KubeResourceSpec):
218
221
  self.nuclio_runtime = None
219
222
  self.no_cache = no_cache
220
223
  self.readiness_timeout = readiness_timeout
224
+ self.readiness_timeout_before_failure = readiness_timeout_before_failure
225
+ self.service_type = service_type
226
+ self.add_templated_ingress_host_mode = add_templated_ingress_host_mode
221
227
 
222
228
  self.min_replicas = min_replicas or 1
223
229
  self.max_replicas = max_replicas or 4
@@ -560,66 +566,39 @@ class RemoteRuntime(KubeResource):
560
566
  if tag:
561
567
  self.metadata.tag = tag
562
568
 
563
- save_record = False
564
- if not dashboard:
565
- # Attempt auto-mounting, before sending to remote build
566
- self.try_auto_mount_based_on_config()
567
- self._fill_credentials()
568
- db = self._get_db()
569
- logger.info("Starting remote function deploy")
570
- data = db.remote_builder(self, False, builder_env=builder_env)
571
- self.status = data["data"].get("status")
572
- self._update_credentials_from_remote_build(data["data"])
573
-
574
- # when a function is deployed, we wait for it to be ready by default
575
- # this also means that the function object will be updated with the function status
576
- self._wait_for_function_deployment(db, verbose=verbose)
577
-
578
- # NOTE: on older mlrun versions & nuclio versions, function are exposed via NodePort
579
- # now, functions can be not exposed (using service type ClusterIP) and hence
580
- # for BC we first try to populate the external invocation url, and then
581
- # if not exists, take the internal invocation url
582
- if self.status.external_invocation_urls:
583
- self.spec.command = f"http://{self.status.external_invocation_urls[0]}"
584
- save_record = True
585
- elif self.status.internal_invocation_urls:
586
- self.spec.command = f"http://{self.status.internal_invocation_urls[0]}"
587
- save_record = True
588
- elif self.status.address:
589
- self.spec.command = f"http://{self.status.address}"
590
- save_record = True
591
-
592
- else:
593
-
569
+ if dashboard:
594
570
  warnings.warn(
595
- "'dashboard' is deprecated in 1.3.0, and will be removed in 1.5.0, "
596
- "Keep 'dashboard' value empty to allow auto-detection by MLRun API.",
597
- # TODO: Remove in 1.5.0
598
- FutureWarning,
571
+ "'dashboard' parameter is no longer supported on client side, "
572
+ "it is being configured through the MLRun API.",
599
573
  )
600
574
 
601
- self.save(versioned=False)
602
- self._ensure_run_db()
603
- internal_invocation_urls, external_invocation_urls = deploy_nuclio_function(
604
- self,
605
- dashboard=dashboard,
606
- watch=True,
607
- auth_info=auth_info,
608
- )
609
- self.status.internal_invocation_urls = internal_invocation_urls
610
- self.status.external_invocation_urls = external_invocation_urls
611
-
612
- # save the (first) function external invocation url
613
- # this is made for backwards compatability because the user, at this point, may
614
- # work remotely and need the external invocation url on the spec.command
615
- # TODO: when using `ClusterIP`, this block might not fulfilled
616
- # as long as function doesnt have ingresses
617
- if self.status.external_invocation_urls:
618
- address = self.status.external_invocation_urls[0]
619
- self.spec.command = f"http://{address}"
620
- self.status.state = "ready"
621
- self.status.address = address
622
- save_record = True
575
+ save_record = False
576
+ # Attempt auto-mounting, before sending to remote build
577
+ self.try_auto_mount_based_on_config()
578
+ self._fill_credentials()
579
+ db = self._get_db()
580
+ logger.info("Starting remote function deploy")
581
+ data = db.remote_builder(self, False, builder_env=builder_env)
582
+ self.status = data["data"].get("status")
583
+ self._update_credentials_from_remote_build(data["data"])
584
+
585
+ # when a function is deployed, we wait for it to be ready by default
586
+ # this also means that the function object will be updated with the function status
587
+ self._wait_for_function_deployment(db, verbose=verbose)
588
+
589
+ # NOTE: on older mlrun versions & nuclio versions, function are exposed via NodePort
590
+ # now, functions can be not exposed (using service type ClusterIP) and hence
591
+ # for BC we first try to populate the external invocation url, and then
592
+ # if not exists, take the internal invocation url
593
+ if self.status.external_invocation_urls:
594
+ self.spec.command = f"http://{self.status.external_invocation_urls[0]}"
595
+ save_record = True
596
+ elif self.status.internal_invocation_urls:
597
+ self.spec.command = f"http://{self.status.internal_invocation_urls[0]}"
598
+ save_record = True
599
+ elif self.status.address:
600
+ self.spec.command = f"http://{self.status.address}"
601
+ save_record = True
623
602
 
624
603
  logger.info(
625
604
  "successfully deployed function",
@@ -685,7 +664,7 @@ class RemoteRuntime(KubeResource):
685
664
  The default preemption mode is configurable in mlrun.mlconf.function_defaults.preemption_mode,
686
665
  by default it's set to **prevent**
687
666
 
688
- :param mode: allow | constrain | prevent | none defined in :py:class:`~mlrun.api.schemas.PreemptionModes`
667
+ :param mode: allow | constrain | prevent | none defined in :py:class:`~mlrun.common.schemas.PreemptionModes`
689
668
  """
690
669
  super().with_preemption_mode(mode=mode)
691
670
 
@@ -694,6 +673,22 @@ class RemoteRuntime(KubeResource):
694
673
  """k8s priority class"""
695
674
  super().with_priority_class(name)
696
675
 
676
+ def with_service_type(
677
+ self, service_type: str, add_templated_ingress_host_mode: str = None
678
+ ):
679
+ """
680
+ Enables to control the service type of the pod and the addition of templated ingress host
681
+
682
+ :param service_type: service type (ClusterIP, NodePort), defaults to
683
+ mlrun.mlconf.httpdb.nuclio.service_type
684
+ :param add_templated_ingress_host_mode: add templated ingress host mode (never, always, onClusterIP),
685
+ see mlrun.mlconf.httpdb.nuclio.add_templated_ingress_host_mode
686
+ for the default and more information
687
+
688
+ """
689
+ self.spec.service_type = service_type
690
+ self.spec.add_templated_ingress_host_mode = add_templated_ingress_host_mode
691
+
697
692
  def _get_state(
698
693
  self,
699
694
  dashboard="",
@@ -816,13 +811,12 @@ class RemoteRuntime(KubeResource):
816
811
  # verify auto mount is applied (with the client credentials)
817
812
  self.try_auto_mount_based_on_config()
818
813
 
819
- # if the function spec contain KFP PipelineParams (futures) pass the full spec to the
820
- # ContainerOp this way KFP will substitute the params with previous step outputs
821
- func_has_pipeline_params = self.to_json().find("{{pipelineparam:op") > 0
822
814
  if (
823
815
  use_function_from_db
824
816
  or use_function_from_db is None
825
- and not func_has_pipeline_params
817
+ # if the function contain KFP PipelineParams (futures) pass the full spec to the
818
+ # ContainerOp this way KFP will substitute the params with previous step outputs
819
+ and not self._has_pipeline_param()
826
820
  ):
827
821
  url = self.save(versioned=True, refresh=True)
828
822
  else:
@@ -1058,9 +1052,7 @@ class RemoteRuntime(KubeResource):
1058
1052
  if (
1059
1053
  not force_external_address
1060
1054
  and self.status.internal_invocation_urls
1061
- and get_k8s_helper(
1062
- silent=True, log=False
1063
- ).is_running_inside_kubernetes_cluster()
1055
+ and mlrun.k8s_utils.is_running_inside_kubernetes_cluster()
1064
1056
  ):
1065
1057
  return f"http://{self.status.internal_invocation_urls[0]}{path}"
1066
1058
 
@@ -1179,428 +1171,6 @@ def get_fullname(name, project, tag):
1179
1171
  return name
1180
1172
 
1181
1173
 
1182
- def deploy_nuclio_function(
1183
- function: RemoteRuntime,
1184
- dashboard="",
1185
- watch=False,
1186
- auth_info: AuthInfo = None,
1187
- client_version: str = None,
1188
- builder_env: dict = None,
1189
- client_python_version: str = None,
1190
- ):
1191
- """Deploys a nuclio function.
1192
-
1193
- :param function: nuclio function object
1194
- :param dashboard: DEPRECATED. Keep empty to allow auto-detection by MLRun API.
1195
- :param watch: wait for function to be ready
1196
- :param auth_info: service AuthInfo
1197
- :param client_version: mlrun client version
1198
- :param builder_env: mlrun builder environment (for config/credentials)
1199
- :param client_python_version: mlrun client python version
1200
- """
1201
- dashboard = dashboard or mlconf.nuclio_dashboard_url
1202
- function_name, project_name, function_config = compile_function_config(
1203
- function,
1204
- client_version=client_version,
1205
- client_python_version=client_python_version,
1206
- builder_env=builder_env or {},
1207
- auth_info=auth_info,
1208
- )
1209
-
1210
- # if mode allows it, enrich function http trigger with an ingress
1211
- enrich_function_with_ingress(
1212
- function_config,
1213
- mlconf.httpdb.nuclio.add_templated_ingress_host_mode,
1214
- mlconf.httpdb.nuclio.default_service_type,
1215
- )
1216
-
1217
- try:
1218
- return nuclio.deploy.deploy_config(
1219
- function_config,
1220
- dashboard_url=dashboard,
1221
- name=function_name,
1222
- project=project_name,
1223
- tag=function.metadata.tag,
1224
- verbose=function.verbose,
1225
- create_new=True,
1226
- watch=watch,
1227
- return_address_mode=nuclio.deploy.ReturnAddressModes.all,
1228
- auth_info=auth_info.to_nuclio_auth_info() if auth_info else None,
1229
- )
1230
- except nuclio.utils.DeployError as exc:
1231
- if exc.err:
1232
- err_message = (
1233
- f"Failed to deploy nuclio function {project_name}/{function_name}"
1234
- )
1235
-
1236
- try:
1237
-
1238
- # the error might not be jsonable, so we'll try to parse it
1239
- # and extract the error message
1240
- json_err = exc.err.response.json()
1241
- if "error" in json_err:
1242
- err_message += f" {json_err['error']}"
1243
- if "errorStackTrace" in json_err:
1244
- logger.warning(
1245
- "Failed to deploy nuclio function",
1246
- nuclio_stacktrace=json_err["errorStackTrace"],
1247
- )
1248
- except Exception as parse_exc:
1249
- logger.warning(
1250
- "Failed to parse nuclio deploy error",
1251
- parse_exc=err_to_str(parse_exc),
1252
- )
1253
-
1254
- mlrun.errors.raise_for_status(
1255
- exc.err.response,
1256
- err_message,
1257
- )
1258
- raise
1259
-
1260
-
1261
- def resolve_function_ingresses(function_spec):
1262
- http_trigger = resolve_function_http_trigger(function_spec)
1263
- if not http_trigger:
1264
- return []
1265
-
1266
- ingresses = []
1267
- for _, ingress_config in (
1268
- http_trigger.get("attributes", {}).get("ingresses", {}).items()
1269
- ):
1270
- ingresses.append(ingress_config)
1271
- return ingresses
1272
-
1273
-
1274
- def resolve_function_http_trigger(function_spec):
1275
- for trigger_name, trigger_config in function_spec.get("triggers", {}).items():
1276
- if trigger_config.get("kind") != "http":
1277
- continue
1278
- return trigger_config
1279
-
1280
-
1281
- def _resolve_function_image_pull_secret(function):
1282
- """
1283
- the corresponding attribute for 'build.secret' in nuclio is imagePullSecrets, attached link for reference
1284
- https://github.com/nuclio/nuclio/blob/e4af2a000dc52ee17337e75181ecb2652b9bf4e5/pkg/processor/build/builder.go#L1073
1285
- if only one of the secrets is set, use it.
1286
- if both are set, use the non default one and give precedence to image_pull_secret
1287
- """
1288
- # enrich only on server side
1289
- if not is_running_as_api():
1290
- return function.spec.image_pull_secret or function.spec.build.secret
1291
-
1292
- if function.spec.image_pull_secret is None:
1293
- function.spec.image_pull_secret = (
1294
- mlrun.mlconf.function.spec.image_pull_secret.default
1295
- )
1296
- elif (
1297
- function.spec.image_pull_secret
1298
- != mlrun.mlconf.function.spec.image_pull_secret.default
1299
- ):
1300
- return function.spec.image_pull_secret
1301
-
1302
- if function.spec.build.secret is None:
1303
- function.spec.build.secret = mlrun.mlconf.httpdb.builder.docker_registry_secret
1304
- elif (
1305
- function.spec.build.secret != mlrun.mlconf.httpdb.builder.docker_registry_secret
1306
- ):
1307
- return function.spec.build.secret
1308
-
1309
- return function.spec.image_pull_secret or function.spec.build.secret
1310
-
1311
-
1312
- def compile_function_config(
1313
- function: RemoteRuntime,
1314
- client_version: str = None,
1315
- client_python_version: str = None,
1316
- builder_env=None,
1317
- auth_info=None,
1318
- ):
1319
- labels = function.metadata.labels or {}
1320
- labels.update({"mlrun/class": function.kind})
1321
- for key, value in labels.items():
1322
- # Adding escaping to the key to prevent it from being split by dots if it contains any
1323
- function.set_config(f"metadata.labels.\\{key}\\", value)
1324
-
1325
- # Add secret configurations to function's pod spec, if secret sources were added.
1326
- # Needs to be here, since it adds env params, which are handled in the next lines.
1327
- # This only needs to run if we're running within k8s context. If running in Docker, for example, skip.
1328
- if get_k8s_helper(silent=True).is_running_inside_kubernetes_cluster():
1329
- function.add_secrets_config_to_spec()
1330
-
1331
- env_dict, external_source_env_dict = function._get_nuclio_config_spec_env()
1332
-
1333
- nuclio_runtime = (
1334
- function.spec.nuclio_runtime
1335
- or _resolve_nuclio_runtime_python_image(
1336
- mlrun_client_version=client_version, python_version=client_python_version
1337
- )
1338
- )
1339
-
1340
- if is_nuclio_version_in_range("0.0.0", "1.6.0") and nuclio_runtime in [
1341
- "python:3.7",
1342
- "python:3.8",
1343
- ]:
1344
- nuclio_runtime_set_from_spec = nuclio_runtime == function.spec.nuclio_runtime
1345
- if nuclio_runtime_set_from_spec:
1346
- raise mlrun.errors.MLRunInvalidArgumentError(
1347
- f"Nuclio version does not support the configured runtime: {nuclio_runtime}"
1348
- )
1349
- else:
1350
- # our default is python:3.9, simply set it to python:3.6 to keep supporting envs with old Nuclio
1351
- nuclio_runtime = "python:3.6"
1352
-
1353
- # In nuclio 1.6.0<=v<1.8.0, python runtimes default behavior was to not decode event strings
1354
- # Our code is counting on the strings to be decoded, so add the needed env var for those versions
1355
- if (
1356
- is_nuclio_version_in_range("1.6.0", "1.8.0")
1357
- and "NUCLIO_PYTHON_DECODE_EVENT_STRINGS" not in env_dict
1358
- ):
1359
- env_dict["NUCLIO_PYTHON_DECODE_EVENT_STRINGS"] = "true"
1360
-
1361
- nuclio_spec = nuclio.ConfigSpec(
1362
- env=env_dict,
1363
- external_source_env=external_source_env_dict,
1364
- config=function.spec.config,
1365
- )
1366
- nuclio_spec.cmd = function.spec.build.commands or []
1367
- project = function.metadata.project or "default"
1368
- tag = function.metadata.tag
1369
- handler = function.spec.function_handler
1370
-
1371
- if function.spec.build.source:
1372
- _compile_nuclio_archive_config(
1373
- nuclio_spec, function, builder_env, project, auth_info=auth_info
1374
- )
1375
-
1376
- nuclio_spec.set_config("spec.runtime", nuclio_runtime)
1377
-
1378
- # In Nuclio >= 1.6.x default serviceType has changed to "ClusterIP".
1379
- nuclio_spec.set_config(
1380
- "spec.serviceType", mlconf.httpdb.nuclio.default_service_type
1381
- )
1382
- if function.spec.readiness_timeout:
1383
- nuclio_spec.set_config(
1384
- "spec.readinessTimeoutSeconds", function.spec.readiness_timeout
1385
- )
1386
- if function.spec.resources:
1387
- nuclio_spec.set_config("spec.resources", function.spec.resources)
1388
- if function.spec.no_cache:
1389
- nuclio_spec.set_config("spec.build.noCache", True)
1390
- if function.spec.build.functionSourceCode:
1391
- nuclio_spec.set_config(
1392
- "spec.build.functionSourceCode", function.spec.build.functionSourceCode
1393
- )
1394
-
1395
- image_pull_secret = _resolve_function_image_pull_secret(function)
1396
- if image_pull_secret:
1397
- nuclio_spec.set_config("spec.imagePullSecrets", image_pull_secret)
1398
-
1399
- if function.spec.base_image_pull:
1400
- nuclio_spec.set_config("spec.build.noBaseImagesPull", False)
1401
- # don't send node selections if nuclio is not compatible
1402
- if validate_nuclio_version_compatibility("1.5.20", "1.6.10"):
1403
- if function.spec.node_selector:
1404
- nuclio_spec.set_config("spec.nodeSelector", function.spec.node_selector)
1405
- if function.spec.node_name:
1406
- nuclio_spec.set_config("spec.nodeName", function.spec.node_name)
1407
- if function.spec.affinity:
1408
- nuclio_spec.set_config(
1409
- "spec.affinity",
1410
- mlrun.runtimes.pod.get_sanitized_attribute(function.spec, "affinity"),
1411
- )
1412
-
1413
- # don't send tolerations if nuclio is not compatible
1414
- if validate_nuclio_version_compatibility("1.7.5"):
1415
- if function.spec.tolerations:
1416
- nuclio_spec.set_config(
1417
- "spec.tolerations",
1418
- mlrun.runtimes.pod.get_sanitized_attribute(
1419
- function.spec, "tolerations"
1420
- ),
1421
- )
1422
- # don't send preemption_mode if nuclio is not compatible
1423
- if validate_nuclio_version_compatibility("1.8.6"):
1424
- if function.spec.preemption_mode:
1425
- nuclio_spec.set_config(
1426
- "spec.PreemptionMode",
1427
- function.spec.preemption_mode,
1428
- )
1429
-
1430
- # don't send default or any priority class name if nuclio is not compatible
1431
- if (
1432
- function.spec.priority_class_name
1433
- and validate_nuclio_version_compatibility("1.6.18")
1434
- and len(mlconf.get_valid_function_priority_class_names())
1435
- ):
1436
- nuclio_spec.set_config(
1437
- "spec.priorityClassName", function.spec.priority_class_name
1438
- )
1439
-
1440
- if function.spec.replicas:
1441
-
1442
- nuclio_spec.set_config(
1443
- "spec.minReplicas", as_number("spec.Replicas", function.spec.replicas)
1444
- )
1445
- nuclio_spec.set_config(
1446
- "spec.maxReplicas", as_number("spec.Replicas", function.spec.replicas)
1447
- )
1448
-
1449
- else:
1450
- nuclio_spec.set_config(
1451
- "spec.minReplicas",
1452
- as_number("spec.minReplicas", function.spec.min_replicas),
1453
- )
1454
- nuclio_spec.set_config(
1455
- "spec.maxReplicas",
1456
- as_number("spec.maxReplicas", function.spec.max_replicas),
1457
- )
1458
-
1459
- if function.spec.service_account:
1460
- nuclio_spec.set_config("spec.serviceAccount", function.spec.service_account)
1461
-
1462
- if function.spec.security_context:
1463
- nuclio_spec.set_config(
1464
- "spec.securityContext",
1465
- mlrun.runtimes.pod.get_sanitized_attribute(
1466
- function.spec, "security_context"
1467
- ),
1468
- )
1469
-
1470
- if (
1471
- function.spec.base_spec
1472
- or function.spec.build.functionSourceCode
1473
- or function.spec.build.source
1474
- or function.kind == mlrun.runtimes.RuntimeKinds.serving # serving can be empty
1475
- ):
1476
- config = function.spec.base_spec
1477
- if not config:
1478
- # if base_spec was not set (when not using code_to_function) and we have base64 code
1479
- # we create the base spec with essential attributes
1480
- config = nuclio.config.new_config()
1481
- update_in(config, "spec.handler", handler or "main:handler")
1482
-
1483
- config = nuclio.config.extend_config(
1484
- config, nuclio_spec, tag, function.spec.build.code_origin
1485
- )
1486
-
1487
- update_in(config, "metadata.name", function.metadata.name)
1488
- update_in(config, "spec.volumes", function.spec.generate_nuclio_volumes())
1489
- base_image = (
1490
- get_in(config, "spec.build.baseImage")
1491
- or function.spec.image
1492
- or function.spec.build.base_image
1493
- )
1494
- if base_image:
1495
- update_in(
1496
- config,
1497
- "spec.build.baseImage",
1498
- enrich_image_url(base_image, client_version, client_python_version),
1499
- )
1500
-
1501
- logger.info("deploy started")
1502
- name = get_fullname(function.metadata.name, project, tag)
1503
- function.status.nuclio_name = name
1504
- update_in(config, "metadata.name", name)
1505
-
1506
- if function.kind == mlrun.runtimes.RuntimeKinds.serving and not get_in(
1507
- config, "spec.build.functionSourceCode"
1508
- ):
1509
- if not function.spec.build.source:
1510
- # set the source to the mlrun serving wrapper
1511
- body = nuclio.build.mlrun_footer.format(
1512
- mlrun.runtimes.serving.serving_subkind
1513
- )
1514
- update_in(
1515
- config,
1516
- "spec.build.functionSourceCode",
1517
- b64encode(body.encode("utf-8")).decode("utf-8"),
1518
- )
1519
- elif not function.spec.function_handler:
1520
- # point the nuclio function handler to mlrun serving wrapper handlers
1521
- update_in(
1522
- config,
1523
- "spec.handler",
1524
- "mlrun.serving.serving_wrapper:handler",
1525
- )
1526
- else:
1527
- # todo: should be deprecated (only work via MLRun service)
1528
- # this may also be called in case of using single file code_to_function(embed_code=False)
1529
- # this option need to be removed or be limited to using remote files (this code runs in server)
1530
- name, config, code = nuclio.build_file(
1531
- function.spec.source,
1532
- name=function.metadata.name,
1533
- project=project,
1534
- handler=handler,
1535
- tag=tag,
1536
- spec=nuclio_spec,
1537
- kind=function.spec.function_kind,
1538
- verbose=function.verbose,
1539
- )
1540
-
1541
- update_in(config, "spec.volumes", function.spec.generate_nuclio_volumes())
1542
- base_image = function.spec.image or function.spec.build.base_image
1543
- if base_image:
1544
- update_in(
1545
- config,
1546
- "spec.build.baseImage",
1547
- enrich_image_url(base_image, client_version, client_python_version),
1548
- )
1549
-
1550
- name = get_fullname(name, project, tag)
1551
- function.status.nuclio_name = name
1552
-
1553
- update_in(config, "metadata.name", name)
1554
-
1555
- return name, project, config
1556
-
1557
-
1558
- def enrich_function_with_ingress(config, mode, service_type):
1559
- # do not enrich with an ingress
1560
- if mode == NuclioIngressAddTemplatedIngressModes.never:
1561
- return
1562
-
1563
- ingresses = resolve_function_ingresses(config["spec"])
1564
-
1565
- # function has ingresses already, nothing to add / enrich
1566
- if ingresses:
1567
- return
1568
-
1569
- # if exists, get the http trigger the function has
1570
- # we would enrich it with an ingress
1571
- http_trigger = resolve_function_http_trigger(config["spec"])
1572
- if not http_trigger:
1573
- # function has an HTTP trigger without an ingress
1574
- # TODO: read from nuclio-api frontend-spec
1575
- http_trigger = {
1576
- "kind": "http",
1577
- "name": "http",
1578
- "maxWorkers": 1,
1579
- "workerAvailabilityTimeoutMilliseconds": 10000, # 10 seconds
1580
- "attributes": {},
1581
- }
1582
-
1583
- def enrich():
1584
- http_trigger.setdefault("attributes", {}).setdefault("ingresses", {})["0"] = {
1585
- "paths": ["/"],
1586
- # this would tell Nuclio to use its default ingress host template
1587
- # and would auto assign a host for the ingress
1588
- "hostTemplate": "@nuclio.fromDefault",
1589
- }
1590
- http_trigger["attributes"]["serviceType"] = service_type
1591
- config["spec"].setdefault("triggers", {})[http_trigger["name"]] = http_trigger
1592
-
1593
- if mode == NuclioIngressAddTemplatedIngressModes.always:
1594
- enrich()
1595
- elif mode == NuclioIngressAddTemplatedIngressModes.on_cluster_ip:
1596
-
1597
- # service type is not cluster ip, bail out
1598
- if service_type and service_type.lower() != "clusterip":
1599
- return
1600
-
1601
- enrich()
1602
-
1603
-
1604
1174
  def get_nuclio_deploy_status(
1605
1175
  name,
1606
1176
  project,
@@ -1659,163 +1229,3 @@ def get_nuclio_deploy_status(
1659
1229
  else:
1660
1230
  text = "\n".join(outputs) if outputs else ""
1661
1231
  return state, address, name, last_log_timestamp, text, function_status
1662
-
1663
-
1664
- def _compile_nuclio_archive_config(
1665
- nuclio_spec,
1666
- function: RemoteRuntime,
1667
- builder_env,
1668
- project=None,
1669
- auth_info=None,
1670
- ):
1671
- secrets = {}
1672
- if project and get_k8s_helper(silent=True).is_running_inside_kubernetes_cluster():
1673
- secrets = get_k8s_helper().get_project_secret_data(project)
1674
-
1675
- def get_secret(key):
1676
- return builder_env.get(key) or secrets.get(key, "")
1677
-
1678
- source = function.spec.build.source
1679
- parsed_url = urlparse(source)
1680
- code_entry_type = ""
1681
- if source.startswith("s3://"):
1682
- code_entry_type = "s3"
1683
- if source.startswith("git://"):
1684
- code_entry_type = "git"
1685
- for archive_prefix in ["http://", "https://", "v3io://", "v3ios://"]:
1686
- if source.startswith(archive_prefix):
1687
- code_entry_type = "archive"
1688
-
1689
- if code_entry_type == "":
1690
- raise mlrun.errors.MLRunInvalidArgumentError(
1691
- "Couldn't resolve code entry type from source"
1692
- )
1693
-
1694
- code_entry_attributes = {}
1695
-
1696
- # resolve work_dir and handler
1697
- work_dir, handler = _resolve_work_dir_and_handler(function.spec.function_handler)
1698
- work_dir = function.spec.workdir or work_dir
1699
- if work_dir != "":
1700
- code_entry_attributes["workDir"] = work_dir
1701
-
1702
- # archive
1703
- if code_entry_type == "archive":
1704
- v3io_access_key = builder_env.get("V3IO_ACCESS_KEY", "")
1705
- if source.startswith("v3io"):
1706
- if not parsed_url.netloc:
1707
- source = mlrun.mlconf.v3io_api + parsed_url.path
1708
- else:
1709
- source = f"http{source[len('v3io'):]}"
1710
- if auth_info and not v3io_access_key:
1711
- v3io_access_key = auth_info.data_session or auth_info.access_key
1712
-
1713
- if v3io_access_key:
1714
- code_entry_attributes["headers"] = {"X-V3io-Session-Key": v3io_access_key}
1715
-
1716
- # s3
1717
- if code_entry_type == "s3":
1718
- bucket, item_key = parse_s3_bucket_and_key(source)
1719
-
1720
- code_entry_attributes["s3Bucket"] = bucket
1721
- code_entry_attributes["s3ItemKey"] = item_key
1722
-
1723
- code_entry_attributes["s3AccessKeyId"] = get_secret("AWS_ACCESS_KEY_ID")
1724
- code_entry_attributes["s3SecretAccessKey"] = get_secret("AWS_SECRET_ACCESS_KEY")
1725
- code_entry_attributes["s3SessionToken"] = get_secret("AWS_SESSION_TOKEN")
1726
-
1727
- # git
1728
- if code_entry_type == "git":
1729
-
1730
- # change git:// to https:// as nuclio expects it to be
1731
- if source.startswith("git://"):
1732
- source = source.replace("git://", "https://")
1733
-
1734
- source, reference, branch = mlrun.utils.resolve_git_reference_from_source(
1735
- source
1736
- )
1737
- if not branch and not reference:
1738
- raise mlrun.errors.MLRunInvalidArgumentError(
1739
- "git branch or refs must be specified in the source e.g.: "
1740
- "'git://<url>/org/repo.git#<branch-name or refs/heads/..>'"
1741
- )
1742
- if reference:
1743
- code_entry_attributes["reference"] = reference
1744
- if branch:
1745
- code_entry_attributes["branch"] = branch
1746
-
1747
- password = get_secret("GIT_PASSWORD")
1748
- username = get_secret("GIT_USERNAME")
1749
-
1750
- token = get_secret("GIT_TOKEN")
1751
- if token:
1752
- username, password = mlrun.utils.get_git_username_password_from_token(token)
1753
-
1754
- code_entry_attributes["username"] = username
1755
- code_entry_attributes["password"] = password
1756
-
1757
- # populate spec with relevant fields
1758
- nuclio_spec.set_config("spec.handler", handler)
1759
- nuclio_spec.set_config("spec.build.path", source)
1760
- nuclio_spec.set_config("spec.build.codeEntryType", code_entry_type)
1761
- nuclio_spec.set_config("spec.build.codeEntryAttributes", code_entry_attributes)
1762
-
1763
-
1764
- def _resolve_work_dir_and_handler(handler):
1765
- """
1766
- Resolves a nuclio function working dir and handler inside an archive/git repo
1767
- :param handler: a path describing working dir and handler of a nuclio function
1768
- :return: (working_dir, handler) tuple, as nuclio expects to get it
1769
-
1770
- Example: ("a/b/c#main:Handler") -> ("a/b/c", "main:Handler")
1771
- """
1772
-
1773
- def extend_handler(base_handler):
1774
- # return default handler and module if not specified
1775
- if not base_handler:
1776
- return "main:handler"
1777
- if ":" not in base_handler:
1778
- base_handler = f"{base_handler}:handler"
1779
- return base_handler
1780
-
1781
- if not handler:
1782
- return "", "main:handler"
1783
-
1784
- split_handler = handler.split("#")
1785
- if len(split_handler) == 1:
1786
- return "", extend_handler(handler)
1787
-
1788
- return split_handler[0], extend_handler(split_handler[1])
1789
-
1790
-
1791
- def _resolve_nuclio_runtime_python_image(
1792
- mlrun_client_version: str = None, python_version: str = None
1793
- ):
1794
- # if no python version or mlrun version is passed it means we use mlrun client older than 1.3.0 therefore need
1795
- # to use the previoud default runtime which is python 3.7
1796
- if not python_version or not mlrun_client_version:
1797
- return "python:3.7"
1798
-
1799
- # If the mlrun version is 0.0.0-<unstable>, it is a dev version,
1800
- # so we can't check if it is higher than 1.3.0, but if the python version was passed,
1801
- # it means it is 1.3.0-rc or higher, so use the image according to the python version
1802
- if mlrun_client_version.startswith("0.0.0-") or "unstable" in mlrun_client_version:
1803
- if python_version.startswith("3.7"):
1804
- return "python:3.7"
1805
-
1806
- return mlrun.mlconf.default_nuclio_runtime
1807
-
1808
- # if mlrun version is older than 1.3.0 we need to use the previous default runtime which is python 3.7
1809
- if semver.VersionInfo.parse(mlrun_client_version) < semver.VersionInfo.parse(
1810
- "1.3.0-X"
1811
- ):
1812
- return "python:3.7"
1813
-
1814
- # if mlrun version is 1.3.0 or newer and python version is 3.7 we need to use python 3.7 image
1815
- if semver.VersionInfo.parse(mlrun_client_version) >= semver.VersionInfo.parse(
1816
- "1.3.0-X"
1817
- ) and python_version.startswith("3.7"):
1818
- return "python:3.7"
1819
-
1820
- # if none of the above conditions are met we use the default runtime which is python 3.9
1821
- return mlrun.mlconf.default_nuclio_runtime