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,257 @@
1
+ """Azure authentication handler with advanced token management."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import threading
6
+ import logging
7
+ from datetime import datetime, timedelta
8
+ from typing import Optional
9
+
10
+ from azure.core.credentials import AccessToken
11
+ from azure.core.exceptions import ClientAuthenticationError
12
+ from azure.identity import (
13
+ DefaultAzureCredential,
14
+ ManagedIdentityCredential,
15
+ ClientSecretCredential,
16
+ )
17
+
18
+ from mlflow.azure.config import AzureAuthConfig, AuthMethod
19
+ from mlflow.azure.exceptions import TokenAcquisitionError
20
+ from mlflow.azure.utils import is_token_expired
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ class TokenCache:
26
+ """Thread-safe token cache with expiration handling."""
27
+
28
+ def __init__(self):
29
+ self._lock = threading.RLock()
30
+ self._token: Optional[AccessToken] = None
31
+ self._expiry: Optional[datetime] = None
32
+
33
+ def get_token(self, buffer_seconds: int = 300) -> Optional[AccessToken]:
34
+ """Get cached token if it's still valid.
35
+
36
+ Args:
37
+ buffer_seconds: Buffer time before expiry to consider token invalid
38
+
39
+ Returns:
40
+ Cached token if valid, None otherwise
41
+ """
42
+ with self._lock:
43
+ if self._token and not is_token_expired(self._expiry, buffer_seconds):
44
+ logger.debug("Using cached token")
45
+ return self._token
46
+
47
+ if self._token:
48
+ logger.debug("Cached token expired or expiring soon")
49
+
50
+ return None
51
+
52
+ def set_token(self, token: AccessToken) -> None:
53
+ """Cache a new token.
54
+
55
+ Args:
56
+ token: Access token to cache
57
+ """
58
+ with self._lock:
59
+ self._token = token
60
+ # Convert timestamp to datetime
61
+ self._expiry = datetime.fromtimestamp(token.expires_on)
62
+
63
+ logger.debug(
64
+ "Token cached, expires at %s (in %d seconds)",
65
+ self._expiry.isoformat(),
66
+ int((self._expiry - datetime.utcnow()).total_seconds()),
67
+ )
68
+
69
+ def clear(self) -> None:
70
+ """Clear the cached token."""
71
+ with self._lock:
72
+ self._token = None
73
+ self._expiry = None
74
+ logger.debug("Token cache cleared")
75
+
76
+
77
+ class AzureAuthHandler:
78
+ """Handles Azure authentication and token management for MLflow PostgreSQL connections."""
79
+
80
+ def __init__(self, config: AzureAuthConfig):
81
+ """Initialize the authentication handler.
82
+
83
+ Args:
84
+ config: Azure authentication configuration
85
+ """
86
+ self.config = config
87
+ self._token_cache = TokenCache()
88
+ self._credential = None
89
+
90
+ if config.enable_debug_logging:
91
+ logging.getLogger().setLevel(logging.DEBUG)
92
+
93
+ logger.info(
94
+ "Initialized Azure auth handler: auth_method=%s, client_id=%s",
95
+ config.auth_method.value,
96
+ config.client_id[:8] + "..." if config.client_id else None,
97
+ )
98
+
99
+ @property
100
+ def credential(self):
101
+ """Get or create Azure credential based on configuration."""
102
+ if self._credential is None:
103
+ self._credential = self._create_credential()
104
+ return self._credential
105
+
106
+ def _create_credential(self):
107
+ """Create appropriate Azure credential based on auth method."""
108
+ auth_method = self.config.auth_method
109
+
110
+ logger.info("Creating Azure credential: auth_method=%s", auth_method.value)
111
+
112
+ try:
113
+ if auth_method == AuthMethod.MANAGED_IDENTITY:
114
+ if self.config.client_id:
115
+ logger.info(
116
+ "Using user-assigned managed identity: client_id=%s", self.config.client_id
117
+ )
118
+ return ManagedIdentityCredential(client_id=self.config.client_id)
119
+ else:
120
+ logger.info("Using system-assigned managed identity")
121
+ return ManagedIdentityCredential()
122
+
123
+ elif auth_method == AuthMethod.SERVICE_PRINCIPAL:
124
+ if not all(
125
+ [self.config.client_id, self.config.client_secret, self.config.tenant_id]
126
+ ):
127
+ raise TokenAcquisitionError(
128
+ "Service principal authentication requires client_id, client_secret, and tenant_id"
129
+ )
130
+
131
+ logger.info(
132
+ "Using service principal authentication: client_id=%s, tenant_id=%s",
133
+ self.config.client_id,
134
+ self.config.tenant_id,
135
+ )
136
+ return ClientSecretCredential(
137
+ tenant_id=self.config.tenant_id,
138
+ client_id=self.config.client_id,
139
+ client_secret=self.config.client_secret,
140
+ )
141
+
142
+ elif auth_method == AuthMethod.DEFAULT_AZURE_CREDENTIAL:
143
+ logger.info("Using DefaultAzureCredential")
144
+ return DefaultAzureCredential()
145
+
146
+ else:
147
+ raise TokenAcquisitionError(f"Unsupported authentication method: {auth_method}")
148
+
149
+ except Exception as e:
150
+ logger.error(
151
+ "Failed to create Azure credential: error=%s, auth_method=%s", str(e), auth_method.value
152
+ )
153
+ raise TokenAcquisitionError(f"Failed to create credential: {e}") from e
154
+
155
+ def _acquire_token_with_retry(self) -> AccessToken:
156
+ """Acquire token with retry logic."""
157
+ last_exception = None
158
+
159
+ for attempt in range(self.config.max_retries):
160
+ try:
161
+ logger.debug("Acquiring new token from Azure (attempt %d)", attempt + 1)
162
+ token = self.credential.get_token(self.config.token_scope)
163
+
164
+ logger.info(
165
+ "Successfully acquired token, expires in %d seconds",
166
+ int(token.expires_on - datetime.utcnow().timestamp()),
167
+ )
168
+
169
+ return token
170
+
171
+ except ClientAuthenticationError as e:
172
+ logger.error("Authentication failed: %s", str(e))
173
+ raise TokenAcquisitionError(f"Authentication failed: {e}") from e
174
+
175
+ except Exception as e:
176
+ last_exception = e
177
+ if attempt < self.config.max_retries - 1:
178
+ delay = self.config.retry_delay * (self.config.retry_backoff ** attempt)
179
+ logger.warning(
180
+ "Token acquisition failed (attempt %d), retrying in %.1f seconds: %s",
181
+ attempt + 1, delay, str(e)
182
+ )
183
+ import time
184
+ time.sleep(delay)
185
+ else:
186
+ logger.error("Token acquisition failed after all retries: %s", str(e))
187
+
188
+ raise TokenAcquisitionError(f"Token acquisition failed: {last_exception}") from last_exception
189
+
190
+ def get_access_token(self, force_refresh: bool = False) -> str:
191
+ """Get a valid access token for PostgreSQL authentication.
192
+
193
+ Args:
194
+ force_refresh: Force token refresh even if cached token is valid
195
+
196
+ Returns:
197
+ Valid access token string
198
+
199
+ Raises:
200
+ TokenAcquisitionError: If token acquisition fails
201
+ """
202
+ if not self.config.should_use_azure_auth:
203
+ raise TokenAcquisitionError("Azure authentication is not enabled")
204
+
205
+ # Try to get cached token first (unless force refresh)
206
+ if not force_refresh:
207
+ cached_token = self._token_cache.get_token(self.config.token_refresh_buffer)
208
+ if cached_token:
209
+ return cached_token.token
210
+
211
+ # Acquire new token
212
+ try:
213
+ new_token = self._acquire_token_with_retry()
214
+ self._token_cache.set_token(new_token)
215
+ return new_token.token
216
+
217
+ except Exception as e:
218
+ logger.error("Failed to acquire access token: %s", str(e))
219
+ raise
220
+
221
+ def refresh_token_if_needed(self) -> bool:
222
+ """Refresh token if it's expiring soon.
223
+
224
+ Returns:
225
+ True if token was refreshed, False otherwise
226
+ """
227
+ if not self.config.should_use_azure_auth:
228
+ return False
229
+
230
+ cached_token = self._token_cache.get_token(self.config.token_refresh_buffer)
231
+ if cached_token:
232
+ return False # Token is still valid
233
+
234
+ try:
235
+ self.get_access_token(force_refresh=True)
236
+ logger.info("Token refreshed proactively")
237
+ return True
238
+ except Exception as e:
239
+ logger.warning("Proactive token refresh failed: %s", str(e))
240
+ return False
241
+
242
+ def clear_token_cache(self) -> None:
243
+ """Clear the token cache."""
244
+ self._token_cache.clear()
245
+ logger.info("Token cache cleared")
246
+
247
+ def is_token_valid(self) -> bool:
248
+ """Check if current cached token is valid.
249
+
250
+ Returns:
251
+ True if token is valid, False otherwise
252
+ """
253
+ if not self.config.should_use_azure_auth:
254
+ return True # SQL auth doesn't use tokens
255
+
256
+ cached_token = self._token_cache.get_token(self.config.token_refresh_buffer)
257
+ return cached_token is not None
mlflow/azure/client.py ADDED
@@ -0,0 +1,319 @@
1
+ """
2
+ This module provides utilities for performing Azure Blob Storage operations without requiring
3
+ the heavyweight azure-storage-blob library dependency
4
+ """
5
+
6
+ import logging
7
+ import urllib
8
+ from copy import deepcopy
9
+
10
+ from mlflow.utils import rest_utils
11
+ from mlflow.utils.file_utils import read_chunk
12
+
13
+ _logger = logging.getLogger(__name__)
14
+ _PUT_BLOCK_HEADERS = {
15
+ "x-ms-blob-type": "BlockBlob",
16
+ }
17
+
18
+
19
+ def put_adls_file_creation(sas_url, headers):
20
+ """Performs an ADLS Azure file create `Put` operation
21
+ (https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create)
22
+
23
+ Args:
24
+ sas_url: A shared access signature URL referring to the Azure ADLS server
25
+ to which the file creation command should be issued.
26
+ headers: Additional headers to include in the Put request body.
27
+ """
28
+ request_url = _append_query_parameters(sas_url, {"resource": "file"})
29
+
30
+ request_headers = {}
31
+ for name, value in headers.items():
32
+ if _is_valid_adls_put_header(name):
33
+ request_headers[name] = value
34
+ else:
35
+ _logger.debug("Removed unsupported '%s' header for ADLS Gen2 Put operation", name)
36
+
37
+ with rest_utils.cloud_storage_http_request(
38
+ "put", request_url, headers=request_headers
39
+ ) as response:
40
+ rest_utils.augmented_raise_for_status(response)
41
+
42
+
43
+ def patch_adls_file_upload(sas_url, local_file, start_byte, size, position, headers, is_single):
44
+ """
45
+ Performs an ADLS Azure file create `Patch` operation
46
+ (https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/update)
47
+
48
+ Args:
49
+ sas_url: A shared access signature URL referring to the Azure ADLS server
50
+ to which the file update command should be issued.
51
+ local_file: The local file to upload
52
+ start_byte: The starting byte of the local file to upload
53
+ size: The number of bytes to upload
54
+ position: Positional offset of the data in the Patch request
55
+ headers: Additional headers to include in the Patch request body
56
+ is_single: Whether this is the only patch operation for this file
57
+ """
58
+ new_params = {"action": "append", "position": str(position)}
59
+ if is_single:
60
+ new_params["flush"] = "true"
61
+ request_url = _append_query_parameters(sas_url, new_params)
62
+
63
+ request_headers = {}
64
+ for name, value in headers.items():
65
+ if _is_valid_adls_patch_header(name):
66
+ request_headers[name] = value
67
+ else:
68
+ _logger.debug("Removed unsupported '%s' header for ADLS Gen2 Patch operation", name)
69
+
70
+ data = read_chunk(local_file, size, start_byte)
71
+ with rest_utils.cloud_storage_http_request(
72
+ "patch", request_url, data=data, headers=request_headers
73
+ ) as response:
74
+ rest_utils.augmented_raise_for_status(response)
75
+
76
+
77
+ def patch_adls_flush(sas_url, position, headers):
78
+ """Performs an ADLS Azure file flush `Patch` operation
79
+ (https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/update)
80
+
81
+ Args:
82
+ sas_url: A shared access signature URL referring to the Azure ADLS server
83
+ to which the file update command should be issued.
84
+ position: The final size of the file to flush.
85
+ headers: Additional headers to include in the Patch request body.
86
+
87
+ """
88
+ request_url = _append_query_parameters(sas_url, {"action": "flush", "position": str(position)})
89
+
90
+ request_headers = {}
91
+ for name, value in headers.items():
92
+ if _is_valid_adls_put_header(name):
93
+ request_headers[name] = value
94
+ else:
95
+ _logger.debug("Removed unsupported '%s' header for ADLS Gen2 Patch operation", name)
96
+
97
+ with rest_utils.cloud_storage_http_request(
98
+ "patch", request_url, headers=request_headers
99
+ ) as response:
100
+ rest_utils.augmented_raise_for_status(response)
101
+
102
+
103
+ def put_block(sas_url, block_id, data, headers):
104
+ """
105
+ Performs an Azure `Put Block` operation
106
+ (https://docs.microsoft.com/en-us/rest/api/storageservices/put-block)
107
+
108
+ Args:
109
+ sas_url: A shared access signature URL referring to the Azure Block Blob
110
+ to which the specified data should be staged.
111
+ block_id: A base64-encoded string identifying the block.
112
+ data: Data to include in the Put Block request body.
113
+ headers: Additional headers to include in the Put Block request body
114
+ (the `x-ms-blob-type` header is always included automatically).
115
+ """
116
+ request_url = _append_query_parameters(sas_url, {"comp": "block", "blockid": block_id})
117
+
118
+ request_headers = deepcopy(_PUT_BLOCK_HEADERS)
119
+ for name, value in headers.items():
120
+ if _is_valid_put_block_header(name):
121
+ request_headers[name] = value
122
+ else:
123
+ _logger.debug("Removed unsupported '%s' header for Put Block operation", name)
124
+
125
+ with rest_utils.cloud_storage_http_request(
126
+ "put", request_url, data=data, headers=request_headers
127
+ ) as response:
128
+ rest_utils.augmented_raise_for_status(response)
129
+
130
+
131
+ def put_block_list(sas_url, block_list, headers):
132
+ """Performs an Azure `Put Block List` operation
133
+ (https://docs.microsoft.com/en-us/rest/api/storageservices/put-block-list)
134
+
135
+ Args:
136
+ sas_url: A shared access signature URL referring to the Azure Block Blob
137
+ to which the specified data should be staged.
138
+ block_list: A list of uncommitted base64-encoded string block IDs to commit. For
139
+ more information, see
140
+ https://docs.microsoft.com/en-us/rest/api/storageservices/put-block-list.
141
+ headers: Headers to include in the Put Block request body.
142
+
143
+ """
144
+ request_url = _append_query_parameters(sas_url, {"comp": "blocklist"})
145
+ data = _build_block_list_xml(block_list)
146
+
147
+ request_headers = {}
148
+ for name, value in headers.items():
149
+ if _is_valid_put_block_list_header(name):
150
+ request_headers[name] = value
151
+ else:
152
+ _logger.debug("Removed unsupported '%s' header for Put Block List operation", name)
153
+
154
+ with rest_utils.cloud_storage_http_request(
155
+ "put", request_url, data=data, headers=request_headers
156
+ ) as response:
157
+ rest_utils.augmented_raise_for_status(response)
158
+
159
+
160
+ def _append_query_parameters(url, parameters):
161
+ parsed_url = urllib.parse.urlparse(url)
162
+ query_dict = dict(urllib.parse.parse_qsl(parsed_url.query))
163
+ query_dict.update(parameters)
164
+ new_query = urllib.parse.urlencode(query_dict)
165
+ new_url_components = parsed_url._replace(query=new_query)
166
+ return urllib.parse.urlunparse(new_url_components)
167
+
168
+
169
+ def _build_block_list_xml(block_list):
170
+ xml = '<?xml version="1.0" encoding="utf-8"?>\n<BlockList>\n'
171
+ for block_id in block_list:
172
+ # Because block IDs are base64-encoded and base64 strings do not contain
173
+ # XML special characters, we can safely insert the block ID directly into
174
+ # the XML document
175
+ xml += f"<Uncommitted>{block_id}</Uncommitted>\n"
176
+ xml += "</BlockList>"
177
+ return xml
178
+
179
+
180
+ def _is_valid_put_block_list_header(header_name):
181
+ """
182
+ Returns:
183
+ True if the specified header name is a valid header for the Put Block List operation,
184
+ False otherwise. For a list of valid headers, see https://docs.microsoft.com/en-us/
185
+ rest/api/storageservices/put-block-list#request-headers and https://docs.microsoft.com/
186
+ en-us/rest/api/storageservices/
187
+ specifying-conditional-headers-for-blob-service-operations#Subheading1.
188
+ """
189
+ return header_name.startswith("x-ms-meta-") or header_name in {
190
+ "Authorization",
191
+ "Date",
192
+ "x-ms-date",
193
+ "x-ms-version",
194
+ "Content-Length",
195
+ "Content-MD5",
196
+ "x-ms-content-crc64",
197
+ "x-ms-blob-cache-control",
198
+ "x-ms-blob-content-type",
199
+ "x-ms-blob-content-encoding",
200
+ "x-ms-blob-content-language",
201
+ "x-ms-blob-content-md5",
202
+ "x-ms-encryption-scope",
203
+ "x-ms-tags",
204
+ "x-ms-lease-id",
205
+ "x-ms-client-request-id",
206
+ "x-ms-blob-content-disposition",
207
+ "x-ms-access-tier",
208
+ "If-Modified-Since",
209
+ "If-Unmodified-Since",
210
+ "If-Match",
211
+ "If-None-Match",
212
+ }
213
+
214
+
215
+ def _is_valid_put_block_header(header_name):
216
+ """
217
+ Returns:
218
+ True if the specified header name is a valid header for the Put Block operation, False
219
+ otherwise. For a list of valid headers, see
220
+ https://docs.microsoft.com/en-us/rest/api/storageservices/put-block#request-headers and
221
+ https://docs.microsoft.com/en-us/rest/api/storageservices/put-block#
222
+ request-headers-customer-provided-encryption-keys.
223
+ """
224
+ return header_name in {
225
+ "Authorization",
226
+ "x-ms-date",
227
+ "x-ms-version",
228
+ "Content-Length",
229
+ "Content-MD5",
230
+ "x-ms-content-crc64",
231
+ "x-ms-encryption-scope",
232
+ "x-ms-lease-id",
233
+ "x-ms-client-request-id",
234
+ "x-ms-encryption-key",
235
+ "x-ms-encryption-key-sha256",
236
+ "x-ms-encryption-algorithm",
237
+ }
238
+
239
+
240
+ def _is_valid_adls_put_header(header_name):
241
+ """
242
+ Returns:
243
+ True if the specified header name is a valid header for the ADLS Put operation, False
244
+ otherwise. For a list of valid headers, see
245
+ https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create
246
+ """
247
+ return header_name in {
248
+ "Cache-Control",
249
+ "Content-Encoding",
250
+ "Content-Language",
251
+ "Content-Disposition",
252
+ "x-ms-cache-control",
253
+ "x-ms-content-type",
254
+ "x-ms-content-encoding",
255
+ "x-ms-content-language",
256
+ "x-ms-content-disposition",
257
+ "x-ms-rename-source",
258
+ "x-ms-lease-id",
259
+ "x-ms-properties",
260
+ "x-ms-permissions",
261
+ "x-ms-umask",
262
+ "x-ms-owner",
263
+ "x-ms-group",
264
+ "x-ms-acl",
265
+ "x-ms-proposed-lease-id",
266
+ "x-ms-expiry-option",
267
+ "x-ms-expiry-time",
268
+ "If-Match",
269
+ "If-None-Match",
270
+ "If-Modified-Since",
271
+ "If-Unmodified-Since",
272
+ "x-ms-source-if-match",
273
+ "x-ms-source-if-none-match",
274
+ "x-ms-source-if-modified-since",
275
+ "x-ms-source-if-unmodified-since",
276
+ "x-ms-encryption-key",
277
+ "x-ms-encryption-key-sha256",
278
+ "x-ms-encryption-algorithm",
279
+ "x-ms-encryption-context",
280
+ "x-ms-client-request-id",
281
+ "x-ms-date",
282
+ "x-ms-version",
283
+ }
284
+
285
+
286
+ def _is_valid_adls_patch_header(header_name):
287
+ """
288
+ Returns:
289
+ True if the specified header name is a valid header for the ADLS Patch operation, False
290
+ otherwise. For a list of valid headers, see
291
+ https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/update
292
+ """
293
+ return header_name in {
294
+ "Content-Length",
295
+ "Content-MD5",
296
+ "x-ms-lease-id",
297
+ "x-ms-cache-control",
298
+ "x-ms-content-type",
299
+ "x-ms-content-disposition",
300
+ "x-ms-content-encoding",
301
+ "x-ms-content-language",
302
+ "x-ms-content-md5",
303
+ "x-ms-properties",
304
+ "x-ms-owner",
305
+ "x-ms-group",
306
+ "x-ms-permissions",
307
+ "x-ms-acl",
308
+ "If-Match",
309
+ "If-None-Match",
310
+ "If-Modified-Since",
311
+ "If-Unmodified-Since",
312
+ "x-ms-encryption-key",
313
+ "x-ms-encryption-key-sha256",
314
+ "x-ms-encryption-algorithm",
315
+ "x-ms-encryption-context",
316
+ "x-ms-client-request-id",
317
+ "x-ms-date",
318
+ "x-ms-version",
319
+ }
mlflow/azure/config.py ADDED
@@ -0,0 +1,120 @@
1
+ """Configuration management for Azure authentication."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from enum import Enum
6
+ import os
7
+ from typing import Optional
8
+
9
+
10
+ class AuthMethod(str, Enum):
11
+ """Supported authentication methods."""
12
+
13
+ MANAGED_IDENTITY = "managed_identity"
14
+ SERVICE_PRINCIPAL = "service_principal"
15
+ SQL_AUTH = "sql_auth"
16
+ DEFAULT_AZURE_CREDENTIAL = "default_azure_credential"
17
+
18
+
19
+ class AzureAuthConfig:
20
+ """Configuration for Azure authentication.
21
+
22
+ This configuration can be loaded from environment variables or
23
+ provided programmatically.
24
+ """
25
+
26
+ def __init__(
27
+ self,
28
+ auth_enabled: Optional[bool] = None,
29
+ auth_method: Optional[str] = None,
30
+ client_id: Optional[str] = None,
31
+ client_secret: Optional[str] = None,
32
+ tenant_id: Optional[str] = None,
33
+ token_scope: str = "https://ossrdbms-aad.database.windows.net/.default",
34
+ connection_timeout: int = 30,
35
+ token_refresh_buffer: int = 300,
36
+ pool_size: int = 20,
37
+ max_overflow: int = 10,
38
+ pool_recycle: int = 3600,
39
+ pool_pre_ping: bool = True,
40
+ max_retries: int = 3,
41
+ retry_delay: float = 1.0,
42
+ retry_backoff: float = 2.0,
43
+ enable_debug_logging: bool = False,
44
+ ):
45
+ """Initialize Azure authentication configuration."""
46
+
47
+ # Core settings - use provided values or environment variables
48
+ self.auth_enabled = (
49
+ auth_enabled
50
+ if auth_enabled is not None
51
+ else os.getenv("MLFLOW_AZURE_AUTH_ENABLED", "false").lower() == "true"
52
+ )
53
+
54
+ self.auth_method = AuthMethod(
55
+ auth_method.lower()
56
+ if auth_method
57
+ else os.getenv("MLFLOW_AZURE_AUTH_METHOD", "sql_auth").lower()
58
+ )
59
+
60
+ # Azure specific settings - check both provided values and environment
61
+ self.client_id = client_id or os.getenv("AZURE_CLIENT_ID")
62
+ self.client_secret = client_secret or os.getenv("AZURE_CLIENT_SECRET")
63
+ self.tenant_id = tenant_id or os.getenv("AZURE_TENANT_ID")
64
+
65
+ # Connection settings
66
+ self.token_scope = token_scope
67
+ self.connection_timeout = connection_timeout
68
+ self.token_refresh_buffer = token_refresh_buffer
69
+
70
+ # Pool settings
71
+ self.pool_size = pool_size
72
+ self.max_overflow = max_overflow
73
+ self.pool_recycle = pool_recycle
74
+ self.pool_pre_ping = pool_pre_ping
75
+
76
+ # Retry settings
77
+ self.max_retries = max_retries
78
+ self.retry_delay = retry_delay
79
+ self.retry_backoff = retry_backoff
80
+
81
+ # Logging
82
+ self.enable_debug_logging = (
83
+ enable_debug_logging
84
+ or os.getenv("MLFLOW_AZURE_DEBUG", "false").lower() == "true"
85
+ )
86
+
87
+ # Additional environment variable checks
88
+ # Only override auth method if not explicitly set
89
+ if (os.getenv("MLFLOW_POSTGRES_USE_MANAGED_IDENTITY", "false").lower() == "true" and
90
+ auth_method is None and
91
+ os.getenv("MLFLOW_AZURE_AUTH_METHOD") is None):
92
+ self.auth_enabled = True
93
+ self.auth_method = AuthMethod.MANAGED_IDENTITY
94
+
95
+ # Validate configuration
96
+ self._validate()
97
+
98
+ def _validate(self):
99
+ """Validate configuration settings."""
100
+ if self.auth_method == AuthMethod.SERVICE_PRINCIPAL:
101
+ if not self.client_secret:
102
+ raise ValueError("client_secret is required for service principal authentication")
103
+ if not self.client_id:
104
+ raise ValueError("client_id is required for service principal authentication")
105
+ if not self.tenant_id:
106
+ raise ValueError("tenant_id is required for service principal authentication")
107
+
108
+ @property
109
+ def should_use_azure_auth(self) -> bool:
110
+ """Check if Azure authentication should be used."""
111
+ return self.auth_enabled and self.auth_method != AuthMethod.SQL_AUTH
112
+
113
+ @property
114
+ def requires_token_refresh(self) -> bool:
115
+ """Check if the auth method requires token refresh."""
116
+ return self.auth_method in [
117
+ AuthMethod.MANAGED_IDENTITY,
118
+ AuthMethod.SERVICE_PRINCIPAL,
119
+ AuthMethod.DEFAULT_AZURE_CREDENTIAL,
120
+ ]