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,259 @@
1
+ import logging
2
+ import os
3
+ import urllib.parse
4
+ from pathlib import Path
5
+ from typing import Optional, Union
6
+
7
+ import mlflow
8
+ from mlflow.exceptions import MlflowException
9
+ from mlflow.store.artifact.artifact_repo import ArtifactRepository
10
+ from mlflow.store.artifact.databricks_models_artifact_repo import DatabricksModelsArtifactRepository
11
+ from mlflow.store.artifact.unity_catalog_models_artifact_repo import (
12
+ UnityCatalogModelsArtifactRepository,
13
+ )
14
+ from mlflow.store.artifact.unity_catalog_oss_models_artifact_repo import (
15
+ UnityCatalogOSSModelsArtifactRepository,
16
+ )
17
+ from mlflow.store.artifact.utils.models import (
18
+ _parse_model_uri,
19
+ get_model_name_and_version,
20
+ is_using_databricks_registry,
21
+ )
22
+ from mlflow.utils.uri import (
23
+ add_databricks_profile_info_to_artifact_uri,
24
+ get_databricks_profile_uri_from_artifact_uri,
25
+ is_databricks_unity_catalog_uri,
26
+ is_models_uri,
27
+ is_oss_unity_catalog_uri,
28
+ )
29
+
30
+ REGISTERED_MODEL_META_FILE_NAME = "registered_model_meta"
31
+
32
+ _logger = logging.getLogger(__name__)
33
+
34
+
35
+ class ModelsArtifactRepository(ArtifactRepository):
36
+ """
37
+ Handles artifacts associated with a model version in the model registry via URIs of the form:
38
+ - `models:/<model_name>/<model_version>`
39
+ - `models:/<model_name>/<stage>` (refers to the latest model version in the given stage)
40
+ - `models:/<model_name>/latest` (refers to the latest of all model versions)
41
+ It is a light wrapper that resolves the artifact path to an absolute URI then instantiates
42
+ and uses the artifact repository for that URI.
43
+ """
44
+
45
+ def __init__(self, artifact_uri: str, tracking_uri: Optional[str] = None) -> None:
46
+ from mlflow.store.artifact.artifact_repository_registry import get_artifact_repository
47
+
48
+ super().__init__(artifact_uri, tracking_uri)
49
+ registry_uri = mlflow.get_registry_uri()
50
+ self.is_logged_model_uri = self._is_logged_model_uri(artifact_uri)
51
+ if is_databricks_unity_catalog_uri(uri=registry_uri) and not self.is_logged_model_uri:
52
+ self.repo = UnityCatalogModelsArtifactRepository(
53
+ artifact_uri=artifact_uri, registry_uri=registry_uri
54
+ )
55
+ self.model_name = self.repo.model_name
56
+ self.model_version = self.repo.model_version
57
+ elif is_oss_unity_catalog_uri(uri=registry_uri) and not self.is_logged_model_uri:
58
+ self.repo = UnityCatalogOSSModelsArtifactRepository(
59
+ artifact_uri=artifact_uri, registry_uri=registry_uri
60
+ )
61
+ self.model_name = self.repo.model_name
62
+ self.model_version = self.repo.model_version
63
+ elif is_using_databricks_registry(artifact_uri) and not self.is_logged_model_uri:
64
+ # Use the DatabricksModelsArtifactRepository if a databricks profile is being used.
65
+ self.repo = DatabricksModelsArtifactRepository(artifact_uri)
66
+ self.model_name = self.repo.model_name
67
+ self.model_version = self.repo.model_version
68
+ else:
69
+ (
70
+ self.model_name,
71
+ self.model_version,
72
+ underlying_uri,
73
+ ) = ModelsArtifactRepository._get_model_uri_infos(artifact_uri)
74
+ self.repo = get_artifact_repository(underlying_uri)
75
+ # TODO: it may be nice to fall back to the source URI explicitly here if for some reason
76
+ # we don't get a download URI here, or fail during the download itself.
77
+
78
+ @staticmethod
79
+ def is_models_uri(uri):
80
+ return urllib.parse.urlparse(uri).scheme == "models"
81
+
82
+ @staticmethod
83
+ def split_models_uri(uri):
84
+ """
85
+ Split 'models:/<name>/<version>/path/to/model' into
86
+ ('models:/<name>/<version>', 'path/to/model').
87
+ Split 'models://<scope>:<prefix>@databricks/<name>/<version>/path/to/model' into
88
+ ('models://<scope>:<prefix>@databricks/<name>/<version>', 'path/to/model').
89
+ Split 'models:/<name>@alias/path/to/model' into
90
+ ('models:/<name>@alias', 'path/to/model').
91
+ """
92
+ uri = uri.rstrip("/")
93
+ parsed_url = urllib.parse.urlparse(uri)
94
+ path = parsed_url.path
95
+ netloc = parsed_url.netloc
96
+ if path.count("/") >= 2 and not path.endswith("/"):
97
+ splits = path.split("/", 3)
98
+ cut_index = 2 if "@" in splits[1] else 3
99
+ model_name_and_version = splits[:cut_index]
100
+ artifact_path = "/".join(splits[cut_index:])
101
+ base_part = f"models://{netloc}" if netloc else "models:"
102
+ return base_part + "/".join(model_name_and_version), artifact_path
103
+ return uri, ""
104
+
105
+ @staticmethod
106
+ def _is_logged_model_uri(uri: Union[str, Path]) -> bool:
107
+ """
108
+ Returns True if the URI is a logged model URI (e.g. 'models:/<model_id>'), False otherwise.
109
+ """
110
+ uri = str(uri)
111
+ return is_models_uri(uri) and _parse_model_uri(uri).model_id is not None
112
+
113
+ @staticmethod
114
+ def _get_model_uri_infos(uri):
115
+ # Note: to support a registry URI that is different from the tracking URI here,
116
+ # we'll need to add setting of registry URIs via environment variables.
117
+
118
+ from mlflow import MlflowClient
119
+
120
+ databricks_profile_uri = (
121
+ get_databricks_profile_uri_from_artifact_uri(uri) or mlflow.get_registry_uri()
122
+ )
123
+ client = MlflowClient(registry_uri=databricks_profile_uri)
124
+ name_and_version_or_id = get_model_name_and_version(client, uri)
125
+ if len(name_and_version_or_id) == 1:
126
+ name = None
127
+ version = None
128
+ model_id = name_and_version_or_id[0]
129
+ download_uri = client.get_logged_model(model_id).artifact_location
130
+ else:
131
+ name, version = name_and_version_or_id
132
+ download_uri = client.get_model_version_download_uri(name, version)
133
+
134
+ return (
135
+ name,
136
+ version,
137
+ add_databricks_profile_info_to_artifact_uri(download_uri, databricks_profile_uri),
138
+ )
139
+
140
+ @staticmethod
141
+ def get_underlying_uri(uri):
142
+ _, _, underlying_uri = ModelsArtifactRepository._get_model_uri_infos(uri)
143
+
144
+ return underlying_uri
145
+
146
+ def log_artifact(self, local_file, artifact_path=None):
147
+ """
148
+ Log a local file as an artifact, optionally taking an ``artifact_path`` to place it in
149
+ within the run's artifacts. Run artifacts can be organized into directories, so you can
150
+ place the artifact in a directory this way.
151
+
152
+ Args:
153
+ local_file: Path to artifact to log.
154
+ artifact_path: Directory within the run's artifact directory in which to log the
155
+ artifact.
156
+ """
157
+ if self.is_logged_model_uri:
158
+ return self.repo.log_artifact(local_file, artifact_path)
159
+ raise ValueError(
160
+ "log_artifact is not supported for models:/<name>/<version> URIs. "
161
+ "Use register_model instead."
162
+ )
163
+
164
+ def log_artifacts(self, local_dir, artifact_path=None):
165
+ """
166
+ Log the files in the specified local directory as artifacts, optionally taking
167
+ an ``artifact_path`` to place them in within the run's artifacts.
168
+
169
+ Args:
170
+ local_dir: Directory of local artifacts to log.
171
+ artifact_path: Directory within the run's artifact directory in which to log the
172
+ artifacts.
173
+ """
174
+ if self.is_logged_model_uri:
175
+ return self.repo.log_artifacts(local_dir, artifact_path)
176
+ raise ValueError(
177
+ "log_artifacts is not supported for models:/<name>/<version> URIs. "
178
+ "Use register_model instead."
179
+ )
180
+
181
+ def list_artifacts(self, path):
182
+ """
183
+ Return all the artifacts for this run_id directly under path. If path is a file, returns
184
+ an empty list. Will error if path is neither a file nor directory.
185
+
186
+ Args:
187
+ path: Relative source path that contain desired artifacts.
188
+
189
+ Returns:
190
+ List of artifacts as FileInfo listed directly under path.
191
+ """
192
+ return self.repo.list_artifacts(path)
193
+
194
+ def _add_registered_model_meta_file(self, model_path):
195
+ from mlflow.utils.yaml_utils import write_yaml
196
+
197
+ write_yaml(
198
+ model_path,
199
+ REGISTERED_MODEL_META_FILE_NAME,
200
+ {
201
+ "model_name": self.model_name,
202
+ "model_version": self.model_version,
203
+ },
204
+ overwrite=True,
205
+ ensure_yaml_extension=False,
206
+ )
207
+
208
+ def download_artifacts(self, artifact_path, dst_path=None, lineage_header_info=None):
209
+ """
210
+ Download an artifact file or directory to a local directory if applicable, and return a
211
+ local path for it.
212
+ For registered models, when the artifact is downloaded, the model name and version
213
+ are saved in the "registered_model_meta" file on the caller's side.
214
+ The caller is responsible for managing the lifecycle of the downloaded artifacts.
215
+
216
+ Args:
217
+ artifact_path: Relative source path to the desired artifacts.
218
+ dst_path: Absolute path of the local filesystem destination directory to which to
219
+ download the specified artifacts. This directory must already exist.
220
+ If unspecified, the artifacts will either be downloaded to a new
221
+ uniquely-named directory on the local filesystem or will be returned
222
+ directly in the case of the LocalArtifactRepository.
223
+ lineage_header_info: Linear header information.
224
+
225
+ Returns:
226
+ Absolute path of the local filesystem location containing the desired artifacts.
227
+ """
228
+
229
+ from mlflow.models.model import MLMODEL_FILE_NAME
230
+
231
+ # Pass lineage header info if model is registered in UC
232
+ if isinstance(self.repo, UnityCatalogModelsArtifactRepository):
233
+ model_path = self.repo.download_artifacts(
234
+ artifact_path, dst_path, lineage_header_info=lineage_header_info
235
+ )
236
+ else:
237
+ model_path = self.repo.download_artifacts(artifact_path, dst_path)
238
+ # NB: only add the registered model metadata iff the artifact path is at the root model
239
+ # directory. For individual files or subdirectories within the model directory, do not
240
+ # create the metadata file.
241
+ if os.path.isdir(model_path) and MLMODEL_FILE_NAME in os.listdir(model_path):
242
+ self._add_registered_model_meta_file(model_path)
243
+
244
+ return model_path
245
+
246
+ def _download_file(self, remote_file_path, local_path):
247
+ """
248
+ Download the file at the specified relative remote path and saves
249
+ it at the specified local path.
250
+
251
+ Args:
252
+ remote_file_path: Source path to the remote file, relative to the root
253
+ directory of the artifact repository.
254
+ local_path: The path to which to save the downloaded file.
255
+ """
256
+ self.repo._download_file(remote_file_path, local_path)
257
+
258
+ def delete_artifacts(self, artifact_path=None):
259
+ raise MlflowException("Not implemented yet")
@@ -0,0 +1,356 @@
1
+ import json
2
+ import logging
3
+ import os
4
+ import posixpath
5
+ import urllib.parse
6
+ from mimetypes import guess_type
7
+
8
+ from mlflow.entities import FileInfo
9
+ from mlflow.environment_variables import (
10
+ MLFLOW_ENABLE_MULTIPART_UPLOAD,
11
+ MLFLOW_MULTIPART_UPLOAD_CHUNK_SIZE,
12
+ MLFLOW_S3_UPLOAD_EXTRA_ARGS,
13
+ )
14
+ from mlflow.exceptions import MlflowException
15
+ from mlflow.protos.databricks_artifacts_pb2 import ArtifactCredentialInfo
16
+ from mlflow.store.artifact.artifact_repo import _retry_with_new_creds
17
+ from mlflow.store.artifact.cloud_artifact_repo import (
18
+ CloudArtifactRepository,
19
+ _complete_futures,
20
+ _compute_num_chunks,
21
+ _validate_chunk_size_aws,
22
+ )
23
+ from mlflow.store.artifact.s3_artifact_repo import _get_s3_client
24
+ from mlflow.utils.file_utils import read_chunk
25
+ from mlflow.utils.request_utils import cloud_storage_http_request
26
+ from mlflow.utils.rest_utils import augmented_raise_for_status
27
+
28
+ _logger = logging.getLogger(__name__)
29
+ _BUCKET_REGION = "BucketRegion"
30
+ _RESPONSE_METADATA = "ResponseMetadata"
31
+ _HTTP_HEADERS = "HTTPHeaders"
32
+ _HTTP_HEADER_BUCKET_REGION = "x-amz-bucket-region"
33
+ _BUCKET_LOCATION_NAME = "BucketLocationName"
34
+
35
+
36
+ class OptimizedS3ArtifactRepository(CloudArtifactRepository):
37
+ """
38
+ An optimized version of the S3 Artifact Repository.
39
+
40
+ This class is used for uploading and downloading S3 artifacts for UC models. While it largely
41
+ copies the behavior of the S3ArtifactRepository, the `log_artifact`, `log_artifacts`, and
42
+ `_download_file` methods are optimized by replacing boto3 client operations with the use of
43
+ presigned URLs for both uploads and downloads.
44
+ """
45
+
46
+ def __init__(
47
+ self,
48
+ artifact_uri,
49
+ access_key_id=None,
50
+ secret_access_key=None,
51
+ session_token=None,
52
+ credential_refresh_def=None,
53
+ addressing_style=None,
54
+ s3_endpoint_url=None,
55
+ s3_upload_extra_args=None,
56
+ ):
57
+ super().__init__(artifact_uri)
58
+ self._access_key_id = access_key_id
59
+ self._secret_access_key = secret_access_key
60
+ self._session_token = session_token
61
+ self._credential_refresh_def = credential_refresh_def
62
+ self._addressing_style = addressing_style
63
+ self._s3_endpoint_url = s3_endpoint_url
64
+ self.bucket, self.bucket_path = self.parse_s3_compliant_uri(self.artifact_uri)
65
+ self._region_name = self._get_region_name()
66
+ self._s3_upload_extra_args = s3_upload_extra_args if s3_upload_extra_args else {}
67
+
68
+ def _refresh_credentials(self):
69
+ if not self._credential_refresh_def:
70
+ return self._get_s3_client()
71
+ new_creds = self._credential_refresh_def()
72
+ self._access_key_id = new_creds["access_key_id"]
73
+ self._secret_access_key = new_creds["secret_access_key"]
74
+ self._session_token = new_creds["session_token"]
75
+ self._s3_upload_extra_args = new_creds["s3_upload_extra_args"]
76
+ return self._get_s3_client()
77
+
78
+ def _get_region_name(self):
79
+ from botocore.exceptions import ClientError
80
+
81
+ temp_client = _get_s3_client(
82
+ addressing_style=self._addressing_style,
83
+ access_key_id=self._access_key_id,
84
+ secret_access_key=self._secret_access_key,
85
+ session_token=self._session_token,
86
+ s3_endpoint_url=self._s3_endpoint_url,
87
+ )
88
+ try:
89
+ head_bucket_resp = temp_client.head_bucket(Bucket=self.bucket)
90
+ # A normal response will have the region in the Bucket_Region field of the response
91
+ if _BUCKET_REGION in head_bucket_resp:
92
+ return head_bucket_resp[_BUCKET_REGION]
93
+ # If the bucket exists but the caller does not have permissions, the http headers
94
+ # are passed back as part of the metadata of a normal, non-throwing response. In
95
+ # this case we use the x-amz-bucket-region field of the HTTP headers which should
96
+ # always be populated with the region.
97
+ if (
98
+ _RESPONSE_METADATA in head_bucket_resp
99
+ and _HTTP_HEADERS in head_bucket_resp[_RESPONSE_METADATA]
100
+ and _HTTP_HEADER_BUCKET_REGION
101
+ in head_bucket_resp[_RESPONSE_METADATA][_HTTP_HEADERS]
102
+ ):
103
+ return head_bucket_resp[_RESPONSE_METADATA][_HTTP_HEADERS][
104
+ _HTTP_HEADER_BUCKET_REGION
105
+ ]
106
+ # Directory buckets do not have a Bucket_Region and instead have a
107
+ # Bucket_Location_Name. This name cannot be used as the region name
108
+ # however, so we warn that this has happened and allow the exception
109
+ # at the end to be raised.
110
+ if _BUCKET_LOCATION_NAME in head_bucket_resp:
111
+ _logger.warning(
112
+ f"Directory bucket {self.bucket} found with BucketLocationName "
113
+ f"{head_bucket_resp[_BUCKET_LOCATION_NAME]}."
114
+ )
115
+ raise Exception(f"Unable to get the region name for bucket {self.bucket}.")
116
+ except ClientError as error:
117
+ # If a client error occurs, we check to see if the x-amz-bucket-region field is set
118
+ # in the response and return that. If it is not present, this will raise due to the
119
+ # key not being present.
120
+ return error.response[_RESPONSE_METADATA][_HTTP_HEADERS][_HTTP_HEADER_BUCKET_REGION]
121
+
122
+ def _get_s3_client(self):
123
+ return _get_s3_client(
124
+ addressing_style=self._addressing_style,
125
+ access_key_id=self._access_key_id,
126
+ secret_access_key=self._secret_access_key,
127
+ session_token=self._session_token,
128
+ region_name=self._region_name,
129
+ s3_endpoint_url=self._s3_endpoint_url,
130
+ )
131
+
132
+ def parse_s3_compliant_uri(self, uri):
133
+ """Parse an S3 URI, returning (bucket, path)"""
134
+ parsed = urllib.parse.urlparse(uri)
135
+ if parsed.scheme != "s3":
136
+ raise Exception(f"Not an S3 URI: {uri}")
137
+ path = parsed.path
138
+ if path.startswith("/"):
139
+ path = path[1:]
140
+ return parsed.netloc, path
141
+
142
+ @staticmethod
143
+ def get_s3_file_upload_extra_args():
144
+ s3_file_upload_extra_args = MLFLOW_S3_UPLOAD_EXTRA_ARGS.get()
145
+ if s3_file_upload_extra_args:
146
+ return json.loads(s3_file_upload_extra_args)
147
+ else:
148
+ return None
149
+
150
+ def _upload_file(self, s3_client, local_file, bucket, key):
151
+ extra_args = {}
152
+ extra_args.update(self._s3_upload_extra_args)
153
+ guessed_type, guessed_encoding = guess_type(local_file)
154
+ if guessed_type is not None:
155
+ extra_args["ContentType"] = guessed_type
156
+ if guessed_encoding is not None:
157
+ extra_args["ContentEncoding"] = guessed_encoding
158
+ environ_extra_args = self.get_s3_file_upload_extra_args()
159
+ if environ_extra_args is not None:
160
+ extra_args.update(environ_extra_args)
161
+
162
+ def try_func(creds):
163
+ creds.upload_file(Filename=local_file, Bucket=bucket, Key=key, ExtraArgs=extra_args)
164
+
165
+ _retry_with_new_creds(
166
+ try_func=try_func, creds_func=self._refresh_credentials, orig_creds=s3_client
167
+ )
168
+
169
+ def log_artifact(self, local_file, artifact_path=None):
170
+ artifact_file_path = os.path.basename(local_file)
171
+ if artifact_path:
172
+ artifact_file_path = posixpath.join(artifact_path, artifact_file_path)
173
+ self._upload_to_cloud(
174
+ cloud_credential_info=self._get_s3_client(),
175
+ src_file_path=local_file,
176
+ artifact_file_path=artifact_file_path,
177
+ )
178
+
179
+ def _get_write_credential_infos(self, remote_file_paths):
180
+ """
181
+ Instead of returning ArtifactCredentialInfo objects, we instead return a list of initialized
182
+ S3 client. We do so because S3 clients cannot be instantiated within each thread.
183
+ """
184
+ return [self._get_s3_client() for _ in remote_file_paths]
185
+
186
+ def _upload_to_cloud(self, cloud_credential_info, src_file_path, artifact_file_path):
187
+ dest_path = posixpath.join(self.bucket_path, artifact_file_path)
188
+ key = posixpath.normpath(dest_path)
189
+ if (
190
+ MLFLOW_ENABLE_MULTIPART_UPLOAD.get()
191
+ and os.path.getsize(src_file_path) > MLFLOW_MULTIPART_UPLOAD_CHUNK_SIZE.get()
192
+ ):
193
+ self._multipart_upload(cloud_credential_info, src_file_path, self.bucket, key)
194
+ else:
195
+ self._upload_file(cloud_credential_info, src_file_path, self.bucket, key)
196
+
197
+ def _multipart_upload(self, cloud_credential_info, local_file, bucket, key):
198
+ # Create multipart upload
199
+ s3_client = cloud_credential_info
200
+ response = s3_client.create_multipart_upload(Bucket=bucket, Key=key)
201
+ upload_id = response["UploadId"]
202
+
203
+ num_parts = _compute_num_chunks(local_file, MLFLOW_MULTIPART_UPLOAD_CHUNK_SIZE.get())
204
+ _validate_chunk_size_aws(MLFLOW_MULTIPART_UPLOAD_CHUNK_SIZE.get())
205
+
206
+ # define helper functions for uploading data
207
+ def _upload_part(part_number, local_file, start_byte, size):
208
+ data = read_chunk(local_file, size, start_byte)
209
+
210
+ def try_func(creds):
211
+ # Create presigned URL for each part
212
+ presigned_url = creds.generate_presigned_url(
213
+ "upload_part",
214
+ Params={
215
+ "Bucket": bucket,
216
+ "Key": key,
217
+ "UploadId": upload_id,
218
+ "PartNumber": part_number,
219
+ },
220
+ )
221
+ with cloud_storage_http_request("put", presigned_url, data=data) as response:
222
+ augmented_raise_for_status(response)
223
+ return response.headers["ETag"]
224
+
225
+ return _retry_with_new_creds(
226
+ try_func=try_func, creds_func=self._refresh_credentials, orig_creds=s3_client
227
+ )
228
+
229
+ try:
230
+ # Upload each part with retries
231
+ futures = {}
232
+ for index in range(num_parts):
233
+ part_number = index + 1
234
+ start_byte = index * MLFLOW_MULTIPART_UPLOAD_CHUNK_SIZE.get()
235
+ future = self.chunk_thread_pool.submit(
236
+ _upload_part,
237
+ part_number=part_number,
238
+ local_file=local_file,
239
+ start_byte=start_byte,
240
+ size=MLFLOW_MULTIPART_UPLOAD_CHUNK_SIZE.get(),
241
+ )
242
+ futures[future] = part_number
243
+
244
+ results, errors = _complete_futures(futures, local_file)
245
+ if errors:
246
+ raise MlflowException(
247
+ f"Failed to upload at least one part of {local_file}. Errors: {errors}"
248
+ )
249
+ parts = [
250
+ {"PartNumber": part_number, "ETag": results[part_number]}
251
+ for part_number in sorted(results)
252
+ ]
253
+
254
+ # Complete multipart upload
255
+ s3_client.complete_multipart_upload(
256
+ Bucket=bucket,
257
+ Key=key,
258
+ UploadId=upload_id,
259
+ MultipartUpload={"Parts": parts},
260
+ )
261
+ except Exception as e:
262
+ _logger.warning(
263
+ "Encountered an unexpected error during multipart upload: %s, aborting", e
264
+ )
265
+ s3_client.abort_multipart_upload(
266
+ Bucket=bucket,
267
+ Key=key,
268
+ UploadId=upload_id,
269
+ )
270
+ raise e
271
+
272
+ def list_artifacts(self, path=None):
273
+ artifact_path = self.bucket_path
274
+ dest_path = self.bucket_path
275
+ if path:
276
+ dest_path = posixpath.join(dest_path, path)
277
+ infos = []
278
+ dest_path = dest_path.rstrip("/") if dest_path else ""
279
+ prefix = dest_path + "/" if dest_path else ""
280
+ s3_client = self._get_s3_client()
281
+ paginator = s3_client.get_paginator("list_objects_v2")
282
+ results = paginator.paginate(Bucket=self.bucket, Prefix=prefix, Delimiter="/")
283
+ for result in results:
284
+ # Subdirectories will be listed as "common prefixes" due to the way we made the request
285
+ for obj in result.get("CommonPrefixes", []):
286
+ subdir_path = obj.get("Prefix")
287
+ self._verify_listed_object_contains_artifact_path_prefix(
288
+ listed_object_path=subdir_path, artifact_path=artifact_path
289
+ )
290
+ subdir_rel_path = posixpath.relpath(path=subdir_path, start=artifact_path)
291
+ if subdir_rel_path.endswith("/"):
292
+ subdir_rel_path = subdir_rel_path[:-1]
293
+ infos.append(FileInfo(subdir_rel_path, True, None))
294
+ # Objects listed directly will be files
295
+ for obj in result.get("Contents", []):
296
+ file_path = obj.get("Key")
297
+ self._verify_listed_object_contains_artifact_path_prefix(
298
+ listed_object_path=file_path, artifact_path=artifact_path
299
+ )
300
+ file_rel_path = posixpath.relpath(path=file_path, start=artifact_path)
301
+ file_size = int(obj.get("Size"))
302
+ infos.append(FileInfo(file_rel_path, False, file_size))
303
+ return sorted(infos, key=lambda f: f.path)
304
+
305
+ @staticmethod
306
+ def _verify_listed_object_contains_artifact_path_prefix(listed_object_path, artifact_path):
307
+ if not listed_object_path.startswith(artifact_path):
308
+ raise MlflowException(
309
+ "The path of the listed S3 object does not begin with the specified"
310
+ f" artifact path. Artifact path: {artifact_path}. Object path:"
311
+ f" {listed_object_path}."
312
+ )
313
+
314
+ def _get_presigned_uri(self, remote_file_path):
315
+ s3_client = self._get_s3_client()
316
+ s3_full_path = posixpath.join(self.bucket_path, remote_file_path)
317
+ return s3_client.generate_presigned_url(
318
+ "get_object", Params={"Bucket": self.bucket, "Key": s3_full_path}
319
+ )
320
+
321
+ def _get_read_credential_infos(self, remote_file_paths):
322
+ return [
323
+ ArtifactCredentialInfo(signed_uri=self._get_presigned_uri(path))
324
+ for path in remote_file_paths
325
+ ]
326
+
327
+ def _download_from_cloud(self, remote_file_path, local_path):
328
+ s3_client = self._get_s3_client()
329
+ s3_full_path = posixpath.join(self.bucket_path, remote_file_path)
330
+
331
+ def try_func(creds):
332
+ creds.download_file(self.bucket, s3_full_path, local_path)
333
+
334
+ _retry_with_new_creds(
335
+ try_func=try_func, creds_func=self._refresh_credentials, orig_creds=s3_client
336
+ )
337
+
338
+ def delete_artifacts(self, artifact_path=None):
339
+ dest_path = self.bucket_path
340
+ if artifact_path:
341
+ dest_path = posixpath.join(dest_path, artifact_path)
342
+
343
+ dest_path = dest_path.rstrip("/") if dest_path else ""
344
+ s3_client = self._get_s3_client()
345
+ paginator = s3_client.get_paginator("list_objects_v2")
346
+ results = paginator.paginate(Bucket=self.bucket, Prefix=dest_path)
347
+ for result in results:
348
+ keys = []
349
+ for to_delete_obj in result.get("Contents", []):
350
+ file_path = to_delete_obj.get("Key")
351
+ self._verify_listed_object_contains_artifact_path_prefix(
352
+ listed_object_path=file_path, artifact_path=dest_path
353
+ )
354
+ keys.append({"Key": file_path})
355
+ if keys:
356
+ s3_client.delete_objects(Bucket=self.bucket, Delete={"Objects": keys})