genesis-flow 1.0.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.
Files changed (645) hide show
  1. genesis_flow-1.0.0.dist-info/METADATA +822 -0
  2. genesis_flow-1.0.0.dist-info/RECORD +645 -0
  3. genesis_flow-1.0.0.dist-info/WHEEL +5 -0
  4. genesis_flow-1.0.0.dist-info/entry_points.txt +19 -0
  5. genesis_flow-1.0.0.dist-info/licenses/LICENSE.txt +202 -0
  6. genesis_flow-1.0.0.dist-info/top_level.txt +1 -0
  7. mlflow/__init__.py +367 -0
  8. mlflow/__main__.py +3 -0
  9. mlflow/ag2/__init__.py +56 -0
  10. mlflow/ag2/ag2_logger.py +294 -0
  11. mlflow/anthropic/__init__.py +40 -0
  12. mlflow/anthropic/autolog.py +129 -0
  13. mlflow/anthropic/chat.py +144 -0
  14. mlflow/artifacts/__init__.py +268 -0
  15. mlflow/autogen/__init__.py +144 -0
  16. mlflow/autogen/chat.py +142 -0
  17. mlflow/azure/__init__.py +26 -0
  18. mlflow/azure/auth_handler.py +257 -0
  19. mlflow/azure/client.py +319 -0
  20. mlflow/azure/config.py +120 -0
  21. mlflow/azure/connection_factory.py +340 -0
  22. mlflow/azure/exceptions.py +27 -0
  23. mlflow/azure/stores.py +327 -0
  24. mlflow/azure/utils.py +183 -0
  25. mlflow/bedrock/__init__.py +45 -0
  26. mlflow/bedrock/_autolog.py +202 -0
  27. mlflow/bedrock/chat.py +122 -0
  28. mlflow/bedrock/stream.py +160 -0
  29. mlflow/bedrock/utils.py +43 -0
  30. mlflow/cli.py +707 -0
  31. mlflow/client.py +12 -0
  32. mlflow/config/__init__.py +56 -0
  33. mlflow/crewai/__init__.py +79 -0
  34. mlflow/crewai/autolog.py +253 -0
  35. mlflow/crewai/chat.py +29 -0
  36. mlflow/data/__init__.py +75 -0
  37. mlflow/data/artifact_dataset_sources.py +170 -0
  38. mlflow/data/code_dataset_source.py +40 -0
  39. mlflow/data/dataset.py +123 -0
  40. mlflow/data/dataset_registry.py +168 -0
  41. mlflow/data/dataset_source.py +110 -0
  42. mlflow/data/dataset_source_registry.py +219 -0
  43. mlflow/data/delta_dataset_source.py +167 -0
  44. mlflow/data/digest_utils.py +108 -0
  45. mlflow/data/evaluation_dataset.py +562 -0
  46. mlflow/data/filesystem_dataset_source.py +81 -0
  47. mlflow/data/http_dataset_source.py +145 -0
  48. mlflow/data/huggingface_dataset.py +258 -0
  49. mlflow/data/huggingface_dataset_source.py +118 -0
  50. mlflow/data/meta_dataset.py +104 -0
  51. mlflow/data/numpy_dataset.py +223 -0
  52. mlflow/data/pandas_dataset.py +231 -0
  53. mlflow/data/polars_dataset.py +352 -0
  54. mlflow/data/pyfunc_dataset_mixin.py +31 -0
  55. mlflow/data/schema.py +76 -0
  56. mlflow/data/sources.py +1 -0
  57. mlflow/data/spark_dataset.py +406 -0
  58. mlflow/data/spark_dataset_source.py +74 -0
  59. mlflow/data/spark_delta_utils.py +118 -0
  60. mlflow/data/tensorflow_dataset.py +350 -0
  61. mlflow/data/uc_volume_dataset_source.py +81 -0
  62. mlflow/db.py +27 -0
  63. mlflow/dspy/__init__.py +17 -0
  64. mlflow/dspy/autolog.py +197 -0
  65. mlflow/dspy/callback.py +398 -0
  66. mlflow/dspy/constant.py +1 -0
  67. mlflow/dspy/load.py +93 -0
  68. mlflow/dspy/save.py +393 -0
  69. mlflow/dspy/util.py +109 -0
  70. mlflow/dspy/wrapper.py +226 -0
  71. mlflow/entities/__init__.py +104 -0
  72. mlflow/entities/_mlflow_object.py +52 -0
  73. mlflow/entities/assessment.py +545 -0
  74. mlflow/entities/assessment_error.py +80 -0
  75. mlflow/entities/assessment_source.py +141 -0
  76. mlflow/entities/dataset.py +92 -0
  77. mlflow/entities/dataset_input.py +51 -0
  78. mlflow/entities/dataset_summary.py +62 -0
  79. mlflow/entities/document.py +48 -0
  80. mlflow/entities/experiment.py +109 -0
  81. mlflow/entities/experiment_tag.py +35 -0
  82. mlflow/entities/file_info.py +45 -0
  83. mlflow/entities/input_tag.py +35 -0
  84. mlflow/entities/lifecycle_stage.py +35 -0
  85. mlflow/entities/logged_model.py +228 -0
  86. mlflow/entities/logged_model_input.py +26 -0
  87. mlflow/entities/logged_model_output.py +32 -0
  88. mlflow/entities/logged_model_parameter.py +46 -0
  89. mlflow/entities/logged_model_status.py +74 -0
  90. mlflow/entities/logged_model_tag.py +33 -0
  91. mlflow/entities/metric.py +200 -0
  92. mlflow/entities/model_registry/__init__.py +29 -0
  93. mlflow/entities/model_registry/_model_registry_entity.py +13 -0
  94. mlflow/entities/model_registry/model_version.py +243 -0
  95. mlflow/entities/model_registry/model_version_deployment_job_run_state.py +44 -0
  96. mlflow/entities/model_registry/model_version_deployment_job_state.py +70 -0
  97. mlflow/entities/model_registry/model_version_search.py +25 -0
  98. mlflow/entities/model_registry/model_version_stages.py +25 -0
  99. mlflow/entities/model_registry/model_version_status.py +35 -0
  100. mlflow/entities/model_registry/model_version_tag.py +35 -0
  101. mlflow/entities/model_registry/prompt.py +73 -0
  102. mlflow/entities/model_registry/prompt_version.py +244 -0
  103. mlflow/entities/model_registry/registered_model.py +175 -0
  104. mlflow/entities/model_registry/registered_model_alias.py +35 -0
  105. mlflow/entities/model_registry/registered_model_deployment_job_state.py +39 -0
  106. mlflow/entities/model_registry/registered_model_search.py +25 -0
  107. mlflow/entities/model_registry/registered_model_tag.py +35 -0
  108. mlflow/entities/multipart_upload.py +74 -0
  109. mlflow/entities/param.py +49 -0
  110. mlflow/entities/run.py +97 -0
  111. mlflow/entities/run_data.py +84 -0
  112. mlflow/entities/run_info.py +188 -0
  113. mlflow/entities/run_inputs.py +59 -0
  114. mlflow/entities/run_outputs.py +43 -0
  115. mlflow/entities/run_status.py +41 -0
  116. mlflow/entities/run_tag.py +36 -0
  117. mlflow/entities/source_type.py +31 -0
  118. mlflow/entities/span.py +774 -0
  119. mlflow/entities/span_event.py +96 -0
  120. mlflow/entities/span_status.py +102 -0
  121. mlflow/entities/trace.py +317 -0
  122. mlflow/entities/trace_data.py +71 -0
  123. mlflow/entities/trace_info.py +220 -0
  124. mlflow/entities/trace_info_v2.py +162 -0
  125. mlflow/entities/trace_location.py +173 -0
  126. mlflow/entities/trace_state.py +39 -0
  127. mlflow/entities/trace_status.py +68 -0
  128. mlflow/entities/view_type.py +51 -0
  129. mlflow/environment_variables.py +866 -0
  130. mlflow/evaluation/__init__.py +16 -0
  131. mlflow/evaluation/assessment.py +369 -0
  132. mlflow/evaluation/evaluation.py +411 -0
  133. mlflow/evaluation/evaluation_tag.py +61 -0
  134. mlflow/evaluation/fluent.py +48 -0
  135. mlflow/evaluation/utils.py +201 -0
  136. mlflow/exceptions.py +213 -0
  137. mlflow/experiments.py +140 -0
  138. mlflow/gemini/__init__.py +81 -0
  139. mlflow/gemini/autolog.py +186 -0
  140. mlflow/gemini/chat.py +261 -0
  141. mlflow/genai/__init__.py +71 -0
  142. mlflow/genai/datasets/__init__.py +67 -0
  143. mlflow/genai/datasets/evaluation_dataset.py +131 -0
  144. mlflow/genai/evaluation/__init__.py +3 -0
  145. mlflow/genai/evaluation/base.py +411 -0
  146. mlflow/genai/evaluation/constant.py +23 -0
  147. mlflow/genai/evaluation/utils.py +244 -0
  148. mlflow/genai/judges/__init__.py +21 -0
  149. mlflow/genai/judges/databricks.py +404 -0
  150. mlflow/genai/label_schemas/__init__.py +153 -0
  151. mlflow/genai/label_schemas/label_schemas.py +209 -0
  152. mlflow/genai/labeling/__init__.py +159 -0
  153. mlflow/genai/labeling/labeling.py +250 -0
  154. mlflow/genai/optimize/__init__.py +13 -0
  155. mlflow/genai/optimize/base.py +198 -0
  156. mlflow/genai/optimize/optimizers/__init__.py +4 -0
  157. mlflow/genai/optimize/optimizers/base_optimizer.py +38 -0
  158. mlflow/genai/optimize/optimizers/dspy_mipro_optimizer.py +221 -0
  159. mlflow/genai/optimize/optimizers/dspy_optimizer.py +91 -0
  160. mlflow/genai/optimize/optimizers/utils/dspy_mipro_callback.py +76 -0
  161. mlflow/genai/optimize/optimizers/utils/dspy_mipro_utils.py +18 -0
  162. mlflow/genai/optimize/types.py +75 -0
  163. mlflow/genai/optimize/util.py +30 -0
  164. mlflow/genai/prompts/__init__.py +206 -0
  165. mlflow/genai/scheduled_scorers.py +431 -0
  166. mlflow/genai/scorers/__init__.py +26 -0
  167. mlflow/genai/scorers/base.py +492 -0
  168. mlflow/genai/scorers/builtin_scorers.py +765 -0
  169. mlflow/genai/scorers/scorer_utils.py +138 -0
  170. mlflow/genai/scorers/validation.py +165 -0
  171. mlflow/genai/utils/data_validation.py +146 -0
  172. mlflow/genai/utils/enum_utils.py +23 -0
  173. mlflow/genai/utils/trace_utils.py +211 -0
  174. mlflow/groq/__init__.py +42 -0
  175. mlflow/groq/_groq_autolog.py +74 -0
  176. mlflow/johnsnowlabs/__init__.py +888 -0
  177. mlflow/langchain/__init__.py +24 -0
  178. mlflow/langchain/api_request_parallel_processor.py +330 -0
  179. mlflow/langchain/autolog.py +147 -0
  180. mlflow/langchain/chat_agent_langgraph.py +340 -0
  181. mlflow/langchain/constant.py +1 -0
  182. mlflow/langchain/constants.py +1 -0
  183. mlflow/langchain/databricks_dependencies.py +444 -0
  184. mlflow/langchain/langchain_tracer.py +597 -0
  185. mlflow/langchain/model.py +919 -0
  186. mlflow/langchain/output_parsers.py +142 -0
  187. mlflow/langchain/retriever_chain.py +153 -0
  188. mlflow/langchain/runnables.py +527 -0
  189. mlflow/langchain/utils/chat.py +402 -0
  190. mlflow/langchain/utils/logging.py +671 -0
  191. mlflow/langchain/utils/serialization.py +36 -0
  192. mlflow/legacy_databricks_cli/__init__.py +0 -0
  193. mlflow/legacy_databricks_cli/configure/__init__.py +0 -0
  194. mlflow/legacy_databricks_cli/configure/provider.py +482 -0
  195. mlflow/litellm/__init__.py +175 -0
  196. mlflow/llama_index/__init__.py +22 -0
  197. mlflow/llama_index/autolog.py +55 -0
  198. mlflow/llama_index/chat.py +43 -0
  199. mlflow/llama_index/constant.py +1 -0
  200. mlflow/llama_index/model.py +577 -0
  201. mlflow/llama_index/pyfunc_wrapper.py +332 -0
  202. mlflow/llama_index/serialize_objects.py +188 -0
  203. mlflow/llama_index/tracer.py +561 -0
  204. mlflow/metrics/__init__.py +479 -0
  205. mlflow/metrics/base.py +39 -0
  206. mlflow/metrics/genai/__init__.py +25 -0
  207. mlflow/metrics/genai/base.py +101 -0
  208. mlflow/metrics/genai/genai_metric.py +771 -0
  209. mlflow/metrics/genai/metric_definitions.py +450 -0
  210. mlflow/metrics/genai/model_utils.py +371 -0
  211. mlflow/metrics/genai/prompt_template.py +68 -0
  212. mlflow/metrics/genai/prompts/__init__.py +0 -0
  213. mlflow/metrics/genai/prompts/v1.py +422 -0
  214. mlflow/metrics/genai/utils.py +6 -0
  215. mlflow/metrics/metric_definitions.py +619 -0
  216. mlflow/mismatch.py +34 -0
  217. mlflow/mistral/__init__.py +34 -0
  218. mlflow/mistral/autolog.py +71 -0
  219. mlflow/mistral/chat.py +135 -0
  220. mlflow/ml_package_versions.py +452 -0
  221. mlflow/models/__init__.py +97 -0
  222. mlflow/models/auth_policy.py +83 -0
  223. mlflow/models/cli.py +354 -0
  224. mlflow/models/container/__init__.py +294 -0
  225. mlflow/models/container/scoring_server/__init__.py +0 -0
  226. mlflow/models/container/scoring_server/nginx.conf +39 -0
  227. mlflow/models/dependencies_schemas.py +287 -0
  228. mlflow/models/display_utils.py +158 -0
  229. mlflow/models/docker_utils.py +211 -0
  230. mlflow/models/evaluation/__init__.py +23 -0
  231. mlflow/models/evaluation/_shap_patch.py +64 -0
  232. mlflow/models/evaluation/artifacts.py +194 -0
  233. mlflow/models/evaluation/base.py +1811 -0
  234. mlflow/models/evaluation/calibration_curve.py +109 -0
  235. mlflow/models/evaluation/default_evaluator.py +996 -0
  236. mlflow/models/evaluation/deprecated.py +23 -0
  237. mlflow/models/evaluation/evaluator_registry.py +80 -0
  238. mlflow/models/evaluation/evaluators/classifier.py +704 -0
  239. mlflow/models/evaluation/evaluators/default.py +233 -0
  240. mlflow/models/evaluation/evaluators/regressor.py +96 -0
  241. mlflow/models/evaluation/evaluators/shap.py +296 -0
  242. mlflow/models/evaluation/lift_curve.py +178 -0
  243. mlflow/models/evaluation/utils/metric.py +123 -0
  244. mlflow/models/evaluation/utils/trace.py +179 -0
  245. mlflow/models/evaluation/validation.py +434 -0
  246. mlflow/models/flavor_backend.py +93 -0
  247. mlflow/models/flavor_backend_registry.py +53 -0
  248. mlflow/models/model.py +1639 -0
  249. mlflow/models/model_config.py +150 -0
  250. mlflow/models/notebook_resources/agent_evaluation_template.html +235 -0
  251. mlflow/models/notebook_resources/eval_with_dataset_example.py +22 -0
  252. mlflow/models/notebook_resources/eval_with_synthetic_example.py +22 -0
  253. mlflow/models/python_api.py +369 -0
  254. mlflow/models/rag_signatures.py +128 -0
  255. mlflow/models/resources.py +321 -0
  256. mlflow/models/signature.py +662 -0
  257. mlflow/models/utils.py +2054 -0
  258. mlflow/models/wheeled_model.py +280 -0
  259. mlflow/openai/__init__.py +57 -0
  260. mlflow/openai/_agent_tracer.py +364 -0
  261. mlflow/openai/api_request_parallel_processor.py +131 -0
  262. mlflow/openai/autolog.py +509 -0
  263. mlflow/openai/constant.py +1 -0
  264. mlflow/openai/model.py +824 -0
  265. mlflow/openai/utils/chat_schema.py +367 -0
  266. mlflow/optuna/__init__.py +3 -0
  267. mlflow/optuna/storage.py +646 -0
  268. mlflow/plugins/__init__.py +72 -0
  269. mlflow/plugins/base.py +358 -0
  270. mlflow/plugins/builtin/__init__.py +24 -0
  271. mlflow/plugins/builtin/pytorch_plugin.py +150 -0
  272. mlflow/plugins/builtin/sklearn_plugin.py +158 -0
  273. mlflow/plugins/builtin/transformers_plugin.py +187 -0
  274. mlflow/plugins/cli.py +321 -0
  275. mlflow/plugins/discovery.py +340 -0
  276. mlflow/plugins/manager.py +465 -0
  277. mlflow/plugins/registry.py +316 -0
  278. mlflow/plugins/templates/framework_plugin_template.py +329 -0
  279. mlflow/prompt/constants.py +20 -0
  280. mlflow/prompt/promptlab_model.py +197 -0
  281. mlflow/prompt/registry_utils.py +248 -0
  282. mlflow/promptflow/__init__.py +495 -0
  283. mlflow/protos/__init__.py +0 -0
  284. mlflow/protos/assessments_pb2.py +174 -0
  285. mlflow/protos/databricks_artifacts_pb2.py +489 -0
  286. mlflow/protos/databricks_filesystem_service_pb2.py +196 -0
  287. mlflow/protos/databricks_managed_catalog_messages_pb2.py +95 -0
  288. mlflow/protos/databricks_managed_catalog_service_pb2.py +86 -0
  289. mlflow/protos/databricks_pb2.py +267 -0
  290. mlflow/protos/databricks_trace_server_pb2.py +374 -0
  291. mlflow/protos/databricks_uc_registry_messages_pb2.py +1249 -0
  292. mlflow/protos/databricks_uc_registry_service_pb2.py +170 -0
  293. mlflow/protos/facet_feature_statistics_pb2.py +296 -0
  294. mlflow/protos/internal_pb2.py +77 -0
  295. mlflow/protos/mlflow_artifacts_pb2.py +336 -0
  296. mlflow/protos/model_registry_pb2.py +1073 -0
  297. mlflow/protos/scalapb/__init__.py +0 -0
  298. mlflow/protos/scalapb/scalapb_pb2.py +104 -0
  299. mlflow/protos/service_pb2.py +2600 -0
  300. mlflow/protos/unity_catalog_oss_messages_pb2.py +457 -0
  301. mlflow/protos/unity_catalog_oss_service_pb2.py +130 -0
  302. mlflow/protos/unity_catalog_prompt_messages_pb2.py +447 -0
  303. mlflow/protos/unity_catalog_prompt_messages_pb2_grpc.py +24 -0
  304. mlflow/protos/unity_catalog_prompt_service_pb2.py +164 -0
  305. mlflow/protos/unity_catalog_prompt_service_pb2_grpc.py +785 -0
  306. mlflow/py.typed +0 -0
  307. mlflow/pydantic_ai/__init__.py +57 -0
  308. mlflow/pydantic_ai/autolog.py +173 -0
  309. mlflow/pyfunc/__init__.py +3844 -0
  310. mlflow/pyfunc/_mlflow_pyfunc_backend_predict.py +61 -0
  311. mlflow/pyfunc/backend.py +523 -0
  312. mlflow/pyfunc/context.py +78 -0
  313. mlflow/pyfunc/dbconnect_artifact_cache.py +144 -0
  314. mlflow/pyfunc/loaders/__init__.py +7 -0
  315. mlflow/pyfunc/loaders/chat_agent.py +117 -0
  316. mlflow/pyfunc/loaders/chat_model.py +125 -0
  317. mlflow/pyfunc/loaders/code_model.py +31 -0
  318. mlflow/pyfunc/loaders/responses_agent.py +112 -0
  319. mlflow/pyfunc/mlserver.py +46 -0
  320. mlflow/pyfunc/model.py +1473 -0
  321. mlflow/pyfunc/scoring_server/__init__.py +604 -0
  322. mlflow/pyfunc/scoring_server/app.py +7 -0
  323. mlflow/pyfunc/scoring_server/client.py +146 -0
  324. mlflow/pyfunc/spark_model_cache.py +48 -0
  325. mlflow/pyfunc/stdin_server.py +44 -0
  326. mlflow/pyfunc/utils/__init__.py +3 -0
  327. mlflow/pyfunc/utils/data_validation.py +224 -0
  328. mlflow/pyfunc/utils/environment.py +22 -0
  329. mlflow/pyfunc/utils/input_converter.py +47 -0
  330. mlflow/pyfunc/utils/serving_data_parser.py +11 -0
  331. mlflow/pytorch/__init__.py +1171 -0
  332. mlflow/pytorch/_lightning_autolog.py +580 -0
  333. mlflow/pytorch/_pytorch_autolog.py +50 -0
  334. mlflow/pytorch/pickle_module.py +35 -0
  335. mlflow/rfunc/__init__.py +42 -0
  336. mlflow/rfunc/backend.py +134 -0
  337. mlflow/runs.py +89 -0
  338. mlflow/server/__init__.py +302 -0
  339. mlflow/server/auth/__init__.py +1224 -0
  340. mlflow/server/auth/__main__.py +4 -0
  341. mlflow/server/auth/basic_auth.ini +6 -0
  342. mlflow/server/auth/cli.py +11 -0
  343. mlflow/server/auth/client.py +537 -0
  344. mlflow/server/auth/config.py +34 -0
  345. mlflow/server/auth/db/__init__.py +0 -0
  346. mlflow/server/auth/db/cli.py +18 -0
  347. mlflow/server/auth/db/migrations/__init__.py +0 -0
  348. mlflow/server/auth/db/migrations/alembic.ini +110 -0
  349. mlflow/server/auth/db/migrations/env.py +76 -0
  350. mlflow/server/auth/db/migrations/versions/8606fa83a998_initial_migration.py +51 -0
  351. mlflow/server/auth/db/migrations/versions/__init__.py +0 -0
  352. mlflow/server/auth/db/models.py +67 -0
  353. mlflow/server/auth/db/utils.py +37 -0
  354. mlflow/server/auth/entities.py +165 -0
  355. mlflow/server/auth/logo.py +14 -0
  356. mlflow/server/auth/permissions.py +65 -0
  357. mlflow/server/auth/routes.py +18 -0
  358. mlflow/server/auth/sqlalchemy_store.py +263 -0
  359. mlflow/server/graphql/__init__.py +0 -0
  360. mlflow/server/graphql/autogenerated_graphql_schema.py +353 -0
  361. mlflow/server/graphql/graphql_custom_scalars.py +24 -0
  362. mlflow/server/graphql/graphql_errors.py +15 -0
  363. mlflow/server/graphql/graphql_no_batching.py +89 -0
  364. mlflow/server/graphql/graphql_schema_extensions.py +74 -0
  365. mlflow/server/handlers.py +3217 -0
  366. mlflow/server/prometheus_exporter.py +17 -0
  367. mlflow/server/validation.py +30 -0
  368. mlflow/shap/__init__.py +691 -0
  369. mlflow/sklearn/__init__.py +1994 -0
  370. mlflow/sklearn/utils.py +1041 -0
  371. mlflow/smolagents/__init__.py +66 -0
  372. mlflow/smolagents/autolog.py +139 -0
  373. mlflow/smolagents/chat.py +29 -0
  374. mlflow/store/__init__.py +10 -0
  375. mlflow/store/_unity_catalog/__init__.py +1 -0
  376. mlflow/store/_unity_catalog/lineage/__init__.py +1 -0
  377. mlflow/store/_unity_catalog/lineage/constants.py +2 -0
  378. mlflow/store/_unity_catalog/registry/__init__.py +6 -0
  379. mlflow/store/_unity_catalog/registry/prompt_info.py +75 -0
  380. mlflow/store/_unity_catalog/registry/rest_store.py +1740 -0
  381. mlflow/store/_unity_catalog/registry/uc_oss_rest_store.py +507 -0
  382. mlflow/store/_unity_catalog/registry/utils.py +121 -0
  383. mlflow/store/artifact/__init__.py +0 -0
  384. mlflow/store/artifact/artifact_repo.py +472 -0
  385. mlflow/store/artifact/artifact_repository_registry.py +154 -0
  386. mlflow/store/artifact/azure_blob_artifact_repo.py +275 -0
  387. mlflow/store/artifact/azure_data_lake_artifact_repo.py +295 -0
  388. mlflow/store/artifact/cli.py +141 -0
  389. mlflow/store/artifact/cloud_artifact_repo.py +332 -0
  390. mlflow/store/artifact/databricks_artifact_repo.py +729 -0
  391. mlflow/store/artifact/databricks_artifact_repo_resources.py +301 -0
  392. mlflow/store/artifact/databricks_logged_model_artifact_repo.py +93 -0
  393. mlflow/store/artifact/databricks_models_artifact_repo.py +216 -0
  394. mlflow/store/artifact/databricks_sdk_artifact_repo.py +134 -0
  395. mlflow/store/artifact/databricks_sdk_models_artifact_repo.py +97 -0
  396. mlflow/store/artifact/dbfs_artifact_repo.py +240 -0
  397. mlflow/store/artifact/ftp_artifact_repo.py +132 -0
  398. mlflow/store/artifact/gcs_artifact_repo.py +296 -0
  399. mlflow/store/artifact/hdfs_artifact_repo.py +209 -0
  400. mlflow/store/artifact/http_artifact_repo.py +218 -0
  401. mlflow/store/artifact/local_artifact_repo.py +142 -0
  402. mlflow/store/artifact/mlflow_artifacts_repo.py +94 -0
  403. mlflow/store/artifact/models_artifact_repo.py +259 -0
  404. mlflow/store/artifact/optimized_s3_artifact_repo.py +356 -0
  405. mlflow/store/artifact/presigned_url_artifact_repo.py +173 -0
  406. mlflow/store/artifact/r2_artifact_repo.py +70 -0
  407. mlflow/store/artifact/runs_artifact_repo.py +265 -0
  408. mlflow/store/artifact/s3_artifact_repo.py +330 -0
  409. mlflow/store/artifact/sftp_artifact_repo.py +141 -0
  410. mlflow/store/artifact/uc_volume_artifact_repo.py +76 -0
  411. mlflow/store/artifact/unity_catalog_models_artifact_repo.py +168 -0
  412. mlflow/store/artifact/unity_catalog_oss_models_artifact_repo.py +168 -0
  413. mlflow/store/artifact/utils/__init__.py +0 -0
  414. mlflow/store/artifact/utils/models.py +148 -0
  415. mlflow/store/db/__init__.py +0 -0
  416. mlflow/store/db/base_sql_model.py +3 -0
  417. mlflow/store/db/db_types.py +10 -0
  418. mlflow/store/db/utils.py +314 -0
  419. mlflow/store/db_migrations/__init__.py +0 -0
  420. mlflow/store/db_migrations/alembic.ini +74 -0
  421. mlflow/store/db_migrations/env.py +84 -0
  422. mlflow/store/db_migrations/versions/0584bdc529eb_add_cascading_deletion_to_datasets_from_experiments.py +88 -0
  423. mlflow/store/db_migrations/versions/0a8213491aaa_drop_duplicate_killed_constraint.py +49 -0
  424. mlflow/store/db_migrations/versions/0c779009ac13_add_deleted_time_field_to_runs_table.py +24 -0
  425. mlflow/store/db_migrations/versions/181f10493468_allow_nulls_for_metric_values.py +35 -0
  426. mlflow/store/db_migrations/versions/27a6a02d2cf1_add_model_version_tags_table.py +38 -0
  427. mlflow/store/db_migrations/versions/2b4d017a5e9b_add_model_registry_tables_to_db.py +77 -0
  428. mlflow/store/db_migrations/versions/2d6e25af4d3e_increase_max_param_val_length.py +33 -0
  429. mlflow/store/db_migrations/versions/3500859a5d39_add_model_aliases_table.py +50 -0
  430. mlflow/store/db_migrations/versions/39d1c3be5f05_add_is_nan_constraint_for_metrics_tables_if_necessary.py +41 -0
  431. mlflow/store/db_migrations/versions/400f98739977_add_logged_model_tables.py +123 -0
  432. mlflow/store/db_migrations/versions/4465047574b1_increase_max_dataset_schema_size.py +38 -0
  433. mlflow/store/db_migrations/versions/451aebb31d03_add_metric_step.py +35 -0
  434. mlflow/store/db_migrations/versions/5b0e9adcef9c_add_cascade_deletion_to_trace_tables_fk.py +40 -0
  435. mlflow/store/db_migrations/versions/6953534de441_add_step_to_inputs_table.py +25 -0
  436. mlflow/store/db_migrations/versions/728d730b5ebd_add_registered_model_tags_table.py +38 -0
  437. mlflow/store/db_migrations/versions/7ac759974ad8_update_run_tags_with_larger_limit.py +36 -0
  438. mlflow/store/db_migrations/versions/7f2a7d5fae7d_add_datasets_inputs_input_tags_tables.py +82 -0
  439. mlflow/store/db_migrations/versions/84291f40a231_add_run_link_to_model_version.py +26 -0
  440. mlflow/store/db_migrations/versions/867495a8f9d4_add_trace_tables.py +90 -0
  441. mlflow/store/db_migrations/versions/89d4b8295536_create_latest_metrics_table.py +169 -0
  442. mlflow/store/db_migrations/versions/90e64c465722_migrate_user_column_to_tags.py +64 -0
  443. mlflow/store/db_migrations/versions/97727af70f4d_creation_time_last_update_time_experiments.py +25 -0
  444. mlflow/store/db_migrations/versions/__init__.py +0 -0
  445. mlflow/store/db_migrations/versions/a8c4a736bde6_allow_nulls_for_run_id.py +27 -0
  446. mlflow/store/db_migrations/versions/acf3f17fdcc7_add_storage_location_field_to_model_.py +29 -0
  447. mlflow/store/db_migrations/versions/bd07f7e963c5_create_index_on_run_uuid.py +26 -0
  448. mlflow/store/db_migrations/versions/bda7b8c39065_increase_model_version_tag_value_limit.py +38 -0
  449. mlflow/store/db_migrations/versions/c48cb773bb87_reset_default_value_for_is_nan_in_metrics_table_for_mysql.py +41 -0
  450. mlflow/store/db_migrations/versions/cbc13b556ace_add_v3_trace_schema_columns.py +31 -0
  451. mlflow/store/db_migrations/versions/cc1f77228345_change_param_value_length_to_500.py +34 -0
  452. mlflow/store/db_migrations/versions/cfd24bdc0731_update_run_status_constraint_with_killed.py +78 -0
  453. mlflow/store/db_migrations/versions/df50e92ffc5e_add_experiment_tags_table.py +38 -0
  454. mlflow/store/db_migrations/versions/f5a4f2784254_increase_run_tag_value_limit.py +36 -0
  455. mlflow/store/entities/__init__.py +3 -0
  456. mlflow/store/entities/paged_list.py +18 -0
  457. mlflow/store/model_registry/__init__.py +10 -0
  458. mlflow/store/model_registry/abstract_store.py +1081 -0
  459. mlflow/store/model_registry/base_rest_store.py +44 -0
  460. mlflow/store/model_registry/databricks_workspace_model_registry_rest_store.py +37 -0
  461. mlflow/store/model_registry/dbmodels/__init__.py +0 -0
  462. mlflow/store/model_registry/dbmodels/models.py +206 -0
  463. mlflow/store/model_registry/file_store.py +1091 -0
  464. mlflow/store/model_registry/rest_store.py +481 -0
  465. mlflow/store/model_registry/sqlalchemy_store.py +1286 -0
  466. mlflow/store/tracking/__init__.py +23 -0
  467. mlflow/store/tracking/abstract_store.py +816 -0
  468. mlflow/store/tracking/dbmodels/__init__.py +0 -0
  469. mlflow/store/tracking/dbmodels/initial_models.py +243 -0
  470. mlflow/store/tracking/dbmodels/models.py +1073 -0
  471. mlflow/store/tracking/file_store.py +2438 -0
  472. mlflow/store/tracking/postgres_managed_identity.py +146 -0
  473. mlflow/store/tracking/rest_store.py +1131 -0
  474. mlflow/store/tracking/sqlalchemy_store.py +2785 -0
  475. mlflow/system_metrics/__init__.py +61 -0
  476. mlflow/system_metrics/metrics/__init__.py +0 -0
  477. mlflow/system_metrics/metrics/base_metrics_monitor.py +32 -0
  478. mlflow/system_metrics/metrics/cpu_monitor.py +23 -0
  479. mlflow/system_metrics/metrics/disk_monitor.py +21 -0
  480. mlflow/system_metrics/metrics/gpu_monitor.py +71 -0
  481. mlflow/system_metrics/metrics/network_monitor.py +34 -0
  482. mlflow/system_metrics/metrics/rocm_monitor.py +123 -0
  483. mlflow/system_metrics/system_metrics_monitor.py +198 -0
  484. mlflow/tracing/__init__.py +16 -0
  485. mlflow/tracing/assessment.py +356 -0
  486. mlflow/tracing/client.py +531 -0
  487. mlflow/tracing/config.py +125 -0
  488. mlflow/tracing/constant.py +105 -0
  489. mlflow/tracing/destination.py +81 -0
  490. mlflow/tracing/display/__init__.py +40 -0
  491. mlflow/tracing/display/display_handler.py +196 -0
  492. mlflow/tracing/export/async_export_queue.py +186 -0
  493. mlflow/tracing/export/inference_table.py +138 -0
  494. mlflow/tracing/export/mlflow_v3.py +137 -0
  495. mlflow/tracing/export/utils.py +70 -0
  496. mlflow/tracing/fluent.py +1417 -0
  497. mlflow/tracing/processor/base_mlflow.py +199 -0
  498. mlflow/tracing/processor/inference_table.py +175 -0
  499. mlflow/tracing/processor/mlflow_v3.py +47 -0
  500. mlflow/tracing/processor/otel.py +73 -0
  501. mlflow/tracing/provider.py +487 -0
  502. mlflow/tracing/trace_manager.py +200 -0
  503. mlflow/tracing/utils/__init__.py +616 -0
  504. mlflow/tracing/utils/artifact_utils.py +28 -0
  505. mlflow/tracing/utils/copy.py +55 -0
  506. mlflow/tracing/utils/environment.py +55 -0
  507. mlflow/tracing/utils/exception.py +21 -0
  508. mlflow/tracing/utils/once.py +35 -0
  509. mlflow/tracing/utils/otlp.py +63 -0
  510. mlflow/tracing/utils/processor.py +54 -0
  511. mlflow/tracing/utils/search.py +292 -0
  512. mlflow/tracing/utils/timeout.py +250 -0
  513. mlflow/tracing/utils/token.py +19 -0
  514. mlflow/tracing/utils/truncation.py +124 -0
  515. mlflow/tracing/utils/warning.py +76 -0
  516. mlflow/tracking/__init__.py +39 -0
  517. mlflow/tracking/_model_registry/__init__.py +1 -0
  518. mlflow/tracking/_model_registry/client.py +764 -0
  519. mlflow/tracking/_model_registry/fluent.py +853 -0
  520. mlflow/tracking/_model_registry/registry.py +67 -0
  521. mlflow/tracking/_model_registry/utils.py +251 -0
  522. mlflow/tracking/_tracking_service/__init__.py +0 -0
  523. mlflow/tracking/_tracking_service/client.py +883 -0
  524. mlflow/tracking/_tracking_service/registry.py +56 -0
  525. mlflow/tracking/_tracking_service/utils.py +275 -0
  526. mlflow/tracking/artifact_utils.py +179 -0
  527. mlflow/tracking/client.py +5900 -0
  528. mlflow/tracking/context/__init__.py +0 -0
  529. mlflow/tracking/context/abstract_context.py +35 -0
  530. mlflow/tracking/context/databricks_cluster_context.py +15 -0
  531. mlflow/tracking/context/databricks_command_context.py +15 -0
  532. mlflow/tracking/context/databricks_job_context.py +49 -0
  533. mlflow/tracking/context/databricks_notebook_context.py +41 -0
  534. mlflow/tracking/context/databricks_repo_context.py +43 -0
  535. mlflow/tracking/context/default_context.py +51 -0
  536. mlflow/tracking/context/git_context.py +32 -0
  537. mlflow/tracking/context/registry.py +98 -0
  538. mlflow/tracking/context/system_environment_context.py +15 -0
  539. mlflow/tracking/default_experiment/__init__.py +1 -0
  540. mlflow/tracking/default_experiment/abstract_context.py +43 -0
  541. mlflow/tracking/default_experiment/databricks_notebook_experiment_provider.py +44 -0
  542. mlflow/tracking/default_experiment/registry.py +75 -0
  543. mlflow/tracking/fluent.py +3595 -0
  544. mlflow/tracking/metric_value_conversion_utils.py +93 -0
  545. mlflow/tracking/multimedia.py +206 -0
  546. mlflow/tracking/registry.py +86 -0
  547. mlflow/tracking/request_auth/__init__.py +0 -0
  548. mlflow/tracking/request_auth/abstract_request_auth_provider.py +34 -0
  549. mlflow/tracking/request_auth/registry.py +60 -0
  550. mlflow/tracking/request_header/__init__.py +0 -0
  551. mlflow/tracking/request_header/abstract_request_header_provider.py +36 -0
  552. mlflow/tracking/request_header/databricks_request_header_provider.py +38 -0
  553. mlflow/tracking/request_header/default_request_header_provider.py +17 -0
  554. mlflow/tracking/request_header/registry.py +79 -0
  555. mlflow/transformers/__init__.py +2982 -0
  556. mlflow/transformers/flavor_config.py +258 -0
  557. mlflow/transformers/hub_utils.py +83 -0
  558. mlflow/transformers/llm_inference_utils.py +468 -0
  559. mlflow/transformers/model_io.py +301 -0
  560. mlflow/transformers/peft.py +51 -0
  561. mlflow/transformers/signature.py +183 -0
  562. mlflow/transformers/torch_utils.py +55 -0
  563. mlflow/types/__init__.py +21 -0
  564. mlflow/types/agent.py +270 -0
  565. mlflow/types/chat.py +240 -0
  566. mlflow/types/llm.py +935 -0
  567. mlflow/types/responses.py +139 -0
  568. mlflow/types/responses_helpers.py +416 -0
  569. mlflow/types/schema.py +1505 -0
  570. mlflow/types/type_hints.py +647 -0
  571. mlflow/types/utils.py +753 -0
  572. mlflow/utils/__init__.py +283 -0
  573. mlflow/utils/_capture_modules.py +256 -0
  574. mlflow/utils/_capture_transformers_modules.py +75 -0
  575. mlflow/utils/_spark_utils.py +201 -0
  576. mlflow/utils/_unity_catalog_oss_utils.py +97 -0
  577. mlflow/utils/_unity_catalog_utils.py +479 -0
  578. mlflow/utils/annotations.py +218 -0
  579. mlflow/utils/arguments_utils.py +16 -0
  580. mlflow/utils/async_logging/__init__.py +1 -0
  581. mlflow/utils/async_logging/async_artifacts_logging_queue.py +258 -0
  582. mlflow/utils/async_logging/async_logging_queue.py +366 -0
  583. mlflow/utils/async_logging/run_artifact.py +38 -0
  584. mlflow/utils/async_logging/run_batch.py +58 -0
  585. mlflow/utils/async_logging/run_operations.py +49 -0
  586. mlflow/utils/autologging_utils/__init__.py +737 -0
  587. mlflow/utils/autologging_utils/client.py +432 -0
  588. mlflow/utils/autologging_utils/config.py +33 -0
  589. mlflow/utils/autologging_utils/events.py +294 -0
  590. mlflow/utils/autologging_utils/logging_and_warnings.py +328 -0
  591. mlflow/utils/autologging_utils/metrics_queue.py +71 -0
  592. mlflow/utils/autologging_utils/safety.py +1104 -0
  593. mlflow/utils/autologging_utils/versioning.py +95 -0
  594. mlflow/utils/checkpoint_utils.py +206 -0
  595. mlflow/utils/class_utils.py +6 -0
  596. mlflow/utils/cli_args.py +257 -0
  597. mlflow/utils/conda.py +354 -0
  598. mlflow/utils/credentials.py +231 -0
  599. mlflow/utils/data_utils.py +17 -0
  600. mlflow/utils/databricks_utils.py +1436 -0
  601. mlflow/utils/docstring_utils.py +477 -0
  602. mlflow/utils/doctor.py +133 -0
  603. mlflow/utils/download_cloud_file_chunk.py +43 -0
  604. mlflow/utils/env_manager.py +16 -0
  605. mlflow/utils/env_pack.py +131 -0
  606. mlflow/utils/environment.py +1009 -0
  607. mlflow/utils/exception_utils.py +14 -0
  608. mlflow/utils/file_utils.py +978 -0
  609. mlflow/utils/git_utils.py +77 -0
  610. mlflow/utils/gorilla.py +797 -0
  611. mlflow/utils/import_hooks/__init__.py +363 -0
  612. mlflow/utils/lazy_load.py +51 -0
  613. mlflow/utils/logging_utils.py +168 -0
  614. mlflow/utils/mime_type_utils.py +58 -0
  615. mlflow/utils/mlflow_tags.py +103 -0
  616. mlflow/utils/model_utils.py +486 -0
  617. mlflow/utils/name_utils.py +346 -0
  618. mlflow/utils/nfs_on_spark.py +62 -0
  619. mlflow/utils/openai_utils.py +164 -0
  620. mlflow/utils/os.py +12 -0
  621. mlflow/utils/oss_registry_utils.py +29 -0
  622. mlflow/utils/plugins.py +17 -0
  623. mlflow/utils/process.py +182 -0
  624. mlflow/utils/promptlab_utils.py +146 -0
  625. mlflow/utils/proto_json_utils.py +743 -0
  626. mlflow/utils/pydantic_utils.py +54 -0
  627. mlflow/utils/request_utils.py +279 -0
  628. mlflow/utils/requirements_utils.py +704 -0
  629. mlflow/utils/rest_utils.py +673 -0
  630. mlflow/utils/search_logged_model_utils.py +127 -0
  631. mlflow/utils/search_utils.py +2111 -0
  632. mlflow/utils/secure_loading.py +221 -0
  633. mlflow/utils/security_validation.py +384 -0
  634. mlflow/utils/server_cli_utils.py +61 -0
  635. mlflow/utils/spark_utils.py +15 -0
  636. mlflow/utils/string_utils.py +138 -0
  637. mlflow/utils/thread_utils.py +63 -0
  638. mlflow/utils/time.py +54 -0
  639. mlflow/utils/timeout.py +42 -0
  640. mlflow/utils/uri.py +572 -0
  641. mlflow/utils/validation.py +662 -0
  642. mlflow/utils/virtualenv.py +458 -0
  643. mlflow/utils/warnings_utils.py +25 -0
  644. mlflow/utils/yaml_utils.py +179 -0
  645. mlflow/version.py +24 -0
@@ -0,0 +1,330 @@
1
+ import json
2
+ import os
3
+ import posixpath
4
+ import urllib.parse
5
+ from datetime import datetime
6
+ from functools import lru_cache
7
+ from mimetypes import guess_type
8
+ from typing import Optional
9
+
10
+ from mlflow.entities import FileInfo
11
+ from mlflow.entities.multipart_upload import (
12
+ CreateMultipartUploadResponse,
13
+ MultipartUploadCredential,
14
+ )
15
+ from mlflow.environment_variables import (
16
+ MLFLOW_BOTO_CLIENT_ADDRESSING_STYLE,
17
+ MLFLOW_S3_ENDPOINT_URL,
18
+ MLFLOW_S3_IGNORE_TLS,
19
+ MLFLOW_S3_UPLOAD_EXTRA_ARGS,
20
+ )
21
+ from mlflow.exceptions import MlflowException
22
+ from mlflow.store.artifact.artifact_repo import (
23
+ ArtifactRepository,
24
+ MultipartUploadMixin,
25
+ )
26
+ from mlflow.utils.file_utils import relative_path_to_artifact_path
27
+
28
+ _MAX_CACHE_SECONDS = 300
29
+
30
+
31
+ def _get_utcnow_timestamp():
32
+ return datetime.utcnow().timestamp()
33
+
34
+
35
+ @lru_cache(maxsize=64)
36
+ def _cached_get_s3_client(
37
+ signature_version,
38
+ addressing_style,
39
+ s3_endpoint_url,
40
+ verify,
41
+ timestamp,
42
+ access_key_id=None,
43
+ secret_access_key=None,
44
+ session_token=None,
45
+ region_name=None,
46
+ ):
47
+ """Returns a boto3 client, caching to avoid extra boto3 verify calls.
48
+
49
+ This method is outside of the S3ArtifactRepository as it is
50
+ agnostic and could be used by other instances.
51
+
52
+ `maxsize` set to avoid excessive memory consumption in the case
53
+ a user has dynamic endpoints (intentionally or as a bug).
54
+
55
+ Some of the boto3 endpoint urls, in very edge cases, might expire
56
+ after twelve hours as that is the current expiration time. To ensure
57
+ we throw an error on verification instead of using an expired endpoint
58
+ we utilise the `timestamp` parameter to invalidate cache.
59
+ """
60
+ import boto3
61
+ from botocore.client import Config
62
+
63
+ # Making it possible to access public S3 buckets
64
+ # Workaround for https://github.com/boto/botocore/issues/2442
65
+ if signature_version.lower() == "unsigned":
66
+ from botocore import UNSIGNED
67
+
68
+ signature_version = UNSIGNED
69
+
70
+ return boto3.client(
71
+ "s3",
72
+ config=Config(
73
+ signature_version=signature_version, s3={"addressing_style": addressing_style}
74
+ ),
75
+ endpoint_url=s3_endpoint_url,
76
+ verify=verify,
77
+ aws_access_key_id=access_key_id,
78
+ aws_secret_access_key=secret_access_key,
79
+ aws_session_token=session_token,
80
+ region_name=region_name,
81
+ )
82
+
83
+
84
+ def _get_s3_client(
85
+ addressing_style=None,
86
+ access_key_id=None,
87
+ secret_access_key=None,
88
+ session_token=None,
89
+ region_name=None,
90
+ s3_endpoint_url=None,
91
+ ):
92
+ if not s3_endpoint_url:
93
+ s3_endpoint_url = MLFLOW_S3_ENDPOINT_URL.get()
94
+ do_verify = not MLFLOW_S3_IGNORE_TLS.get()
95
+
96
+ # The valid verify argument value is None/False/path to cert bundle file, See
97
+ # https://github.com/boto/boto3/blob/73865126cad3938ca80a2f567a1c79cb248169a7/
98
+ # boto3/session.py#L212
99
+ verify = None if do_verify else False
100
+
101
+ # NOTE: If you need to specify this env variable, please file an issue at
102
+ # https://github.com/mlflow/mlflow/issues so we know your use-case!
103
+ signature_version = os.environ.get("MLFLOW_EXPERIMENTAL_S3_SIGNATURE_VERSION", "s3v4")
104
+
105
+ # Invalidate cache every `_MAX_CACHE_SECONDS`
106
+ timestamp = int(_get_utcnow_timestamp() / _MAX_CACHE_SECONDS)
107
+
108
+ if not addressing_style:
109
+ addressing_style = MLFLOW_BOTO_CLIENT_ADDRESSING_STYLE.get()
110
+
111
+ return _cached_get_s3_client(
112
+ signature_version,
113
+ addressing_style,
114
+ s3_endpoint_url,
115
+ verify,
116
+ timestamp,
117
+ access_key_id=access_key_id,
118
+ secret_access_key=secret_access_key,
119
+ session_token=session_token,
120
+ region_name=region_name,
121
+ )
122
+
123
+
124
+ class S3ArtifactRepository(ArtifactRepository, MultipartUploadMixin):
125
+ """Stores artifacts on Amazon S3."""
126
+
127
+ def __init__(
128
+ self,
129
+ artifact_uri: str,
130
+ tracking_uri: Optional[str] = None,
131
+ access_key_id=None,
132
+ secret_access_key=None,
133
+ session_token=None,
134
+ ) -> None:
135
+ super().__init__(artifact_uri, tracking_uri)
136
+ self._access_key_id = access_key_id
137
+ self._secret_access_key = secret_access_key
138
+ self._session_token = session_token
139
+
140
+ def _get_s3_client(self):
141
+ return _get_s3_client(
142
+ access_key_id=self._access_key_id,
143
+ secret_access_key=self._secret_access_key,
144
+ session_token=self._session_token,
145
+ )
146
+
147
+ def parse_s3_compliant_uri(self, uri):
148
+ """Parse an S3 URI, returning (bucket, path)"""
149
+ parsed = urllib.parse.urlparse(uri)
150
+ if parsed.scheme != "s3":
151
+ raise Exception(f"Not an S3 URI: {uri}")
152
+ path = parsed.path
153
+ if path.startswith("/"):
154
+ path = path[1:]
155
+ return parsed.netloc, path
156
+
157
+ @staticmethod
158
+ def get_s3_file_upload_extra_args():
159
+ s3_file_upload_extra_args = MLFLOW_S3_UPLOAD_EXTRA_ARGS.get()
160
+ if s3_file_upload_extra_args:
161
+ return json.loads(s3_file_upload_extra_args)
162
+ else:
163
+ return None
164
+
165
+ def _upload_file(self, s3_client, local_file, bucket, key):
166
+ extra_args = {}
167
+ guessed_type, guessed_encoding = guess_type(local_file)
168
+ if guessed_type is not None:
169
+ extra_args["ContentType"] = guessed_type
170
+ if guessed_encoding is not None:
171
+ extra_args["ContentEncoding"] = guessed_encoding
172
+ environ_extra_args = self.get_s3_file_upload_extra_args()
173
+ if environ_extra_args is not None:
174
+ extra_args.update(environ_extra_args)
175
+ s3_client.upload_file(Filename=local_file, Bucket=bucket, Key=key, ExtraArgs=extra_args)
176
+
177
+ def log_artifact(self, local_file, artifact_path=None):
178
+ (bucket, dest_path) = self.parse_s3_compliant_uri(self.artifact_uri)
179
+ if artifact_path:
180
+ dest_path = posixpath.join(dest_path, artifact_path)
181
+ dest_path = posixpath.join(dest_path, os.path.basename(local_file))
182
+ self._upload_file(
183
+ s3_client=self._get_s3_client(), local_file=local_file, bucket=bucket, key=dest_path
184
+ )
185
+
186
+ def log_artifacts(self, local_dir, artifact_path=None):
187
+ (bucket, dest_path) = self.parse_s3_compliant_uri(self.artifact_uri)
188
+ if artifact_path:
189
+ dest_path = posixpath.join(dest_path, artifact_path)
190
+ s3_client = self._get_s3_client()
191
+ local_dir = os.path.abspath(local_dir)
192
+ for root, _, filenames in os.walk(local_dir):
193
+ upload_path = dest_path
194
+ if root != local_dir:
195
+ rel_path = os.path.relpath(root, local_dir)
196
+ rel_path = relative_path_to_artifact_path(rel_path)
197
+ upload_path = posixpath.join(dest_path, rel_path)
198
+
199
+ for f in filenames:
200
+ self._upload_file(
201
+ s3_client=s3_client,
202
+ local_file=os.path.join(root, f),
203
+ bucket=bucket,
204
+ key=posixpath.join(upload_path, f),
205
+ )
206
+
207
+ def list_artifacts(self, path=None):
208
+ (bucket, artifact_path) = self.parse_s3_compliant_uri(self.artifact_uri)
209
+ dest_path = artifact_path
210
+ if path:
211
+ dest_path = posixpath.join(dest_path, path)
212
+ dest_path = dest_path.rstrip("/") if dest_path else ""
213
+ infos = []
214
+ prefix = dest_path + "/" if dest_path else ""
215
+ s3_client = self._get_s3_client()
216
+ paginator = s3_client.get_paginator("list_objects_v2")
217
+ results = paginator.paginate(Bucket=bucket, Prefix=prefix, Delimiter="/")
218
+ for result in results:
219
+ # Subdirectories will be listed as "common prefixes" due to the way we made the request
220
+ for obj in result.get("CommonPrefixes", []):
221
+ subdir_path = obj.get("Prefix")
222
+ self._verify_listed_object_contains_artifact_path_prefix(
223
+ listed_object_path=subdir_path, artifact_path=artifact_path
224
+ )
225
+ subdir_rel_path = posixpath.relpath(path=subdir_path, start=artifact_path)
226
+ if subdir_rel_path.endswith("/"):
227
+ subdir_rel_path = subdir_rel_path[:-1]
228
+ infos.append(FileInfo(subdir_rel_path, True, None))
229
+ # Objects listed directly will be files
230
+ for obj in result.get("Contents", []):
231
+ file_path = obj.get("Key")
232
+ self._verify_listed_object_contains_artifact_path_prefix(
233
+ listed_object_path=file_path, artifact_path=artifact_path
234
+ )
235
+ file_rel_path = posixpath.relpath(path=file_path, start=artifact_path)
236
+ file_size = int(obj.get("Size"))
237
+ infos.append(FileInfo(file_rel_path, False, file_size))
238
+ return sorted(infos, key=lambda f: f.path)
239
+
240
+ @staticmethod
241
+ def _verify_listed_object_contains_artifact_path_prefix(listed_object_path, artifact_path):
242
+ if not listed_object_path.startswith(artifact_path):
243
+ raise MlflowException(
244
+ "The path of the listed S3 object does not begin with the specified"
245
+ f" artifact path. Artifact path: {artifact_path}. Object path:"
246
+ f" {listed_object_path}."
247
+ )
248
+
249
+ def _download_file(self, remote_file_path, local_path):
250
+ (bucket, s3_root_path) = self.parse_s3_compliant_uri(self.artifact_uri)
251
+ s3_full_path = posixpath.join(s3_root_path, remote_file_path)
252
+ s3_client = self._get_s3_client()
253
+ s3_client.download_file(bucket, s3_full_path, local_path)
254
+
255
+ def delete_artifacts(self, artifact_path=None):
256
+ (bucket, dest_path) = self.parse_s3_compliant_uri(self.artifact_uri)
257
+ if artifact_path:
258
+ dest_path = posixpath.join(dest_path, artifact_path)
259
+
260
+ dest_path = dest_path.rstrip("/") if dest_path else ""
261
+ s3_client = self._get_s3_client()
262
+ paginator = s3_client.get_paginator("list_objects_v2")
263
+ results = paginator.paginate(Bucket=bucket, Prefix=dest_path)
264
+ for result in results:
265
+ keys = []
266
+ for to_delete_obj in result.get("Contents", []):
267
+ file_path = to_delete_obj.get("Key")
268
+ self._verify_listed_object_contains_artifact_path_prefix(
269
+ listed_object_path=file_path, artifact_path=dest_path
270
+ )
271
+ keys.append({"Key": file_path})
272
+ if keys:
273
+ s3_client.delete_objects(Bucket=bucket, Delete={"Objects": keys})
274
+
275
+ def create_multipart_upload(self, local_file, num_parts=1, artifact_path=None):
276
+ (bucket, dest_path) = self.parse_s3_compliant_uri(self.artifact_uri)
277
+ if artifact_path:
278
+ dest_path = posixpath.join(dest_path, artifact_path)
279
+ dest_path = posixpath.join(dest_path, os.path.basename(local_file))
280
+ s3_client = self._get_s3_client()
281
+ create_response = s3_client.create_multipart_upload(
282
+ Bucket=bucket,
283
+ Key=dest_path,
284
+ )
285
+ upload_id = create_response["UploadId"]
286
+ credentials = []
287
+ for i in range(1, num_parts + 1): # part number must be in [1, 10000]
288
+ url = s3_client.generate_presigned_url(
289
+ "upload_part",
290
+ Params={
291
+ "Bucket": bucket,
292
+ "Key": dest_path,
293
+ "PartNumber": i,
294
+ "UploadId": upload_id,
295
+ },
296
+ )
297
+ credentials.append(
298
+ MultipartUploadCredential(
299
+ url=url,
300
+ part_number=i,
301
+ headers={},
302
+ )
303
+ )
304
+ return CreateMultipartUploadResponse(
305
+ credentials=credentials,
306
+ upload_id=upload_id,
307
+ )
308
+
309
+ def complete_multipart_upload(self, local_file, upload_id, parts=None, artifact_path=None):
310
+ (bucket, dest_path) = self.parse_s3_compliant_uri(self.artifact_uri)
311
+ if artifact_path:
312
+ dest_path = posixpath.join(dest_path, artifact_path)
313
+ dest_path = posixpath.join(dest_path, os.path.basename(local_file))
314
+ parts = [{"PartNumber": part.part_number, "ETag": part.etag} for part in parts]
315
+ s3_client = self._get_s3_client()
316
+ s3_client.complete_multipart_upload(
317
+ Bucket=bucket, Key=dest_path, UploadId=upload_id, MultipartUpload={"Parts": parts}
318
+ )
319
+
320
+ def abort_multipart_upload(self, local_file, upload_id, artifact_path=None):
321
+ (bucket, dest_path) = self.parse_s3_compliant_uri(self.artifact_uri)
322
+ if artifact_path:
323
+ dest_path = posixpath.join(dest_path, artifact_path)
324
+ dest_path = posixpath.join(dest_path, os.path.basename(local_file))
325
+ s3_client = self._get_s3_client()
326
+ s3_client.abort_multipart_upload(
327
+ Bucket=bucket,
328
+ Key=dest_path,
329
+ UploadId=upload_id,
330
+ )
@@ -0,0 +1,141 @@
1
+ import os
2
+ import posixpath
3
+ import sys
4
+ import urllib.parse
5
+ from contextlib import contextmanager
6
+ from queue import Queue
7
+ from typing import Optional
8
+
9
+ from mlflow.entities import FileInfo
10
+ from mlflow.store.artifact.artifact_repo import ArtifactRepository
11
+
12
+
13
+ # Based on: https://stackoverflow.com/a/58466685
14
+ def _put_r_for_windows(sftp, local_dir, remote_dir, preserve_mtime=False):
15
+ for entry in os.listdir(local_dir):
16
+ local_path = os.path.join(local_dir, entry)
17
+ remote_path = posixpath.join(remote_dir, entry)
18
+ if os.path.isdir(local_path):
19
+ sftp.mkdir(remote_path)
20
+ _put_r_for_windows(sftp, local_path, remote_path, preserve_mtime)
21
+ else:
22
+ sftp.put(local_path, remote_path, preserve_mtime=preserve_mtime)
23
+
24
+
25
+ class _SftpPool:
26
+ def __init__(self, connections):
27
+ self._idle_connection_queue = Queue()
28
+ for c in connections:
29
+ self._idle_connection_queue.put(c)
30
+
31
+ @contextmanager
32
+ def get_sftp_connection(self):
33
+ c = self._idle_connection_queue.get(block=True)
34
+ try:
35
+ yield c
36
+ finally:
37
+ self._idle_connection_queue.put(c)
38
+
39
+
40
+ class SFTPArtifactRepository(ArtifactRepository):
41
+ """Stores artifacts as files in a remote directory, via sftp."""
42
+
43
+ def __init__(self, artifact_uri: str, tracking_uri: Optional[str] = None) -> None:
44
+ super().__init__(artifact_uri, tracking_uri)
45
+ parsed = urllib.parse.urlparse(artifact_uri)
46
+ self.config = {
47
+ "host": parsed.hostname,
48
+ "port": parsed.port,
49
+ "username": parsed.username,
50
+ "password": parsed.password,
51
+ }
52
+ self.path = parsed.path or "/"
53
+
54
+ import paramiko
55
+ import pysftp
56
+
57
+ if self.config["host"] is None:
58
+ self.config["host"] = "localhost"
59
+
60
+ ssh_config = paramiko.SSHConfig()
61
+ user_config_file = os.path.expanduser("~/.ssh/config")
62
+ if os.path.exists(user_config_file):
63
+ with open(user_config_file) as f:
64
+ ssh_config.parse(f)
65
+
66
+ user_config = ssh_config.lookup(self.config["host"])
67
+
68
+ if "hostname" in user_config:
69
+ self.config["host"] = user_config["hostname"]
70
+
71
+ if self.config.get("username", None) is None and "user" in user_config:
72
+ self.config["username"] = user_config["user"]
73
+
74
+ if self.config.get("port", None) is None:
75
+ if "port" in user_config:
76
+ self.config["port"] = int(user_config["port"])
77
+ else:
78
+ self.config["port"] = 22
79
+
80
+ if "identityfile" in user_config:
81
+ self.config["private_key"] = user_config["identityfile"][0]
82
+
83
+ connections = [pysftp.Connection(**self.config) for _ in range(self.max_workers)]
84
+ self.pool = _SftpPool(connections)
85
+
86
+ def log_artifact(self, local_file, artifact_path=None):
87
+ artifact_dir = posixpath.join(self.path, artifact_path) if artifact_path else self.path
88
+ with self.pool.get_sftp_connection() as sftp:
89
+ sftp.makedirs(artifact_dir)
90
+ sftp.put(local_file, posixpath.join(artifact_dir, os.path.basename(local_file)))
91
+
92
+ def log_artifacts(self, local_dir, artifact_path=None):
93
+ artifact_dir = posixpath.join(self.path, artifact_path) if artifact_path else self.path
94
+ with self.pool.get_sftp_connection() as sftp:
95
+ sftp.makedirs(artifact_dir)
96
+ if sys.platform == "win32":
97
+ _put_r_for_windows(sftp, local_dir, artifact_dir)
98
+ else:
99
+ sftp.put_r(local_dir, artifact_dir)
100
+
101
+ def _is_directory(self, artifact_path):
102
+ artifact_dir = self.path
103
+ path = posixpath.join(artifact_dir, artifact_path) if artifact_path else artifact_dir
104
+ with self.pool.get_sftp_connection() as sftp:
105
+ return sftp.isdir(path)
106
+
107
+ def list_artifacts(self, path=None):
108
+ artifact_dir = self.path
109
+ list_dir = posixpath.join(artifact_dir, path) if path else artifact_dir
110
+ with self.pool.get_sftp_connection() as sftp:
111
+ if not sftp.isdir(list_dir):
112
+ return []
113
+ artifact_files = sftp.listdir(list_dir)
114
+ infos = []
115
+ for file_name in artifact_files:
116
+ file_path = file_name if path is None else posixpath.join(path, file_name)
117
+ full_file_path = posixpath.join(list_dir, file_name)
118
+ if sftp.isdir(full_file_path):
119
+ infos.append(FileInfo(file_path, True, None))
120
+ else:
121
+ infos.append(FileInfo(file_path, False, sftp.stat(full_file_path).st_size))
122
+ return infos
123
+
124
+ def _download_file(self, remote_file_path, local_path):
125
+ remote_full_path = posixpath.join(self.path, remote_file_path)
126
+ with self.pool.get_sftp_connection() as sftp:
127
+ sftp.get(remote_full_path, local_path)
128
+
129
+ def delete_artifacts(self, artifact_path=None):
130
+ artifact_dir = posixpath.join(self.path, artifact_path) if artifact_path else self.path
131
+ with self.pool.get_sftp_connection() as sftp:
132
+ self._delete_inner(artifact_dir, sftp)
133
+
134
+ def _delete_inner(self, artifact_path, sftp):
135
+ if sftp.isdir(artifact_path):
136
+ with sftp.cd(artifact_path):
137
+ for element in sftp.listdir():
138
+ self._delete_inner(element, sftp)
139
+ sftp.rmdir(artifact_path)
140
+ elif sftp.isfile(artifact_path):
141
+ sftp.remove(artifact_path)
@@ -0,0 +1,76 @@
1
+ from typing import Optional
2
+
3
+ import mlflow.utils.databricks_utils
4
+ from mlflow.environment_variables import MLFLOW_ENABLE_UC_VOLUME_FUSE_ARTIFACT_REPO
5
+ from mlflow.exceptions import MlflowException
6
+ from mlflow.protos.databricks_pb2 import INVALID_PARAMETER_VALUE
7
+ from mlflow.store.artifact.databricks_sdk_artifact_repo import DatabricksSdkArtifactRepository
8
+ from mlflow.store.artifact.local_artifact_repo import LocalArtifactRepository
9
+ from mlflow.utils.uri import (
10
+ get_databricks_profile_uri_from_artifact_uri,
11
+ is_databricks_model_registry_artifacts_uri,
12
+ is_valid_uc_volumes_uri,
13
+ remove_databricks_profile_info_from_artifact_uri,
14
+ strip_scheme,
15
+ )
16
+
17
+
18
+ class UCVolumesArtifactRepository(DatabricksSdkArtifactRepository):
19
+ """
20
+ Stores artifacts on UC Volumes using the Files REST API.
21
+ """
22
+
23
+ def __init__(self, artifact_uri: str, tracking_uri: Optional[str] = None) -> None:
24
+ if not is_valid_uc_volumes_uri(artifact_uri):
25
+ raise MlflowException(
26
+ message=(
27
+ f"UC volumes URI must be of the form "
28
+ f"dbfs:/Volumes/<catalog>/<schema>/<volume>/<path>: {artifact_uri}"
29
+ ),
30
+ error_code=INVALID_PARAMETER_VALUE,
31
+ )
32
+ uri = remove_databricks_profile_info_from_artifact_uri(artifact_uri)
33
+ super().__init__("/" + strip_scheme(uri).strip("/"), tracking_uri)
34
+
35
+
36
+ def uc_volume_artifact_repo_factory(artifact_uri: str, tracking_uri: Optional[str] = None):
37
+ """
38
+ Returns an ArtifactRepository subclass for storing artifacts on Volumes.
39
+
40
+ This factory method is used with URIs of the form ``dbfs:/Volumes/<path>``. Volume-backed
41
+ artifact storage can only be used together with the RestStore.
42
+
43
+ Args:
44
+ artifact_uri: Volume root artifact URI.
45
+ tracking_uri: The tracking URI.
46
+
47
+ Returns:
48
+ Subclass of ArtifactRepository capable of storing artifacts on DBFS.
49
+ """
50
+ if not is_valid_uc_volumes_uri(artifact_uri):
51
+ raise MlflowException(
52
+ message=(
53
+ f"UC volumes URI must be of the form "
54
+ f"dbfs:/Volumes/<catalog>/<schema>/<volume>/<path>: {artifact_uri}"
55
+ ),
56
+ error_code=INVALID_PARAMETER_VALUE,
57
+ )
58
+
59
+ artifact_uri = artifact_uri.rstrip("/")
60
+ db_profile_uri = get_databricks_profile_uri_from_artifact_uri(artifact_uri)
61
+ if (
62
+ mlflow.utils.databricks_utils.is_uc_volume_fuse_available()
63
+ and MLFLOW_ENABLE_UC_VOLUME_FUSE_ARTIFACT_REPO.get()
64
+ and not is_databricks_model_registry_artifacts_uri(artifact_uri)
65
+ and (db_profile_uri is None or db_profile_uri == "databricks")
66
+ ):
67
+ # If the UC Volume FUSE mount is available, write artifacts directly to
68
+ # /Volumes/... using local filesystem APIs.
69
+ # Note: it is possible for a named Databricks profile to point to the current workspace,
70
+ # but we're going to avoid doing a complex check and assume users will use `databricks`
71
+ # to mean the current workspace. Using `UCVolumesArtifactRepository` to access
72
+ # the current workspace's Volumes should still work; it just may be slower.
73
+ uri_without_profile = remove_databricks_profile_info_from_artifact_uri(artifact_uri)
74
+ path = strip_scheme(uri_without_profile).lstrip("/")
75
+ return LocalArtifactRepository(f"file:///{path}", tracking_uri)
76
+ return UCVolumesArtifactRepository(artifact_uri, tracking_uri)