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,458 @@
1
+ import logging
2
+ import os
3
+ import re
4
+ import shutil
5
+ import sys
6
+ import tempfile
7
+ import uuid
8
+ from pathlib import Path
9
+ from typing import Literal, Optional
10
+
11
+ from packaging.version import Version
12
+
13
+ import mlflow
14
+ from mlflow.environment_variables import _MLFLOW_TESTING, MLFLOW_ENV_ROOT
15
+ from mlflow.exceptions import MlflowException
16
+ from mlflow.models.model import MLMODEL_FILE_NAME, Model
17
+ from mlflow.utils import env_manager as em
18
+ from mlflow.utils.conda import _PIP_CACHE_DIR
19
+ from mlflow.utils.databricks_utils import is_in_databricks_runtime
20
+ from mlflow.utils.environment import (
21
+ _CONDA_ENV_FILE_NAME,
22
+ _PYTHON_ENV_FILE_NAME,
23
+ _REQUIREMENTS_FILE_NAME,
24
+ _get_mlflow_env_name,
25
+ _PythonEnv,
26
+ )
27
+ from mlflow.utils.file_utils import remove_on_error
28
+ from mlflow.utils.os import is_windows
29
+ from mlflow.utils.process import _exec_cmd, _join_commands
30
+ from mlflow.utils.requirements_utils import _parse_requirements
31
+
32
+ _logger = logging.getLogger(__name__)
33
+
34
+
35
+ def _get_mlflow_virtualenv_root():
36
+ """
37
+ Returns the root directory to store virtualenv environments created by MLflow.
38
+ """
39
+ return MLFLOW_ENV_ROOT.get()
40
+
41
+
42
+ _DATABRICKS_PYENV_BIN_PATH = "/databricks/.pyenv/bin/pyenv"
43
+
44
+
45
+ def _is_pyenv_available():
46
+ """
47
+ Returns True if pyenv is available, otherwise False.
48
+ """
49
+ return _get_pyenv_bin_path() is not None
50
+
51
+
52
+ def _validate_pyenv_is_available():
53
+ """
54
+ Validates pyenv is available. If not, throws an `MlflowException` with a brief instruction on
55
+ how to install pyenv.
56
+ """
57
+ url = (
58
+ "https://github.com/pyenv/pyenv#installation"
59
+ if not is_windows()
60
+ else "https://github.com/pyenv-win/pyenv-win#installation"
61
+ )
62
+ if not _is_pyenv_available():
63
+ raise MlflowException(
64
+ f"Could not find the pyenv binary. See {url} for installation instructions."
65
+ )
66
+
67
+
68
+ def _is_virtualenv_available():
69
+ """
70
+ Returns True if virtualenv is available, otherwise False.
71
+ """
72
+ return shutil.which("virtualenv") is not None
73
+
74
+
75
+ def _validate_virtualenv_is_available():
76
+ """
77
+ Validates virtualenv is available. If not, throws an `MlflowException` with a brief instruction
78
+ on how to install virtualenv.
79
+ """
80
+ if not _is_virtualenv_available():
81
+ raise MlflowException(
82
+ "Could not find the virtualenv binary. Run `pip install virtualenv` to install "
83
+ "virtualenv."
84
+ )
85
+
86
+
87
+ _SEMANTIC_VERSION_REGEX = re.compile(r"^([0-9]+)\.([0-9]+)\.([0-9]+)$")
88
+
89
+
90
+ def _get_pyenv_bin_path():
91
+ if os.path.exists(_DATABRICKS_PYENV_BIN_PATH):
92
+ return _DATABRICKS_PYENV_BIN_PATH
93
+ return shutil.which("pyenv")
94
+
95
+
96
+ def _find_latest_installable_python_version(version_prefix):
97
+ """
98
+ Find the latest installable python version that matches the given version prefix
99
+ from the output of `pyenv install --list`. For example, `version_prefix("3.8")` returns '3.8.x'
100
+ where 'x' represents the latest micro version in 3.8.
101
+ """
102
+ lines = _exec_cmd(
103
+ [_get_pyenv_bin_path(), "install", "--list"],
104
+ capture_output=True,
105
+ shell=is_windows(),
106
+ ).stdout.splitlines()
107
+ semantic_versions = filter(_SEMANTIC_VERSION_REGEX.match, map(str.strip, lines))
108
+ matched = [v for v in semantic_versions if v.startswith(version_prefix)]
109
+ if not matched:
110
+ raise MlflowException(f"Could not find python version that matches {version_prefix}")
111
+ return sorted(matched, key=Version)[-1]
112
+
113
+
114
+ def _install_python(version, pyenv_root=None, capture_output=False):
115
+ """Installs a specified version of python with pyenv and returns a path to the installed python
116
+ binary.
117
+
118
+ Args:
119
+ version: Python version to install.
120
+ pyenv_root: The value of the "PYENV_ROOT" environment variable used when running
121
+ `pyenv install` which installs python in `{PYENV_ROOT}/versions/{version}`.
122
+ capture_output: Set the `capture_output` argument when calling `_exec_cmd`.
123
+
124
+ Returns:
125
+ Path to the installed python binary.
126
+ """
127
+ version = (
128
+ version
129
+ if _SEMANTIC_VERSION_REGEX.match(version)
130
+ else _find_latest_installable_python_version(version)
131
+ )
132
+ _logger.info("Installing python %s if it does not exist", version)
133
+ # pyenv-win doesn't support `--skip-existing` but its behavior is enabled by default
134
+ # https://github.com/pyenv-win/pyenv-win/pull/314
135
+ pyenv_install_options = ("--skip-existing",) if not is_windows() else ()
136
+ extra_env = {"PYENV_ROOT": pyenv_root} if pyenv_root else None
137
+ pyenv_bin_path = _get_pyenv_bin_path()
138
+ _exec_cmd(
139
+ [pyenv_bin_path, "install", *pyenv_install_options, version],
140
+ capture_output=capture_output,
141
+ # Windows fails to find pyenv and throws `FileNotFoundError` without `shell=True`
142
+ shell=is_windows(),
143
+ extra_env=extra_env,
144
+ )
145
+
146
+ if not is_windows():
147
+ if pyenv_root is None:
148
+ pyenv_root = _exec_cmd([pyenv_bin_path, "root"], capture_output=True).stdout.strip()
149
+ path_to_bin = ("bin", "python")
150
+ else:
151
+ # pyenv-win doesn't provide the `pyenv root` command
152
+ pyenv_root = os.getenv("PYENV_ROOT")
153
+ if pyenv_root is None:
154
+ raise MlflowException("Environment variable 'PYENV_ROOT' must be set")
155
+ path_to_bin = ("python.exe",)
156
+ return Path(pyenv_root).joinpath("versions", version, *path_to_bin)
157
+
158
+
159
+ def _get_conda_env_file(model_config):
160
+ from mlflow.pyfunc import _extract_conda_env
161
+
162
+ for flavor, config in model_config.flavors.items():
163
+ if flavor == mlflow.pyfunc.FLAVOR_NAME:
164
+ env = config.get(mlflow.pyfunc.ENV)
165
+ if env:
166
+ return _extract_conda_env(env)
167
+ return _CONDA_ENV_FILE_NAME
168
+
169
+
170
+ def _get_python_env_file(model_config):
171
+ from mlflow.pyfunc import EnvType
172
+
173
+ for flavor, config in model_config.flavors.items():
174
+ if flavor == mlflow.pyfunc.FLAVOR_NAME:
175
+ env = config.get(mlflow.pyfunc.ENV)
176
+ if isinstance(env, dict):
177
+ # Models saved in MLflow >= 2.0 use a dictionary for the pyfunc flavor
178
+ # `env` config, where the keys are different environment managers (e.g.
179
+ # conda, virtualenv) and the values are corresponding environment paths
180
+ return env[EnvType.VIRTUALENV]
181
+ return _PYTHON_ENV_FILE_NAME
182
+
183
+
184
+ def _get_python_env(local_model_path):
185
+ """Constructs `_PythonEnv` from the model artifacts stored in `local_model_path`. If
186
+ `python_env.yaml` is available, use it, otherwise extract model dependencies from `conda.yaml`.
187
+ If `conda.yaml` contains conda dependencies except `python`, `pip`, `setuptools`, and, `wheel`,
188
+ an `MlflowException` is thrown because conda dependencies cannot be installed in a virtualenv
189
+ environment.
190
+
191
+ Args:
192
+ local_model_path: Local directory containing the model artifacts.
193
+
194
+ Returns:
195
+ `_PythonEnv` instance.
196
+
197
+ """
198
+ model_config = Model.load(local_model_path / MLMODEL_FILE_NAME)
199
+ python_env_file = local_model_path / _get_python_env_file(model_config)
200
+ conda_env_file = local_model_path / _get_conda_env_file(model_config)
201
+ requirements_file = local_model_path / _REQUIREMENTS_FILE_NAME
202
+
203
+ if python_env_file.exists():
204
+ return _PythonEnv.from_yaml(python_env_file)
205
+ else:
206
+ _logger.info(
207
+ "This model is missing %s, which is because it was logged in an older version"
208
+ "of MLflow (< 1.26.0) that does not support restoring a model environment with "
209
+ "virtualenv. Attempting to extract model dependencies from %s and %s instead.",
210
+ _PYTHON_ENV_FILE_NAME,
211
+ _REQUIREMENTS_FILE_NAME,
212
+ _CONDA_ENV_FILE_NAME,
213
+ )
214
+ if requirements_file.exists():
215
+ deps = _PythonEnv.get_dependencies_from_conda_yaml(conda_env_file)
216
+ return _PythonEnv(
217
+ python=deps["python"],
218
+ build_dependencies=deps["build_dependencies"],
219
+ dependencies=[f"-r {_REQUIREMENTS_FILE_NAME}"],
220
+ )
221
+ else:
222
+ return _PythonEnv.from_conda_yaml(conda_env_file)
223
+
224
+
225
+ def _get_virtualenv_name(python_env, work_dir_path, env_id=None):
226
+ requirements = _parse_requirements(
227
+ python_env.dependencies,
228
+ is_constraint=False,
229
+ base_dir=work_dir_path,
230
+ )
231
+ return _get_mlflow_env_name(
232
+ str(python_env) + "".join(map(str, sorted(requirements))) + (env_id or "")
233
+ )
234
+
235
+
236
+ def _get_virtualenv_activate_cmd(env_dir: Path) -> str:
237
+ # Created a command to activate the environment
238
+ paths = ("bin", "activate") if not is_windows() else ("Scripts", "activate.bat")
239
+ activate_cmd = env_dir.joinpath(*paths)
240
+ return f"source {activate_cmd}" if not is_windows() else str(activate_cmd)
241
+
242
+
243
+ def _create_virtualenv(
244
+ local_model_path: Path,
245
+ python_env: _PythonEnv,
246
+ env_dir: Path,
247
+ pyenv_root_dir: Optional[str] = None,
248
+ env_manager: Literal["virtualenv", "uv"] = em.UV,
249
+ extra_env: Optional[dict[str, str]] = None,
250
+ capture_output: bool = False,
251
+ pip_requirements_override: Optional[list[str]] = None,
252
+ ):
253
+ if env_manager not in {em.VIRTUALENV, em.UV}:
254
+ raise MlflowException.invalid_parameter_value(
255
+ f"Invalid value for `env_manager`: {env_manager}. "
256
+ f"Must be one of `{em.VIRTUALENV}, {em.UV}`"
257
+ )
258
+
259
+ activate_cmd = _get_virtualenv_activate_cmd(env_dir)
260
+ if env_dir.exists():
261
+ _logger.info(f"Environment {env_dir} already exists")
262
+ return activate_cmd
263
+
264
+ if env_manager == em.VIRTUALENV:
265
+ python_bin_path = _install_python(
266
+ python_env.python, pyenv_root=pyenv_root_dir, capture_output=capture_output
267
+ )
268
+ _logger.info(f"Creating a new environment in {env_dir} with {python_bin_path}")
269
+ env_creation_cmd = [
270
+ sys.executable,
271
+ "-m",
272
+ "virtualenv",
273
+ "--python",
274
+ python_bin_path,
275
+ env_dir,
276
+ ]
277
+ install_deps_cmd_prefix = "python -m pip install"
278
+ elif env_manager == em.UV:
279
+ _logger.info(
280
+ f"Creating a new environment in {env_dir} with python "
281
+ f"version {python_env.python} using uv"
282
+ )
283
+ env_creation_cmd = ["uv", "venv", env_dir, f"--python={python_env.python}"]
284
+ install_deps_cmd_prefix = "uv pip install --prerelease=allow"
285
+ if _MLFLOW_TESTING.get():
286
+ os.environ["RUST_LOG"] = "uv=debug"
287
+ with remove_on_error(
288
+ env_dir,
289
+ onerror=lambda e: _logger.warning(
290
+ "Encountered an unexpected error: %s while creating a virtualenv environment in %s, "
291
+ "removing the environment directory...",
292
+ repr(e),
293
+ env_dir,
294
+ ),
295
+ ):
296
+ _exec_cmd(
297
+ env_creation_cmd,
298
+ capture_output=capture_output,
299
+ )
300
+
301
+ _logger.info("Installing dependencies")
302
+ for deps in filter(None, [python_env.build_dependencies, python_env.dependencies]):
303
+ with tempfile.TemporaryDirectory() as tmpdir:
304
+ # Create a temporary requirements file in the model directory to resolve the
305
+ # references in it correctly. To do this, we must first symlink or copy the model
306
+ # directory's contents to a temporary location for compatibility with deployment
307
+ # tools that store models in a read-only mount
308
+ try:
309
+ for model_item in os.listdir(local_model_path):
310
+ os.symlink(
311
+ src=os.path.join(local_model_path, model_item),
312
+ dst=os.path.join(tmpdir, model_item),
313
+ )
314
+ except Exception as e:
315
+ _logger.warning(
316
+ "Failed to symlink model directory during dependency installation"
317
+ " Copying instead. Exception: %s",
318
+ e,
319
+ )
320
+ _copy_model_to_writeable_destination(local_model_path, tmpdir)
321
+
322
+ tmp_req_file = f"requirements.{uuid.uuid4().hex}.txt"
323
+ Path(tmpdir).joinpath(tmp_req_file).write_text("\n".join(deps))
324
+ cmd = _join_commands(activate_cmd, f"{install_deps_cmd_prefix} -r {tmp_req_file}")
325
+ _exec_cmd(cmd, capture_output=capture_output, cwd=tmpdir, extra_env=extra_env)
326
+
327
+ if pip_requirements_override:
328
+ _logger.info(
329
+ "Installing additional dependencies specified by "
330
+ f"pip_requirements_override: {pip_requirements_override}"
331
+ )
332
+ cmd = _join_commands(
333
+ activate_cmd,
334
+ f"{install_deps_cmd_prefix} --quiet {' '.join(pip_requirements_override)}",
335
+ )
336
+ _exec_cmd(cmd, capture_output=capture_output, extra_env=extra_env)
337
+
338
+ return activate_cmd
339
+
340
+
341
+ def _copy_model_to_writeable_destination(model_src, dst):
342
+ """
343
+ Copies the specified `model_src` directory, which may be read-only, to the writeable `dst`
344
+ directory.
345
+ """
346
+ os.makedirs(dst, exist_ok=True)
347
+ for model_item in os.listdir(model_src):
348
+ # Copy individual files and subdirectories, rather than using `shutil.copytree()`
349
+ # because `shutil.copytree()` will apply the permissions from the source directory,
350
+ # which may be read-only
351
+ copy_fn = shutil.copytree if os.path.isdir(model_item) else shutil.copy2
352
+
353
+ copy_fn(
354
+ src=os.path.join(model_src, model_item),
355
+ dst=os.path.join(dst, model_item),
356
+ )
357
+
358
+
359
+ def _get_virtualenv_extra_env_vars(env_root_dir=None):
360
+ extra_env = {
361
+ # PIP_NO_INPUT=1 makes pip run in non-interactive mode,
362
+ # otherwise pip might prompt "yes or no" and ask stdin input
363
+ "PIP_NO_INPUT": "1",
364
+ }
365
+ if env_root_dir is not None:
366
+ # Note: Both conda pip and virtualenv can use the pip cache directory.
367
+ extra_env["PIP_CACHE_DIR"] = os.path.join(env_root_dir, _PIP_CACHE_DIR)
368
+ return extra_env
369
+
370
+
371
+ _VIRTUALENV_ENVS_DIR = "virtualenv_envs"
372
+ _PYENV_ROOT_DIR = "pyenv_root"
373
+
374
+
375
+ def _get_or_create_virtualenv( # noqa: D417
376
+ local_model_path,
377
+ env_id=None,
378
+ env_root_dir=None,
379
+ capture_output=False,
380
+ pip_requirements_override: Optional[list[str]] = None,
381
+ env_manager: Literal["virtualenv", "uv"] = em.UV,
382
+ ):
383
+ """Restores an MLflow model's environment in a virtual environment and returns a command
384
+ to activate it.
385
+
386
+ Args:
387
+ local_model_path: Local directory containing the model artifacts.
388
+ env_id: Optional string that is added to the contents of the yaml file before
389
+ calculating the hash. It can be used to distinguish environments that have the
390
+ same conda dependencies but are supposed to be different based on the context.
391
+ For example, when serving the model we may install additional dependencies to the
392
+ environment after the environment has been activated.
393
+ pip_requirements_override: If specified, install the specified python dependencies to
394
+ the environment (upgrade if already installed).
395
+ env_manager: Specifies the environment manager to use to create the environment.
396
+ Defaults to "uv".
397
+
398
+ .. tip::
399
+ It is highly recommended to use "uv" as it has significant performance improvements
400
+ over "virtualenv".
401
+
402
+ Returns:
403
+ Command to activate the created virtual environment
404
+ (e.g. "source /path/to/bin/activate").
405
+
406
+ """
407
+ if env_manager == em.VIRTUALENV:
408
+ _validate_pyenv_is_available()
409
+ _validate_virtualenv_is_available()
410
+
411
+ local_model_path = Path(local_model_path)
412
+ python_env = _get_python_env(local_model_path)
413
+
414
+ pyenv_root_dir = None
415
+ if env_root_dir is None:
416
+ virtual_envs_root_path = Path(_get_mlflow_virtualenv_root())
417
+ else:
418
+ virtual_envs_root_path = Path(env_root_dir) / _VIRTUALENV_ENVS_DIR
419
+ if env_manager == em.VIRTUALENV:
420
+ pyenv_root_path = Path(env_root_dir) / _PYENV_ROOT_DIR
421
+ pyenv_root_path.mkdir(parents=True, exist_ok=True)
422
+ pyenv_root_dir = str(pyenv_root_path)
423
+
424
+ virtual_envs_root_path.mkdir(parents=True, exist_ok=True)
425
+ env_name = _get_virtualenv_name(python_env, local_model_path, env_id)
426
+ env_dir = virtual_envs_root_path / env_name
427
+ try:
428
+ env_dir.exists()
429
+ except PermissionError:
430
+ if is_in_databricks_runtime():
431
+ # Updating env_name only doesn't work because the cluster may not have
432
+ # permission to access the original virtual_envs_root_path
433
+ virtual_envs_root_path = (
434
+ Path(env_root_dir) / f"{_VIRTUALENV_ENVS_DIR}_{uuid.uuid4().hex[:8]}"
435
+ )
436
+ virtual_envs_root_path.mkdir(parents=True, exist_ok=True)
437
+ env_dir = virtual_envs_root_path / env_name
438
+ else:
439
+ _logger.warning(
440
+ f"Existing virtual environment directory {env_dir} cannot be accessed "
441
+ "due to permission error. Check the permissions of the directory and "
442
+ "try again. If the issue persists, consider cleaning up the directory manually."
443
+ )
444
+ raise
445
+
446
+ extra_env = _get_virtualenv_extra_env_vars(env_root_dir)
447
+
448
+ # Create an environment
449
+ return _create_virtualenv(
450
+ local_model_path=local_model_path,
451
+ python_env=python_env,
452
+ env_dir=env_dir,
453
+ pyenv_root_dir=pyenv_root_dir,
454
+ env_manager=env_manager,
455
+ extra_env=extra_env,
456
+ capture_output=capture_output,
457
+ pip_requirements_override=pip_requirements_override,
458
+ )
@@ -0,0 +1,25 @@
1
+ import warnings
2
+
3
+ # ANSI escape code
4
+ ANSI_BASE = "\033["
5
+ COLORS = {
6
+ "default_bold": f"{ANSI_BASE}1m",
7
+ "red": f"{ANSI_BASE}31m",
8
+ "red_bold": f"{ANSI_BASE}1;31m",
9
+ "yellow": f"{ANSI_BASE}33m",
10
+ "yellow_bold": f"{ANSI_BASE}1;33m",
11
+ "blue": f"{ANSI_BASE}34m",
12
+ "blue_bold": f"{ANSI_BASE}1;34m",
13
+ }
14
+ RESET = "\033[0m"
15
+
16
+
17
+ def color_warning(message: str, stacklevel: int, color: str, category: type[Warning] = UserWarning):
18
+ if color in COLORS:
19
+ message = f"{COLORS[color]}{message}{RESET}"
20
+
21
+ warnings.warn(
22
+ message=message,
23
+ category=category,
24
+ stacklevel=stacklevel + 1,
25
+ )
@@ -0,0 +1,179 @@
1
+ import codecs
2
+ import json
3
+ import os
4
+ import pathlib
5
+ import shutil
6
+ import tempfile
7
+
8
+ import yaml
9
+
10
+ from mlflow.utils.file_utils import ENCODING, exists, get_parent_dir
11
+
12
+ try:
13
+ from yaml import CSafeDumper as YamlSafeDumper
14
+ from yaml import CSafeLoader as YamlSafeLoader
15
+
16
+ except ImportError:
17
+ from yaml import SafeDumper as YamlSafeDumper
18
+ from yaml import SafeLoader as YamlSafeLoader
19
+
20
+ from mlflow.exceptions import MissingConfigException
21
+ from mlflow.utils import merge_dicts
22
+
23
+
24
+ def write_yaml(root, file_name, data, overwrite=False, sort_keys=True, ensure_yaml_extension=True):
25
+ """Write dictionary data in yaml format.
26
+
27
+ Args:
28
+ root: Directory name.
29
+ file_name: Desired file name.
30
+ data: Data to be dumped as yaml format.
31
+ overwrite: If True, will overwrite existing files.
32
+ sort_keys: Whether to sort the keys when writing the yaml file.
33
+ ensure_yaml_extension: If True, will automatically add .yaml extension if not given.
34
+ """
35
+ if not exists(root):
36
+ raise MissingConfigException(f"Parent directory '{root}' does not exist.")
37
+
38
+ file_path = os.path.join(root, file_name)
39
+ yaml_file_name = file_path
40
+ if ensure_yaml_extension and not file_path.endswith(".yaml"):
41
+ yaml_file_name = file_path + ".yaml"
42
+
43
+ if exists(yaml_file_name) and not overwrite:
44
+ raise Exception(f"Yaml file '{file_path}' exists as '{yaml_file_name}")
45
+
46
+ with codecs.open(yaml_file_name, mode="w", encoding=ENCODING) as yaml_file:
47
+ yaml.dump(
48
+ data,
49
+ yaml_file,
50
+ default_flow_style=False,
51
+ allow_unicode=True,
52
+ sort_keys=sort_keys,
53
+ Dumper=YamlSafeDumper,
54
+ )
55
+
56
+
57
+ def overwrite_yaml(root, file_name, data, ensure_yaml_extension=True):
58
+ """Safely overwrites a preexisting yaml file, ensuring that file contents are not deleted or
59
+ corrupted if the write fails. This is achieved by writing contents to a temporary file
60
+ and moving the temporary file to replace the preexisting file, rather than opening the
61
+ preexisting file for a direct write.
62
+
63
+ Args:
64
+ root: Directory name.
65
+ file_name: File name.
66
+ data: The data to write, represented as a dictionary.
67
+ ensure_yaml_extension: If True, Will automatically add .yaml extension if not given.
68
+ """
69
+ tmp_file_path = None
70
+ original_file_path = os.path.join(root, file_name)
71
+ original_file_mode = os.stat(original_file_path).st_mode
72
+ try:
73
+ tmp_file_fd, tmp_file_path = tempfile.mkstemp(suffix="file.yaml")
74
+ os.close(tmp_file_fd)
75
+ write_yaml(
76
+ root=get_parent_dir(tmp_file_path),
77
+ file_name=os.path.basename(tmp_file_path),
78
+ data=data,
79
+ overwrite=True,
80
+ sort_keys=True,
81
+ ensure_yaml_extension=ensure_yaml_extension,
82
+ )
83
+ shutil.move(tmp_file_path, original_file_path)
84
+ # restores original file permissions, see https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp
85
+ os.chmod(original_file_path, original_file_mode)
86
+ finally:
87
+ if tmp_file_path is not None and os.path.exists(tmp_file_path):
88
+ os.remove(tmp_file_path)
89
+
90
+
91
+ def read_yaml(root, file_name):
92
+ """Read data from yaml file and return as dictionary
93
+ Args:
94
+ root: Directory name.
95
+ file_name: File name. Expects to have '.yaml' extension.
96
+
97
+ Returns:
98
+ Data in yaml file as dictionary.
99
+ """
100
+ if not exists(root):
101
+ raise MissingConfigException(
102
+ f"Cannot read '{file_name}'. Parent dir '{root}' does not exist."
103
+ )
104
+
105
+ file_path = os.path.join(root, file_name)
106
+ if not exists(file_path):
107
+ raise MissingConfigException(f"Yaml file '{file_path}' does not exist.")
108
+ with codecs.open(file_path, mode="r", encoding=ENCODING) as yaml_file:
109
+ return yaml.load(yaml_file, Loader=YamlSafeLoader)
110
+
111
+
112
+ class UniqueKeyLoader(YamlSafeLoader):
113
+ def construct_mapping(self, node, deep=False):
114
+ mapping = set()
115
+ for key_node, _ in node.value:
116
+ key = self.construct_object(key_node, deep=deep)
117
+ if key in mapping:
118
+ raise ValueError(f"Duplicate '{key}' key found in YAML.")
119
+ mapping.add(key)
120
+ return super().construct_mapping(node, deep)
121
+
122
+
123
+ def render_and_merge_yaml(root, template_name, context_name):
124
+ """Renders a Jinja2-templated YAML file based on a YAML context file, merge them, and return
125
+ result as a dictionary.
126
+
127
+ Args:
128
+ root: Root directory of the YAML files.
129
+ template_name: Name of the template file.
130
+ context_name: Name of the context file.
131
+
132
+ Returns:
133
+ Data in yaml file as dictionary.
134
+ """
135
+ from jinja2 import FileSystemLoader, StrictUndefined
136
+ from jinja2.sandbox import SandboxedEnvironment
137
+
138
+ template_path = os.path.join(root, template_name)
139
+ context_path = os.path.join(root, context_name)
140
+
141
+ for path in (template_path, context_path):
142
+ if not pathlib.Path(path).is_file():
143
+ raise MissingConfigException(f"Yaml file '{path}' does not exist.")
144
+
145
+ j2_env = SandboxedEnvironment(
146
+ loader=FileSystemLoader(root, encoding=ENCODING),
147
+ undefined=StrictUndefined,
148
+ line_comment_prefix="#",
149
+ )
150
+
151
+ def from_json(input_var):
152
+ with open(input_var, encoding="utf-8") as f:
153
+ return json.load(f)
154
+
155
+ j2_env.filters["from_json"] = from_json
156
+ # Compute final source of context file (e.g. my-profile.yml), applying Jinja filters
157
+ # like from_json as needed to load context information from files, then load into a dict
158
+ context_source = j2_env.get_template(context_name).render({})
159
+ context_dict = yaml.load(context_source, Loader=UniqueKeyLoader) or {}
160
+
161
+ # Substitute parameters from context dict into template
162
+ source = j2_env.get_template(template_name).render(context_dict)
163
+ rendered_template_dict = yaml.load(source, Loader=UniqueKeyLoader)
164
+ return merge_dicts(rendered_template_dict, context_dict)
165
+
166
+
167
+ class safe_edit_yaml:
168
+ def __init__(self, root, file_name, edit_func):
169
+ self._root = root
170
+ self._file_name = file_name
171
+ self._edit_func = edit_func
172
+ self._original = read_yaml(root, file_name)
173
+
174
+ def __enter__(self):
175
+ new_dict = self._edit_func(self._original.copy())
176
+ write_yaml(self._root, self._file_name, new_dict, overwrite=True)
177
+
178
+ def __exit__(self, *args):
179
+ write_yaml(self._root, self._file_name, self._original, overwrite=True)
mlflow/version.py ADDED
@@ -0,0 +1,24 @@
1
+ # Copyright 2018 Databricks, Inc.
2
+ import importlib.metadata
3
+ import re
4
+
5
+ VERSION = "3.1.2.dev0"
6
+
7
+
8
+ def is_release_version():
9
+ return bool(re.match(r"^\d+\.\d+\.\d+$", VERSION))
10
+
11
+
12
+ def _is_package_installed(package_name: str) -> bool:
13
+ try:
14
+ importlib.metadata.version(package_name)
15
+ return True
16
+ except importlib.metadata.PackageNotFoundError:
17
+ return False
18
+
19
+
20
+ # A flag to indicate whether the environment only has the tracing SDK
21
+ # installed, or includes the full MLflow or mlflow-skinny package.
22
+ # This is used to determine whether to import modules that require
23
+ # dependencies that are not included in the tracing SDK.
24
+ IS_TRACING_SDK_ONLY = not any(_is_package_installed(pkg) for pkg in ["mlflow", "mlflow-skinny"])