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
@@ -0,0 +1,616 @@
1
+ # Copyright 2023 Iguazio
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+ import os
16
+ import pathlib
17
+ import tempfile
18
+ from typing import Tuple, Union
19
+
20
+ from mlrun.artifacts import Artifact
21
+ from mlrun.datastore import DataItem
22
+ from mlrun.errors import MLRunInvalidArgumentError
23
+
24
+ from ..utils import (
25
+ DEFAULT_ARCHIVE_FORMAT,
26
+ DEFAULT_STRUCT_FILE_FORMAT,
27
+ ArchiveSupportedFormat,
28
+ ArtifactType,
29
+ StructFileSupportedFormat,
30
+ )
31
+ from .default_packager import DefaultPackager
32
+
33
+ # ----------------------------------------------------------------------------------------------------------------------
34
+ # builtins packagers:
35
+ # ----------------------------------------------------------------------------------------------------------------------
36
+
37
+
38
+ class IntPackager(DefaultPackager):
39
+ """
40
+ ``builtins.int`` packager.
41
+ """
42
+
43
+ PACKABLE_OBJECT_TYPE = int
44
+ DEFAULT_PACKING_ARTIFACT_TYPE = ArtifactType.RESULT
45
+
46
+
47
+ class FloatPackager(DefaultPackager):
48
+ """
49
+ ``builtins.float`` packager.
50
+ """
51
+
52
+ PACKABLE_OBJECT_TYPE = float
53
+ DEFAULT_PACKING_ARTIFACT_TYPE = ArtifactType.RESULT
54
+
55
+
56
+ class BoolPackager(DefaultPackager):
57
+ """
58
+ ``builtins.bool`` packager.
59
+ """
60
+
61
+ PACKABLE_OBJECT_TYPE = bool
62
+ DEFAULT_PACKING_ARTIFACT_TYPE = ArtifactType.RESULT
63
+
64
+
65
+ class StrPackager(DefaultPackager):
66
+ """
67
+ ``builtins.str`` packager.
68
+ """
69
+
70
+ PACKABLE_OBJECT_TYPE = str
71
+ DEFAULT_PACKING_ARTIFACT_TYPE = ArtifactType.RESULT
72
+ DEFAULT_UNPACKING_ARTIFACT_TYPE = ArtifactType.PATH
73
+
74
+ @classmethod
75
+ def pack_path(
76
+ cls, obj: str, key: str, archive_format: str = DEFAULT_ARCHIVE_FORMAT
77
+ ) -> Tuple[Artifact, dict]:
78
+ """
79
+ Pack a path string value content (pack the file or directory in that path).
80
+
81
+ :param obj: The string path value to pack.
82
+ :param key: The key to use for the artifact.
83
+ :param archive_format: The archive format to use in case the path is of a directory. Default is zip.
84
+
85
+ :return: The packed artifact and instructions.
86
+ """
87
+ # TODO: Add a configuration like `archive_file: bool = False` to enable archiving a single file to shrink it in
88
+ # size. In that case the `is_directory` instruction will make it so when an archive is received, if its
89
+ # a directory, when exporting it a directory path should be returned. And, if its a file, a path to the
90
+ # single file exported should be returned.
91
+ # Verify the path is of an existing file:
92
+ if not os.path.exists(obj):
93
+ raise MLRunInvalidArgumentError(f"The given path do not exist: '{obj}'")
94
+
95
+ # Proceed by path type (file or directory):
96
+ if os.path.isfile(obj):
97
+ # Create the artifact:
98
+ artifact = Artifact(key=key, src_path=os.path.abspath(obj))
99
+ instructions = {"is_directory": False}
100
+ elif os.path.isdir(obj):
101
+ # Archive the directory:
102
+ output_path = tempfile.mkdtemp()
103
+ archiver = ArchiveSupportedFormat.get_format_handler(fmt=archive_format)
104
+ archive_path = archiver.create_archive(
105
+ directory_path=obj, output_path=output_path
106
+ )
107
+ # Create the artifact:
108
+ artifact = Artifact(key=key, src_path=archive_path)
109
+ instructions = {"archive_format": archive_format, "is_directory": True}
110
+ else:
111
+ raise MLRunInvalidArgumentError(
112
+ f"The given path is not a file nor a directory: '{obj}'"
113
+ )
114
+
115
+ return artifact, instructions
116
+
117
+ @classmethod
118
+ def unpack_path(
119
+ cls, data_item: DataItem, is_directory: bool = False, archive_format: str = None
120
+ ) -> str:
121
+ """
122
+ Unpack a data item representing a path string. If the path is of a file, the file is downloaded to a local
123
+ temporary directory and its path is returned. If the path is of a directory, the archive is extracted and the
124
+ directory path extracted is returned.
125
+
126
+ :param data_item: The data item to unpack.
127
+ :param is_directory: Whether the path should be treated as a file or a directory. Files (even archives like
128
+ zip) won't be extracted.
129
+ :param archive_format: The archive format to use in case the path is of a directory. Default is None - will be
130
+ read by the archive file extension.
131
+
132
+ :return: The unpacked string.
133
+ """
134
+ # Get the file to a local temporary directory:
135
+ path = data_item.local()
136
+
137
+ # Mark the downloaded file for future clear:
138
+ cls.add_future_clearing_path(path=path)
139
+
140
+ # If it's not a directory, return the file path. Otherwise, it should be extracted according to the archive
141
+ # format:
142
+ if not is_directory:
143
+ return path
144
+
145
+ # Get the archive format by the file extension:
146
+ if archive_format is None:
147
+ archive_format = ArchiveSupportedFormat.match_format(path=path)
148
+ if archive_format is None:
149
+ raise MLRunInvalidArgumentError(
150
+ f"Archive format of {data_item.key} ('{''.join(pathlib.Path(path).suffixes)}') is not supported. "
151
+ f"Supported formats are: {' '.join(ArchiveSupportedFormat.get_all_formats())}"
152
+ )
153
+
154
+ # Extract the archive:
155
+ archiver = ArchiveSupportedFormat.get_format_handler(fmt=archive_format)
156
+ directory_path = archiver.extract_archive(
157
+ archive_path=path, output_path=os.path.dirname(path)
158
+ )
159
+
160
+ # Mark the extracted content for future clear:
161
+ cls.add_future_clearing_path(path=directory_path)
162
+
163
+ # Return the extracted directory path:
164
+ return directory_path
165
+
166
+
167
+ class _BuiltinCollectionPackager(DefaultPackager):
168
+ """
169
+ A base packager for builtin python dictionaries and lists as they share common artifact and file types.
170
+ """
171
+
172
+ DEFAULT_PACKING_ARTIFACT_TYPE = ArtifactType.RESULT
173
+ DEFAULT_UNPACKING_ARTIFACT_TYPE = ArtifactType.FILE
174
+
175
+ @classmethod
176
+ def pack_file(
177
+ cls,
178
+ obj: Union[dict, list],
179
+ key: str,
180
+ file_format: str = DEFAULT_STRUCT_FILE_FORMAT,
181
+ ) -> Tuple[Artifact, dict]:
182
+ """
183
+ Pack a builtin collection as a file by the given format.
184
+
185
+ :param obj: The builtin collection to pack.
186
+ :param key: The key to use for the artifact.
187
+ :param file_format: The file format to save as. Default is json.
188
+
189
+ :return: The packed artifact and instructions.
190
+ """
191
+ # Write to file:
192
+ formatter = StructFileSupportedFormat.get_format_handler(fmt=file_format)
193
+ temp_directory = pathlib.Path(tempfile.mkdtemp())
194
+ cls.add_future_clearing_path(path=temp_directory)
195
+ file_path = temp_directory / f"{key}.{file_format}"
196
+ formatter.write(obj=obj, file_path=str(file_path))
197
+
198
+ # Create the artifact and instructions:
199
+ artifact = Artifact(key=key, src_path=os.path.abspath(file_path))
200
+ instructions = {"file_format": file_format}
201
+
202
+ return artifact, instructions
203
+
204
+ @classmethod
205
+ def unpack_file(
206
+ cls, data_item: DataItem, file_format: str = None
207
+ ) -> Union[dict, list]:
208
+ """
209
+ Unpack a builtin collection from file.
210
+
211
+ :param data_item: The data item to unpack.
212
+ :param file_format: The file format to use for reading the builtin collection. Default is None - will be read by
213
+ the file extension.
214
+
215
+ :return: The unpacked builtin collection.
216
+ """
217
+ # Get the file:
218
+ file_path = data_item.local()
219
+ cls.add_future_clearing_path(path=file_path)
220
+
221
+ # Get the archive format by the file extension if needed:
222
+ if file_format is None:
223
+ file_format = StructFileSupportedFormat.match_format(path=file_path)
224
+ if file_format is None:
225
+ raise MLRunInvalidArgumentError(
226
+ f"File format of {data_item.key} ('{''.join(pathlib.Path(file_path).suffixes)}') is not supported. "
227
+ f"Supported formats are: {' '.join(StructFileSupportedFormat.get_all_formats())}"
228
+ )
229
+
230
+ # Read the object:
231
+ formatter = StructFileSupportedFormat.get_format_handler(fmt=file_format)
232
+ obj = formatter.read(file_path=file_path)
233
+
234
+ return obj
235
+
236
+
237
+ class DictPackager(_BuiltinCollectionPackager):
238
+ """
239
+ ``builtins.dict`` packager.
240
+ """
241
+
242
+ PACKABLE_OBJECT_TYPE = dict
243
+
244
+ @classmethod
245
+ def unpack_file(cls, data_item: DataItem, file_format: str = None) -> dict:
246
+ """
247
+ Unpack a dictionary from file.
248
+
249
+ :param data_item: The data item to unpack.
250
+ :param file_format: The file format to use for reading the dictionary. Default is None - will be read by the
251
+ file extension.
252
+
253
+ :return: The unpacked dictionary.
254
+ """
255
+ # Unpack the object:
256
+ obj = super().unpack_file(data_item=data_item, file_format=file_format)
257
+
258
+ # Check if needed to cast from list:
259
+ if isinstance(obj, list):
260
+ return {index: element for index, element in enumerate(obj)}
261
+ return obj
262
+
263
+
264
+ class ListPackager(_BuiltinCollectionPackager):
265
+ """
266
+ ``builtins.list`` packager.
267
+ """
268
+
269
+ PACKABLE_OBJECT_TYPE = list
270
+
271
+ @classmethod
272
+ def unpack_file(cls, data_item: DataItem, file_format: str = None) -> list:
273
+ """
274
+ Unpack a list from file.
275
+
276
+ :param data_item: The data item to unpack.
277
+ :param file_format: The file format to use for reading the list. Default is None - will be read by the file
278
+ extension.
279
+
280
+ :return: The unpacked list.
281
+ """
282
+ # Unpack the object:
283
+ obj = super().unpack_file(data_item=data_item, file_format=file_format)
284
+
285
+ # Check if needed to cast from dict:
286
+ if isinstance(obj, dict):
287
+ return list(obj.values())
288
+ return obj
289
+
290
+
291
+ class TuplePackager(ListPackager):
292
+ """
293
+ ``builtins.tuple`` packager.
294
+
295
+ Notice: a ``tuple`` returned from a function is usually treated as multiple returned objects, and so MLRun will try
296
+ to pack each of them separately and not as a single tuple. For example::
297
+
298
+ def example_func_1():
299
+ return 10, [1, 2, 3], "Hello MLRun"
300
+
301
+ Will be returned as a ``tuple`` of 3 items: `(10, [1, 2, 3], "Hello MLRun")` but the items will be packaged
302
+ separately one by one and not as a single ``tuple``.
303
+
304
+ In order to pack tuples (not recommended), use the configuration::
305
+
306
+ mlrun.mlconf.packagers.pack_tuple = True
307
+
308
+ Or more correctly, cast your returned tuple to a ``list`` like so::
309
+
310
+ def example_func_2():
311
+ my_tuple = (2, 4)
312
+ return list(my_tuple)
313
+ """
314
+
315
+ PACKABLE_OBJECT_TYPE = tuple
316
+
317
+ @classmethod
318
+ def pack_result(cls, obj: tuple, key: str) -> dict:
319
+ """
320
+ Pack a tuple as a result.
321
+
322
+ :param obj: The tuple to pack and log.
323
+ :param key: The result's key.
324
+
325
+ :return: The result dictionary.
326
+ """
327
+ return super().pack_result(obj=list(obj), key=key)
328
+
329
+ @classmethod
330
+ def pack_file(
331
+ cls, obj: tuple, key: str, file_format: str = DEFAULT_STRUCT_FILE_FORMAT
332
+ ) -> Tuple[Artifact, dict]:
333
+ """
334
+ Pack a tuple as a file by the given format.
335
+
336
+ :param obj: The tuple to pack.
337
+ :param key: The key to use for the artifact.
338
+ :param file_format: The file format to save as. Default is json.
339
+
340
+ :return: The packed artifact and instructions.
341
+ """
342
+ return super().pack_file(obj=list(obj), key=key, file_format=file_format)
343
+
344
+ @classmethod
345
+ def unpack_file(cls, data_item: DataItem, file_format: str = None) -> tuple:
346
+ """
347
+ Unpack a tuple from file.
348
+
349
+ :param data_item: The data item to unpack.
350
+ :param file_format: The file format to use for reading the tuple. Default is None - will be read by the file
351
+ extension.
352
+
353
+ :return: The unpacked tuple.
354
+ """
355
+ return tuple(super().unpack_file(data_item=data_item, file_format=file_format))
356
+
357
+
358
+ class SetPackager(ListPackager):
359
+ """
360
+ ``builtins.set`` packager.
361
+ """
362
+
363
+ PACKABLE_OBJECT_TYPE = set
364
+
365
+ @classmethod
366
+ def pack_result(cls, obj: set, key: str) -> dict:
367
+ """
368
+ Pack a set as a result.
369
+
370
+ :param obj: The set to pack and log.
371
+ :param key: The result's key.
372
+
373
+ :return: The result dictionary.
374
+ """
375
+ return super().pack_result(obj=list(obj), key=key)
376
+
377
+ @classmethod
378
+ def pack_file(
379
+ cls, obj: set, key: str, file_format: str = DEFAULT_STRUCT_FILE_FORMAT
380
+ ) -> Tuple[Artifact, dict]:
381
+ """
382
+ Pack a set as a file by the given format.
383
+
384
+ :param obj: The set to pack.
385
+ :param key: The key to use for the artifact.
386
+ :param file_format: The file format to save as. Default is json.
387
+
388
+ :return: The packed artifact and instructions.
389
+ """
390
+ return super().pack_file(obj=list(obj), key=key, file_format=file_format)
391
+
392
+ @classmethod
393
+ def unpack_file(cls, data_item: DataItem, file_format: str = None) -> set:
394
+ """
395
+ Unpack a set from file.
396
+
397
+ :param data_item: The data item to unpack.
398
+ :param file_format: The file format to use for reading the set. Default is None - will be read by the file
399
+ extension.
400
+
401
+ :return: The unpacked set.
402
+ """
403
+ return set(super().unpack_file(data_item=data_item, file_format=file_format))
404
+
405
+
406
+ class FrozensetPackager(SetPackager):
407
+ """
408
+ ``builtins.frozenset`` packager.
409
+ """
410
+
411
+ PACKABLE_OBJECT_TYPE = frozenset
412
+
413
+ @classmethod
414
+ def pack_file(
415
+ cls, obj: frozenset, key: str, file_format: str = DEFAULT_STRUCT_FILE_FORMAT
416
+ ) -> Tuple[Artifact, dict]:
417
+ """
418
+ Pack a frozenset as a file by the given format.
419
+
420
+ :param obj: The frozenset to pack.
421
+ :param key: The key to use for the artifact.
422
+ :param file_format: The file format to save as. Default is json.
423
+
424
+ :return: The packed artifact and instructions.
425
+ """
426
+ return super().pack_file(obj=set(obj), key=key, file_format=file_format)
427
+
428
+ @classmethod
429
+ def unpack_file(cls, data_item: DataItem, file_format: str = None) -> frozenset:
430
+ """
431
+ Unpack a frozenset from file.
432
+
433
+ :param data_item: The data item to unpack.
434
+ :param file_format: The file format to use for reading the frozenset. Default is None - will be read by the file
435
+ extension.
436
+
437
+ :return: The unpacked frozenset.
438
+ """
439
+ return frozenset(
440
+ super().unpack_file(data_item=data_item, file_format=file_format)
441
+ )
442
+
443
+
444
+ class BytesPackager(ListPackager):
445
+ """
446
+ ``builtins.bytes`` packager.
447
+ """
448
+
449
+ PACKABLE_OBJECT_TYPE = bytes
450
+
451
+ @classmethod
452
+ def pack_result(cls, obj: bytes, key: str) -> dict:
453
+ """
454
+ Pack bytes as a result.
455
+
456
+ :param obj: The bytearray to pack and log.
457
+ :param key: The result's key.
458
+
459
+ :return: The result dictionary.
460
+ """
461
+ return {key: obj}
462
+
463
+ @classmethod
464
+ def pack_file(
465
+ cls, obj: bytes, key: str, file_format: str = DEFAULT_STRUCT_FILE_FORMAT
466
+ ) -> Tuple[Artifact, dict]:
467
+ """
468
+ Pack a bytes as a file by the given format.
469
+
470
+ :param obj: The bytes to pack.
471
+ :param key: The key to use for the artifact.
472
+ :param file_format: The file format to save as. Default is json.
473
+
474
+ :return: The packed artifact and instructions.
475
+ """
476
+ return super().pack_file(obj=list(obj), key=key, file_format=file_format)
477
+
478
+ @classmethod
479
+ def unpack_file(cls, data_item: DataItem, file_format: str = None) -> bytes:
480
+ """
481
+ Unpack a bytes from file.
482
+
483
+ :param data_item: The data item to unpack.
484
+ :param file_format: The file format to use for reading the bytes. Default is None - will be read by the file
485
+ extension.
486
+
487
+ :return: The unpacked bytes.
488
+ """
489
+ return bytes(super().unpack_file(data_item=data_item, file_format=file_format))
490
+
491
+
492
+ class BytearrayPackager(BytesPackager):
493
+ """
494
+ ``builtins.bytearray`` packager.
495
+ """
496
+
497
+ PACKABLE_OBJECT_TYPE = bytearray
498
+
499
+ @classmethod
500
+ def pack_result(cls, obj: bytearray, key: str) -> dict:
501
+ """
502
+ Pack a bytearray as a result.
503
+
504
+ :param obj: The bytearray to pack and log.
505
+ :param key: The result's key.
506
+
507
+ :return: The result dictionary.
508
+ """
509
+ return {key: bytes(obj)}
510
+
511
+ @classmethod
512
+ def pack_file(
513
+ cls, obj: bytearray, key: str, file_format: str = DEFAULT_STRUCT_FILE_FORMAT
514
+ ) -> Tuple[Artifact, dict]:
515
+ """
516
+ Pack a bytearray as a file by the given format.
517
+
518
+ :param obj: The bytearray to pack.
519
+ :param key: The key to use for the artifact.
520
+ :param file_format: The file format to save as. Default is json.
521
+
522
+ :return: The packed artifact and instructions.
523
+ """
524
+ return super().pack_file(obj=bytes(obj), key=key, file_format=file_format)
525
+
526
+ @classmethod
527
+ def unpack_file(cls, data_item: DataItem, file_format: str = None) -> bytearray:
528
+ """
529
+ Unpack a bytearray from file.
530
+
531
+ :param data_item: The data item to unpack.
532
+ :param file_format: The file format to use for reading the bytearray. Default is None - will be read by the file
533
+ extension.
534
+
535
+ :return: The unpacked bytearray.
536
+ """
537
+ return bytearray(
538
+ super().unpack_file(data_item=data_item, file_format=file_format)
539
+ )
540
+
541
+
542
+ # ----------------------------------------------------------------------------------------------------------------------
543
+ # pathlib packagers:
544
+ # ----------------------------------------------------------------------------------------------------------------------
545
+
546
+
547
+ class PathPackager(StrPackager):
548
+ """
549
+ ``pathlib.Path`` packager. It is also used for all `Path` inheriting pathlib objects (`PosixPath` and
550
+ `WindowsPath`).
551
+ """
552
+
553
+ PACKABLE_OBJECT_TYPE = pathlib.Path
554
+ PACK_SUBCLASSES = True
555
+ DEFAULT_PACKING_ARTIFACT_TYPE = "path"
556
+
557
+ @classmethod
558
+ def pack_result(cls, obj: pathlib.Path, key: str) -> dict:
559
+ """
560
+ Pack the `Path` as a string result.
561
+
562
+ :param obj: The `Path` to pack.
563
+ :param key: The key to use in the results dictionary.
564
+
565
+ :return: The packed result.
566
+ """
567
+ return super().pack_result(obj=str(obj), key=key)
568
+
569
+ @classmethod
570
+ def pack_path(
571
+ cls, obj: pathlib.Path, key: str, archive_format: str = DEFAULT_ARCHIVE_FORMAT
572
+ ) -> Tuple[Artifact, dict]:
573
+ """
574
+ Pack a `Path` value (pack the file or directory in that path).
575
+
576
+ :param obj: The `Path` to pack.
577
+ :param key: The key to use for the artifact.
578
+ :param archive_format: The archive format to use in case the path is of a directory. Default is zip.
579
+
580
+ :return: The packed artifact and instructions.
581
+ """
582
+ return super().pack_path(obj=str(obj), key=key, archive_format=archive_format)
583
+
584
+ @classmethod
585
+ def unpack_path(
586
+ cls, data_item: DataItem, is_directory: bool = False, archive_format: str = None
587
+ ) -> pathlib.Path:
588
+ """
589
+ Unpack a data item representing a `Path`. If the path is of a file, the file is downloaded to a local
590
+ temporary directory and its path is returned. If the path is of a directory, the archive is extracted and the
591
+ directory path extracted is returned.
592
+
593
+ :param data_item: The data item to unpack.
594
+ :param is_directory: Whether the path should be treated as a file or a directory. Files (even archives like
595
+ zip) won't be extracted.
596
+ :param archive_format: The archive format to use in case the path is of a directory. Default is None - will be
597
+ read by the archive file extension.
598
+
599
+ :return: The unpacked `Path`.
600
+ """
601
+ return pathlib.Path(
602
+ super().unpack_path(
603
+ data_item=data_item,
604
+ is_directory=is_directory,
605
+ archive_format=archive_format,
606
+ )
607
+ )
608
+
609
+
610
+ # ----------------------------------------------------------------------------------------------------------------------
611
+ # TODO: collection packagers:
612
+ # ----------------------------------------------------------------------------------------------------------------------
613
+
614
+ # ----------------------------------------------------------------------------------------------------------------------
615
+ # TODO: datetime packagers:
616
+ # ----------------------------------------------------------------------------------------------------------------------