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,604 @@
1
+ """
2
+ Scoring server for python model format.
3
+ The passed int model is expected to have function:
4
+ predict(pandas.Dataframe) -> pandas.DataFrame
5
+
6
+ Input, expected in text/csv or application/json format,
7
+ is parsed into pandas.DataFrame and passed to the model.
8
+
9
+ Defines four endpoints:
10
+ /ping used for health check
11
+ /health (same as /ping)
12
+ /version used for getting the mlflow version
13
+ /invocations used for scoring
14
+ """
15
+
16
+ import asyncio
17
+ import inspect
18
+ import json
19
+ import logging
20
+ import os
21
+ import shlex
22
+ import sys
23
+ import traceback
24
+ from functools import wraps
25
+ from typing import Any, NamedTuple, Optional
26
+
27
+ from mlflow.environment_variables import (
28
+ _MLFLOW_IS_IN_SERVING_ENVIRONMENT,
29
+ MLFLOW_SCORING_SERVER_REQUEST_TIMEOUT,
30
+ )
31
+
32
+ # NB: We need to be careful what we import form mlflow here. Scoring server is used from within
33
+ # model's conda environment. The version of mlflow doing the serving (outside) and the version of
34
+ # mlflow in the model's conda environment (inside) can differ. We should therefore keep mlflow
35
+ # dependencies to the minimum here.
36
+ # ALl of the mlflow dependencies below need to be backwards compatible.
37
+ from mlflow.exceptions import MlflowException
38
+ from mlflow.pyfunc.model import _log_warning_if_params_not_in_predict_signature
39
+ from mlflow.types import ParamSchema, Schema
40
+ from mlflow.utils import reraise
41
+ from mlflow.utils.file_utils import path_to_local_file_uri
42
+ from mlflow.utils.proto_json_utils import (
43
+ MlflowInvalidInputException,
44
+ NumpyEncoder,
45
+ _get_jsonable_obj,
46
+ dataframe_from_parsed_json,
47
+ parse_tf_serving_input,
48
+ )
49
+ from mlflow.version import VERSION
50
+
51
+ try:
52
+ from mlflow.pyfunc import PyFuncModel, load_model
53
+ except ImportError:
54
+ from mlflow.pyfunc import load_pyfunc as load_model
55
+ from io import StringIO
56
+
57
+ from mlflow.protos.databricks_pb2 import BAD_REQUEST, INVALID_PARAMETER_VALUE
58
+ from mlflow.pyfunc.utils.serving_data_parser import is_unified_llm_input
59
+
60
+ _SERVER_MODEL_PATH = "__pyfunc_model_path__"
61
+ SERVING_MODEL_CONFIG = "SERVING_MODEL_CONFIG"
62
+
63
+ CONTENT_TYPE_CSV = "text/csv"
64
+ CONTENT_TYPE_JSON = "application/json"
65
+
66
+ CONTENT_TYPES = [
67
+ CONTENT_TYPE_CSV,
68
+ CONTENT_TYPE_JSON,
69
+ ]
70
+
71
+ _logger = logging.getLogger(__name__)
72
+
73
+ DF_RECORDS = "dataframe_records"
74
+ DF_SPLIT = "dataframe_split"
75
+ INSTANCES = "instances"
76
+ INPUTS = "inputs"
77
+
78
+ SUPPORTED_FORMATS = {DF_RECORDS, DF_SPLIT, INSTANCES, INPUTS}
79
+ SERVING_PARAMS_KEY = "params"
80
+
81
+ REQUIRED_INPUT_FORMAT = (
82
+ f"The input must be a JSON dictionary with exactly one of the input fields {SUPPORTED_FORMATS}"
83
+ )
84
+ SCORING_PROTOCOL_CHANGE_INFO = (
85
+ "IMPORTANT: The MLflow Model scoring protocol has changed in MLflow version 2.0. If you are"
86
+ " seeing this error, you are likely using an outdated scoring request format. To resolve the"
87
+ " error, either update your request format or adjust your MLflow Model's requirements file to"
88
+ " specify an older version of MLflow (for example, change the 'mlflow' requirement specifier"
89
+ " to 'mlflow==1.30.0'). If you are making a request using the MLflow client"
90
+ " (e.g. via `mlflow.pyfunc.spark_udf()`), upgrade your MLflow client to a version >= 2.0 in"
91
+ " order to use the new request format. For more information about the updated MLflow"
92
+ " Model scoring protocol in MLflow 2.0, see"
93
+ " https://mlflow.org/docs/latest/models.html#deploy-mlflow-models."
94
+ )
95
+
96
+
97
+ def load_model_with_mlflow_config(model_uri):
98
+ extra_kwargs = {}
99
+ if model_config_json := os.environ.get(SERVING_MODEL_CONFIG):
100
+ extra_kwargs["model_config"] = json.loads(model_config_json)
101
+
102
+ return load_model(model_uri, **extra_kwargs)
103
+
104
+
105
+ # Keep this method to maintain compatibility with MLServer
106
+ # https://github.com/SeldonIO/MLServer/blob/caa173ab099a4ec002a7c252cbcc511646c261a6/runtimes/mlflow/mlserver_mlflow/runtime.py#L13C5-L13C31
107
+ def infer_and_parse_json_input(json_input, schema: Schema = None):
108
+ """
109
+ Args:
110
+ json_input: A JSON-formatted string representation of TF serving input or a Pandas
111
+ DataFrame, or a stream containing such a string representation.
112
+ schema: Optional schema specification to be used during parsing.
113
+ """
114
+ if isinstance(json_input, dict):
115
+ decoded_input = json_input
116
+ else:
117
+ try:
118
+ decoded_input = json.loads(json_input)
119
+ except json.decoder.JSONDecodeError as ex:
120
+ raise MlflowException(
121
+ message=(
122
+ "Failed to parse input from JSON. Ensure that input is a valid JSON"
123
+ f" formatted string. Error: '{ex}'. Input: \n{json_input}\n"
124
+ ),
125
+ error_code=BAD_REQUEST,
126
+ )
127
+ if isinstance(decoded_input, dict):
128
+ format_keys = set(decoded_input.keys()).intersection(SUPPORTED_FORMATS)
129
+ if len(format_keys) != 1:
130
+ message = f"Received dictionary with input fields: {list(decoded_input.keys())}"
131
+ raise MlflowException(
132
+ message=f"{REQUIRED_INPUT_FORMAT}. {message}. {SCORING_PROTOCOL_CHANGE_INFO}",
133
+ error_code=BAD_REQUEST,
134
+ )
135
+ input_format = format_keys.pop()
136
+ if input_format in (INSTANCES, INPUTS):
137
+ return parse_tf_serving_input(decoded_input, schema=schema)
138
+
139
+ elif input_format in (DF_SPLIT, DF_RECORDS):
140
+ # NB: skip the dataframe_ prefix
141
+ pandas_orient = input_format[10:]
142
+ return dataframe_from_parsed_json(
143
+ decoded_input[input_format], pandas_orient=pandas_orient, schema=schema
144
+ )
145
+ elif isinstance(decoded_input, list):
146
+ message = "Received a list"
147
+ raise MlflowException(
148
+ message=f"{REQUIRED_INPUT_FORMAT}. {message}. {SCORING_PROTOCOL_CHANGE_INFO}",
149
+ error_code=BAD_REQUEST,
150
+ )
151
+ else:
152
+ message = f"Received unexpected input type '{type(decoded_input)}'"
153
+ raise MlflowException(
154
+ message=f"{REQUIRED_INPUT_FORMAT}. {message}.", error_code=BAD_REQUEST
155
+ )
156
+
157
+
158
+ def _decode_json_input(json_input):
159
+ """
160
+ Args:
161
+ json_input: A JSON-formatted string representation of TF serving input or a Pandas
162
+ DataFrame, or a stream containing such a string representation.
163
+
164
+ Returns:
165
+ A dictionary representation of the JSON input.
166
+ """
167
+ if isinstance(json_input, dict):
168
+ return json_input
169
+
170
+ try:
171
+ decoded_input = json.loads(json_input)
172
+ except json.decoder.JSONDecodeError as ex:
173
+ raise MlflowInvalidInputException(
174
+ "Ensure that input is a valid JSON formatted string. "
175
+ f"Error: '{ex!r}'\nInput: \n{json_input}\n"
176
+ ) from ex
177
+
178
+ if isinstance(decoded_input, dict):
179
+ return decoded_input
180
+ if isinstance(decoded_input, list):
181
+ raise MlflowInvalidInputException(f"{REQUIRED_INPUT_FORMAT}. Received a list.")
182
+
183
+ raise MlflowInvalidInputException(
184
+ f"{REQUIRED_INPUT_FORMAT}. Received unexpected input type '{type(decoded_input)}."
185
+ )
186
+
187
+
188
+ def _split_data_and_params_for_llm_input(json_input, param_schema: Optional[ParamSchema]):
189
+ data = {}
190
+ params = {}
191
+ schema_params = {param.name for param in param_schema.params} if param_schema else {}
192
+
193
+ for key, value in json_input.items():
194
+ # if the model defines a param schema, then we can add
195
+ # it to the params dict. otherwise, add it to the data
196
+ # dict to prevent it from being ignored at inference time
197
+ if key in schema_params:
198
+ params[key] = value
199
+ else:
200
+ data[key] = value
201
+
202
+ return data, params
203
+
204
+
205
+ def _split_data_and_params(json_input):
206
+ input_dict = _decode_json_input(json_input)
207
+ data = {k: v for k, v in input_dict.items() if k in SUPPORTED_FORMATS}
208
+ params = input_dict.pop(SERVING_PARAMS_KEY, None)
209
+ return data, params
210
+
211
+
212
+ def infer_and_parse_data(data, schema: Schema = None):
213
+ """
214
+ Args:
215
+ data: A dictionary representation of TF serving input or a Pandas
216
+ DataFrame, or a stream containing such a string representation.
217
+ schema: Optional schema specification to be used during parsing.
218
+ """
219
+
220
+ format_keys = set(data.keys()).intersection(SUPPORTED_FORMATS)
221
+ if len(format_keys) != 1:
222
+ message = f"Received dictionary with input fields: {list(data.keys())}"
223
+ raise MlflowException(
224
+ message=f"{REQUIRED_INPUT_FORMAT}. {message}. {SCORING_PROTOCOL_CHANGE_INFO}",
225
+ error_code=BAD_REQUEST,
226
+ )
227
+ input_format = format_keys.pop()
228
+ if input_format in (INSTANCES, INPUTS):
229
+ return parse_tf_serving_input(data, schema=schema)
230
+
231
+ if input_format in (DF_SPLIT, DF_RECORDS):
232
+ pandas_orient = input_format[10:] # skip the dataframe_ prefix
233
+ return dataframe_from_parsed_json(
234
+ data[input_format], pandas_orient=pandas_orient, schema=schema
235
+ )
236
+
237
+
238
+ def parse_csv_input(csv_input, schema: Schema = None):
239
+ """
240
+ Args:
241
+ csv_input: A CSV-formatted string representation of a Pandas DataFrame, or a stream
242
+ containing such a string representation.
243
+ schema: Optional schema specification to be used during parsing.
244
+ """
245
+ import pandas as pd
246
+
247
+ try:
248
+ if schema is None:
249
+ return pd.read_csv(csv_input)
250
+ else:
251
+ dtypes = dict(zip(schema.input_names(), schema.pandas_types()))
252
+ return pd.read_csv(csv_input, dtype=dtypes)
253
+ except Exception as e:
254
+ _handle_serving_error(
255
+ error_message=(
256
+ "Failed to parse input as a Pandas DataFrame. Ensure that the input is"
257
+ " a valid CSV-formatted Pandas DataFrame produced using the"
258
+ f" `pandas.DataFrame.to_csv()` method. Error: '{e}'"
259
+ ),
260
+ error_code=BAD_REQUEST,
261
+ )
262
+
263
+
264
+ def unwrapped_predictions_to_json(raw_predictions, output):
265
+ predictions = _get_jsonable_obj(raw_predictions, pandas_orient="records")
266
+ return json.dump(predictions, output, cls=NumpyEncoder)
267
+
268
+
269
+ def predictions_to_json(raw_predictions, output, metadata=None):
270
+ if metadata and "predictions" in metadata:
271
+ raise MlflowException(
272
+ "metadata cannot contain 'predictions' key", error_code=INVALID_PARAMETER_VALUE
273
+ )
274
+ predictions = _get_jsonable_obj(raw_predictions, pandas_orient="records")
275
+ return json.dump({"predictions": predictions, **(metadata or {})}, output, cls=NumpyEncoder)
276
+
277
+
278
+ def _handle_serving_error(error_message, error_code, include_traceback=True):
279
+ """
280
+ Logs information about an exception thrown by model inference code that is currently being
281
+ handled and reraises it with the specified error message. The exception stack trace
282
+ is also included in the reraised error message.
283
+
284
+ Args:
285
+ error_message: A message for the reraised exception.
286
+ error_code: An appropriate error code for the reraised exception. This should be one of
287
+ the codes listed in the `mlflow.protos.databricks_pb2` proto.
288
+ include_traceback: Whether to include the current traceback in the returned error.
289
+ """
290
+ if include_traceback:
291
+ traceback_buf = StringIO()
292
+ traceback.print_exc(file=traceback_buf)
293
+ traceback_str = traceback_buf.getvalue()
294
+ e = MlflowException(message=error_message, error_code=error_code, stack_trace=traceback_str)
295
+ else:
296
+ e = MlflowException(message=error_message, error_code=error_code)
297
+ reraise(MlflowException, e)
298
+
299
+
300
+ class InvocationsResponse(NamedTuple):
301
+ response: str
302
+ status: int
303
+ mimetype: str
304
+
305
+
306
+ def invocations(data, content_type, model, input_schema):
307
+ type_parts = list(map(str.strip, content_type.split(";")))
308
+ mime_type = type_parts[0]
309
+ parameter_value_pairs = type_parts[1:]
310
+ parameter_values = {
311
+ key: value for pair in parameter_value_pairs for key, _, value in [pair.partition("=")]
312
+ }
313
+
314
+ charset = parameter_values.get("charset", "utf-8").lower()
315
+ if charset != "utf-8":
316
+ return InvocationsResponse(
317
+ response="The scoring server only supports UTF-8",
318
+ status=415,
319
+ mimetype="text/plain",
320
+ )
321
+
322
+ unexpected_content_parameters = set(parameter_values.keys()).difference({"charset"})
323
+ if unexpected_content_parameters:
324
+ return InvocationsResponse(
325
+ response=(
326
+ f"Unrecognized content type parameters: "
327
+ f"{', '.join(unexpected_content_parameters)}. "
328
+ f"{SCORING_PROTOCOL_CHANGE_INFO}"
329
+ ),
330
+ status=415,
331
+ mimetype="text/plain",
332
+ )
333
+
334
+ # The traditional JSON request/response format, wraps the data with one of the supported keys
335
+ # like "dataframe_split" and "predictions". For LLM use cases, we also support unwrapped JSON
336
+ # payload, to provide unified prediction interface.
337
+ should_parse_as_unified_llm_input = False
338
+
339
+ if mime_type == CONTENT_TYPE_CSV:
340
+ # Convert from CSV to pandas
341
+ if isinstance(data, bytes):
342
+ data = data.decode("utf-8")
343
+ csv_input = StringIO(data)
344
+ data = parse_csv_input(csv_input=csv_input, schema=input_schema)
345
+ params = None
346
+ elif mime_type == CONTENT_TYPE_JSON:
347
+ parsed_json_input = _parse_json_data(data, model.metadata, input_schema)
348
+ data = parsed_json_input.data
349
+ params = parsed_json_input.params
350
+ should_parse_as_unified_llm_input = parsed_json_input.is_unified_llm_input
351
+ else:
352
+ return InvocationsResponse(
353
+ response=(
354
+ "This predictor only supports the following content types:"
355
+ f" Types: {CONTENT_TYPES}."
356
+ f" Got '{content_type}'."
357
+ ),
358
+ status=415,
359
+ mimetype="text/plain",
360
+ )
361
+
362
+ # Do the prediction
363
+ # NB: utils._validate_serving_input mimic the scoring process here to validate input_example
364
+ # work for serving, so any changes here should be reflected there as well
365
+ try:
366
+ if "params" in inspect.signature(model.predict).parameters:
367
+ raw_predictions = model.predict(data, params=params)
368
+ else:
369
+ _log_warning_if_params_not_in_predict_signature(_logger, params)
370
+ raw_predictions = model.predict(data)
371
+ except MlflowException as e:
372
+ if "Failed to enforce schema" in e.message:
373
+ _logger.warning(
374
+ "If using `instances` as input key, we internally convert "
375
+ "the data type from `records` (List[Dict]) type to "
376
+ "`list` (Dict[str, List]) type if the data is a pandas "
377
+ "dataframe representation. This might cause schema changes. "
378
+ "Please use `inputs` to avoid this conversion.\n"
379
+ )
380
+ e.message = f"Failed to predict data '{data}'. \nError: {e.message}"
381
+ raise e
382
+ except Exception:
383
+ raise MlflowException(
384
+ message=(
385
+ "Encountered an unexpected error while evaluating the model. Verify"
386
+ " that the serialized input Dataframe is compatible with the model for"
387
+ " inference."
388
+ ),
389
+ error_code=BAD_REQUEST,
390
+ stack_trace=traceback.format_exc(),
391
+ )
392
+ result = StringIO()
393
+
394
+ # if the data was formatted using the unified LLM format,
395
+ # then return the data without the "predictions" key
396
+ if should_parse_as_unified_llm_input:
397
+ unwrapped_predictions_to_json(raw_predictions, result)
398
+ else:
399
+ predictions_to_json(raw_predictions, result)
400
+
401
+ return InvocationsResponse(response=result.getvalue(), status=200, mimetype="application/json")
402
+
403
+
404
+ class ParsedJsonInput(NamedTuple):
405
+ data: Any
406
+ params: Optional[dict[str, Any]]
407
+ is_unified_llm_input: bool
408
+
409
+
410
+ def _parse_json_data(data, metadata, input_schema):
411
+ json_input = _decode_json_input(data)
412
+ _is_unified_llm_input = is_unified_llm_input(json_input)
413
+ # no data parsing for unified LLM input format
414
+ if _is_unified_llm_input:
415
+ # Unified LLM input format
416
+ if hasattr(metadata, "get_params_schema"):
417
+ params_schema = metadata.get_params_schema()
418
+ else:
419
+ params_schema = None
420
+ data, params = _split_data_and_params_for_llm_input(json_input, params_schema)
421
+ else:
422
+ # Traditional json input format
423
+ data, params = _split_data_and_params(data)
424
+ # data only needs to be parsed if the model signature is not from type hint
425
+ # default to True for backwards compatibility
426
+ should_parse_data = (
427
+ not metadata._is_signature_from_type_hint()
428
+ if hasattr(metadata, "_is_signature_from_type_hint")
429
+ else True
430
+ )
431
+ if should_parse_data:
432
+ data = infer_and_parse_data(data, input_schema)
433
+ else:
434
+ if INPUTS not in data:
435
+ raise MlflowException.invalid_parameter_value(
436
+ "Request payload must be a dictionary with 'inputs' key when "
437
+ f"the model contains a valid type hint. Found keys in payload: {data.keys()}."
438
+ )
439
+ data = data[INPUTS]
440
+ return ParsedJsonInput(data, params, _is_unified_llm_input)
441
+
442
+
443
+ def _async_catch_mlflow_exception(func):
444
+ from fastapi.responses import Response
445
+
446
+ @wraps(func)
447
+ async def wrapper(*args, **kwargs):
448
+ try:
449
+ return await func(*args, **kwargs)
450
+ except MlflowException as e:
451
+ return Response(
452
+ content=e.serialize_as_json(),
453
+ status_code=e.get_http_status_code(),
454
+ media_type="application/json",
455
+ )
456
+
457
+ return wrapper
458
+
459
+
460
+ def init(model: PyFuncModel):
461
+ """
462
+ Initialize the server. Loads pyfunc model from the path.
463
+ """
464
+ from fastapi import FastAPI, Request
465
+ from fastapi.responses import Response
466
+
467
+ app = FastAPI()
468
+ input_schema = model.metadata.get_input_schema()
469
+ # set the environment variable to indicate that we are in a serving environment
470
+ os.environ[_MLFLOW_IS_IN_SERVING_ENVIRONMENT.name] = "true"
471
+ timeout = MLFLOW_SCORING_SERVER_REQUEST_TIMEOUT.get()
472
+
473
+ @app.middleware("http")
474
+ async def timeout_middleware(request: Request, call_next):
475
+ try:
476
+ return await asyncio.wait_for(call_next(request), timeout=timeout)
477
+ except (asyncio.TimeoutError, TimeoutError):
478
+ return Response(
479
+ content="Request processing time exceeded limit",
480
+ status_code=504,
481
+ media_type="application/json",
482
+ )
483
+
484
+ @app.route("/ping", methods=["GET"])
485
+ @app.route("/health", methods=["GET"])
486
+ async def ping(request: Request):
487
+ """
488
+ Determine if the container is working and healthy.
489
+ We declare it healthy if we can load the model successfully.
490
+ """
491
+ health = model is not None
492
+ status = 200 if health else 404
493
+ return Response(content="\n", status_code=status, media_type="application/json")
494
+
495
+ @app.route("/version", methods=["GET"])
496
+ async def version(request: Request):
497
+ """
498
+ Returns the current mlflow version.
499
+ """
500
+ return Response(content=VERSION, status_code=200, media_type="application/json")
501
+
502
+ @app.route("/invocations", methods=["POST"])
503
+ @_async_catch_mlflow_exception
504
+ async def transformation(request: Request):
505
+ """
506
+ Do an inference on a single batch of data. In this sample server,
507
+ we take data as CSV or json, convert it to a Pandas DataFrame or Numpy,
508
+ generate predictions and convert them back to json.
509
+ """
510
+
511
+ data = await request.body()
512
+ content_type = request.headers.get("content-type")
513
+ # TODO: convert "invocations" to an async method to make internal logic fully non-blocking.
514
+ result = await asyncio.to_thread(invocations, data, content_type, model, input_schema)
515
+
516
+ return Response(
517
+ content=result.response, status_code=result.status, media_type=result.mimetype
518
+ )
519
+
520
+ return app
521
+
522
+
523
+ def _predict(model_uri, input_path, output_path, content_type):
524
+ from mlflow.pyfunc.utils.environment import _simulate_serving_environment
525
+
526
+ with _simulate_serving_environment():
527
+ pyfunc_model = load_model(model_uri)
528
+
529
+ should_parse_as_unified_llm_input = False
530
+ if content_type == "json":
531
+ if input_path is None:
532
+ input_str = sys.stdin.read()
533
+ else:
534
+ with open(input_path) as f:
535
+ input_str = f.read()
536
+ parsed_json_input = _parse_json_data(
537
+ data=input_str,
538
+ metadata=pyfunc_model.metadata,
539
+ input_schema=pyfunc_model.metadata.get_input_schema(),
540
+ )
541
+ df = parsed_json_input.data
542
+ params = parsed_json_input.params
543
+ should_parse_as_unified_llm_input = parsed_json_input.is_unified_llm_input
544
+ elif content_type == "csv":
545
+ df = (
546
+ parse_csv_input(input_path)
547
+ if input_path is not None
548
+ else parse_csv_input(sys.stdin)
549
+ )
550
+ params = None
551
+ else:
552
+ raise Exception(f"Unknown content type '{content_type}'")
553
+
554
+ if "params" in inspect.signature(pyfunc_model.predict).parameters:
555
+ raw_predictions = pyfunc_model.predict(df, params=params)
556
+ else:
557
+ _log_warning_if_params_not_in_predict_signature(_logger, params)
558
+ raw_predictions = pyfunc_model.predict(df)
559
+
560
+ parse_output_func = (
561
+ unwrapped_predictions_to_json
562
+ if should_parse_as_unified_llm_input
563
+ else predictions_to_json
564
+ )
565
+
566
+ if output_path is None:
567
+ parse_output_func(raw_predictions, sys.stdout)
568
+ else:
569
+ with open(output_path, "w") as fout:
570
+ parse_output_func(raw_predictions, fout)
571
+
572
+
573
+ def _serve(model_uri, port, host):
574
+ pyfunc_model = load_model(model_uri)
575
+ init(pyfunc_model).run(port=port, host=host)
576
+
577
+
578
+ def get_cmd(
579
+ model_uri: str,
580
+ port: Optional[int] = None,
581
+ host: Optional[int] = None,
582
+ timeout: Optional[int] = None,
583
+ nworkers: Optional[int] = None,
584
+ ) -> tuple[str, dict[str, str]]:
585
+ local_uri = path_to_local_file_uri(model_uri)
586
+ timeout = timeout or MLFLOW_SCORING_SERVER_REQUEST_TIMEOUT.get()
587
+
588
+ args = []
589
+ if host:
590
+ args.append(f"--host {shlex.quote(host)}")
591
+
592
+ if port:
593
+ args.append(f"--port {port}")
594
+
595
+ if nworkers:
596
+ args.append(f"--workers {nworkers}")
597
+
598
+ command = f"uvicorn {' '.join(args)} mlflow.pyfunc.scoring_server.app:app"
599
+
600
+ command_env = os.environ.copy()
601
+ command_env[_SERVER_MODEL_PATH] = local_uri
602
+ command_env[MLFLOW_SCORING_SERVER_REQUEST_TIMEOUT.name] = str(timeout)
603
+
604
+ return command, command_env
@@ -0,0 +1,7 @@
1
+ import os
2
+
3
+ from mlflow.pyfunc import scoring_server
4
+
5
+ app = scoring_server.init(
6
+ scoring_server.load_model_with_mlflow_config(os.environ[scoring_server._SERVER_MODEL_PATH])
7
+ )