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,774 @@
1
+ import base64
2
+ import json
3
+ import logging
4
+ from functools import lru_cache
5
+ from typing import Any, Optional, Union
6
+
7
+ from google.protobuf.json_format import MessageToDict, ParseDict
8
+ from google.protobuf.struct_pb2 import Value
9
+ from opentelemetry.sdk.resources import Resource as _OTelResource
10
+ from opentelemetry.sdk.trace import Event as OTelEvent
11
+ from opentelemetry.sdk.trace import ReadableSpan as OTelReadableSpan
12
+ from opentelemetry.trace import NonRecordingSpan, SpanContext, TraceFlags
13
+ from opentelemetry.trace import Span as OTelSpan
14
+
15
+ import mlflow
16
+ from mlflow.entities.span_event import SpanEvent
17
+ from mlflow.entities.span_status import SpanStatus, SpanStatusCode
18
+ from mlflow.exceptions import MlflowException
19
+ from mlflow.protos.databricks_pb2 import INVALID_PARAMETER_VALUE
20
+ from mlflow.protos.databricks_trace_server_pb2 import Span as ProtoSpan
21
+ from mlflow.tracing.constant import SpanAttributeKey
22
+ from mlflow.tracing.utils import (
23
+ TraceJSONEncoder,
24
+ build_otel_context,
25
+ decode_id,
26
+ encode_span_id,
27
+ encode_trace_id,
28
+ )
29
+ from mlflow.tracing.utils.processor import apply_span_processors
30
+
31
+ _logger = logging.getLogger(__name__)
32
+
33
+
34
+ # Not using enum as we want to allow custom span type string.
35
+ class SpanType:
36
+ """
37
+ Predefined set of span types.
38
+ """
39
+
40
+ LLM = "LLM"
41
+ CHAIN = "CHAIN"
42
+ AGENT = "AGENT"
43
+ TOOL = "TOOL"
44
+ CHAT_MODEL = "CHAT_MODEL"
45
+ RETRIEVER = "RETRIEVER"
46
+ PARSER = "PARSER"
47
+ EMBEDDING = "EMBEDDING"
48
+ RERANKER = "RERANKER"
49
+ UNKNOWN = "UNKNOWN"
50
+
51
+
52
+ def create_mlflow_span(
53
+ otel_span: Any, trace_id: str, span_type: Optional[str] = None
54
+ ) -> Union["Span", "LiveSpan", "NoOpSpan"]:
55
+ """
56
+ Factory function to create a span object.
57
+
58
+ When creating a MLflow span object from the OpenTelemetry span, the factory function
59
+ should always be used to ensure the correct span object is created.
60
+ """
61
+ if not otel_span or isinstance(otel_span, NonRecordingSpan):
62
+ return NoOpSpan()
63
+
64
+ if isinstance(otel_span, OTelSpan):
65
+ return LiveSpan(otel_span, trace_id, span_type)
66
+
67
+ if isinstance(otel_span, OTelReadableSpan):
68
+ return Span(otel_span)
69
+
70
+ raise MlflowException(
71
+ "The `otel_span` argument must be an instance of one of valid "
72
+ f"OpenTelemetry span classes, but got {type(otel_span)}.",
73
+ INVALID_PARAMETER_VALUE,
74
+ )
75
+
76
+
77
+ class Span:
78
+ """
79
+ A span object. A span represents a unit of work or operation and is the building
80
+ block of Traces.
81
+
82
+ This Span class represents immutable span data that is already finished and persisted.
83
+ The "live" span that is being created and updated during the application runtime is
84
+ represented by the :py:class:`LiveSpan <mlflow.entities.LiveSpan>` subclass.
85
+ """
86
+
87
+ def __init__(self, otel_span: OTelReadableSpan):
88
+ if not isinstance(otel_span, OTelReadableSpan):
89
+ raise MlflowException(
90
+ "The `otel_span` argument for the Span class must be an instance of ReadableSpan, "
91
+ f"but got {type(otel_span)}.",
92
+ INVALID_PARAMETER_VALUE,
93
+ )
94
+
95
+ self._span = otel_span
96
+ # Since the span is immutable, we can cache the attributes to avoid the redundant
97
+ # deserialization of the attribute values.
98
+ self._attributes = _CachedSpanAttributesRegistry(otel_span)
99
+
100
+ @property
101
+ @lru_cache(maxsize=1)
102
+ def trace_id(self) -> str:
103
+ """The trace ID of the span, a unique identifier for the trace it belongs to."""
104
+ return self.get_attribute(SpanAttributeKey.REQUEST_ID)
105
+
106
+ @property
107
+ def request_id(self) -> str:
108
+ """Deprecated. Use `trace_id` instead."""
109
+ return self.trace_id
110
+
111
+ @property
112
+ def span_id(self) -> str:
113
+ """The ID of the span. This is only unique within a trace."""
114
+ return encode_span_id(self._span.context.span_id)
115
+
116
+ @property
117
+ def name(self) -> str:
118
+ """The name of the span."""
119
+ return self._span.name
120
+
121
+ @property
122
+ def start_time_ns(self) -> int:
123
+ """The start time of the span in nanosecond."""
124
+ return self._span._start_time
125
+
126
+ @property
127
+ def end_time_ns(self) -> Optional[int]:
128
+ """The end time of the span in nanosecond."""
129
+ return self._span._end_time
130
+
131
+ @property
132
+ def parent_id(self) -> Optional[str]:
133
+ """The span ID of the parent span."""
134
+ if self._span.parent is None:
135
+ return None
136
+ return encode_span_id(self._span.parent.span_id)
137
+
138
+ @property
139
+ def status(self) -> SpanStatus:
140
+ """The status of the span."""
141
+ return SpanStatus.from_otel_status(self._span.status)
142
+
143
+ @property
144
+ def inputs(self) -> Any:
145
+ """The input values of the span."""
146
+ return self.get_attribute(SpanAttributeKey.INPUTS)
147
+
148
+ @property
149
+ def outputs(self) -> Any:
150
+ """The output values of the span."""
151
+ return self.get_attribute(SpanAttributeKey.OUTPUTS)
152
+
153
+ @property
154
+ def span_type(self) -> str:
155
+ """The type of the span."""
156
+ return self.get_attribute(SpanAttributeKey.SPAN_TYPE)
157
+
158
+ @property
159
+ def _trace_id(self) -> str:
160
+ """
161
+ The OpenTelemetry trace ID of the span. Note that this should not be exposed to
162
+ the user, instead, use trace_id property as an unique identifier for a trace.
163
+ """
164
+ return encode_trace_id(self._span.context.trace_id)
165
+
166
+ @property
167
+ def attributes(self) -> dict[str, Any]:
168
+ """
169
+ Get all attributes of the span.
170
+
171
+ Returns:
172
+ A dictionary of all attributes of the span.
173
+ """
174
+ return self._attributes.get_all()
175
+
176
+ @property
177
+ def events(self) -> list[SpanEvent]:
178
+ """
179
+ Get all events of the span.
180
+
181
+ Returns:
182
+ A list of all events of the span.
183
+ """
184
+ return [
185
+ SpanEvent(
186
+ name=event.name,
187
+ timestamp=event.timestamp,
188
+ # Convert from OpenTelemetry's BoundedAttributes class to a simple dict
189
+ # to avoid the serialization issue due to having a lock object.
190
+ attributes=dict(event.attributes),
191
+ )
192
+ for event in self._span.events
193
+ ]
194
+
195
+ def __repr__(self):
196
+ return (
197
+ f"{type(self).__name__}(name={self.name!r}, trace_id={self.trace_id!r}, "
198
+ f"span_id={self.span_id!r}, parent_id={self.parent_id!r})"
199
+ )
200
+
201
+ def get_attribute(self, key: str) -> Optional[Any]:
202
+ """
203
+ Get a single attribute value from the span.
204
+
205
+ Args:
206
+ key: The key of the attribute to get.
207
+
208
+ Returns:
209
+ The value of the attribute if it exists, otherwise None.
210
+ """
211
+ return self._attributes.get(key)
212
+
213
+ def to_dict(self) -> dict[str, Any]:
214
+ d = MessageToDict(
215
+ self.to_proto(),
216
+ preserving_proto_field_name=True,
217
+ )
218
+ # Casting fields types as MessageToDict convert everything to string
219
+ d["start_time_unix_nano"] = self.start_time_ns
220
+ d["end_time_unix_nano"] = self.end_time_ns
221
+ for i, event in enumerate(d.get("events", [])):
222
+ event["time_unix_nano"] = self.events[i].timestamp
223
+ event["attributes"] = self.events[i].attributes
224
+ return d
225
+
226
+ @classmethod
227
+ def from_dict(cls, data: dict[str, Any]) -> "Span":
228
+ """Create a Span object from the given dictionary."""
229
+ try:
230
+ # Try to deserialize the span using the v3 schema
231
+ request_id = data.get("attributes", {}).get(SpanAttributeKey.REQUEST_ID)
232
+ if not request_id:
233
+ raise MlflowException(
234
+ f"The {SpanAttributeKey.REQUEST_ID} attribute is empty or missing.",
235
+ INVALID_PARAMETER_VALUE,
236
+ )
237
+
238
+ if Span._is_span_v2_schema(data):
239
+ return cls.from_dict_v2(data)
240
+
241
+ trace_id = _decode_id_from_byte(data["trace_id"])
242
+ span_id = _decode_id_from_byte(data["span_id"])
243
+ # Parent ID always exists in proto (empty string) even if the span is a root span.
244
+ parent_id = (
245
+ _decode_id_from_byte(data["parent_span_id"]) if data["parent_span_id"] else None
246
+ )
247
+
248
+ end_time_ns = data.get("end_time_unix_nano")
249
+ end_time_ns = int(end_time_ns) if end_time_ns else None
250
+
251
+ otel_span = OTelReadableSpan(
252
+ name=data["name"],
253
+ context=build_otel_context(trace_id, span_id),
254
+ parent=build_otel_context(trace_id, parent_id) if parent_id else None,
255
+ start_time=int(data["start_time_unix_nano"]),
256
+ end_time=end_time_ns,
257
+ attributes=data["attributes"],
258
+ status=SpanStatus(
259
+ status_code=SpanStatusCode.from_proto_status_code(data["status"]["code"]),
260
+ description=data["status"].get("message"),
261
+ ).to_otel_status(),
262
+ # Setting an empty resource explicitly. Otherwise OTel create a new Resource by
263
+ # Resource.create(), which introduces a significant overhead in some environments.
264
+ # https://github.com/mlflow/mlflow/issues/15625
265
+ resource=_OTelResource.get_empty(),
266
+ events=[
267
+ OTelEvent(
268
+ name=event["name"],
269
+ timestamp=int(event["time_unix_nano"]),
270
+ attributes=event.get("attributes", {}),
271
+ )
272
+ for event in data.get("events", [])
273
+ ],
274
+ )
275
+ return cls(otel_span)
276
+ except Exception as e:
277
+ raise MlflowException(
278
+ "Failed to create a Span object from the given dictionary",
279
+ INVALID_PARAMETER_VALUE,
280
+ ) from e
281
+
282
+ @staticmethod
283
+ def _is_span_v2_schema(data: dict[str, Any]) -> bool:
284
+ return "context" in data
285
+
286
+ @classmethod
287
+ def from_dict_v2(cls, data: dict[str, Any]) -> "Span":
288
+ """Create a Span object from the given dictionary in v2 schema."""
289
+ trace_id = decode_id(data["context"]["trace_id"])
290
+ span_id = decode_id(data["context"]["span_id"])
291
+ parent_id = decode_id(data["parent_id"]) if data["parent_id"] else None
292
+
293
+ otel_span = OTelReadableSpan(
294
+ name=data["name"],
295
+ context=build_otel_context(trace_id, span_id),
296
+ parent=build_otel_context(trace_id, parent_id) if parent_id else None,
297
+ start_time=data["start_time"],
298
+ end_time=data["end_time"],
299
+ attributes=data["attributes"],
300
+ status=SpanStatus(data["status_code"], data["status_message"]).to_otel_status(),
301
+ # Setting an empty resource explicitly. Otherwise OTel create a new Resource by
302
+ # Resource.create(), which introduces a significant overhead in some environments.
303
+ # https://github.com/mlflow/mlflow/issues/15625
304
+ resource=_OTelResource.get_empty(),
305
+ events=[
306
+ OTelEvent(
307
+ name=event["name"],
308
+ timestamp=event["timestamp"],
309
+ attributes=event["attributes"],
310
+ )
311
+ for event in data["events"]
312
+ ],
313
+ )
314
+ return cls(otel_span)
315
+
316
+ def to_proto(self):
317
+ """Convert into OTLP compatible proto object to sent to the Databricks Trace Server."""
318
+ otel_status = self._span.status
319
+ status = ProtoSpan.Status(
320
+ code=otel_status.status_code.value,
321
+ message=otel_status.description,
322
+ )
323
+ parent = _encode_span_id_to_byte(self._span.parent.span_id) if self._span.parent else b""
324
+
325
+ # NB: This is a workaround that some DBX internal code pass float timestamp
326
+ start_time_unix_nano = int(self._span.start_time) if self._span.start_time else None
327
+ end_time_unix_nano = int(self._span.end_time) if self._span.end_time else None
328
+
329
+ return ProtoSpan(
330
+ trace_id=_encode_trace_id_to_byte(self._span.context.trace_id),
331
+ span_id=_encode_span_id_to_byte(self._span.context.span_id),
332
+ trace_state=self._span.context.trace_state or "",
333
+ parent_span_id=parent,
334
+ name=self.name,
335
+ start_time_unix_nano=start_time_unix_nano,
336
+ end_time_unix_nano=end_time_unix_nano,
337
+ events=[event.to_proto() for event in self.events],
338
+ status=status,
339
+ attributes={k: ParseDict(v, Value()) for k, v in self._span.attributes.items()},
340
+ )
341
+
342
+
343
+ def _encode_span_id_to_byte(span_id: Optional[int]) -> bytes:
344
+ # https://github.com/open-telemetry/opentelemetry-python/blob/e01fa0c77a7be0af77d008a888c2b6a707b05c3d/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py#L131
345
+ return span_id.to_bytes(length=8, byteorder="big", signed=False)
346
+
347
+
348
+ def _encode_trace_id_to_byte(trace_id: int) -> bytes:
349
+ # https://github.com/open-telemetry/opentelemetry-python/blob/e01fa0c77a7be0af77d008a888c2b6a707b05c3d/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py#L135
350
+ return trace_id.to_bytes(length=16, byteorder="big", signed=False)
351
+
352
+
353
+ def _decode_id_from_byte(trace_or_span_id_b64: str) -> int:
354
+ # Decoding the base64 encoded trace or span ID to bytes and then converting it to int.
355
+ bytes = base64.b64decode(trace_or_span_id_b64)
356
+ return int.from_bytes(bytes, byteorder="big", signed=False)
357
+
358
+
359
+ class LiveSpan(Span):
360
+ """
361
+ A "live" version of the :py:class:`Span <mlflow.entities.Span>` class.
362
+
363
+ The live spans are those being created and updated during the application runtime.
364
+ When users start a new span using the tracing APIs within their code, this live span
365
+ object is returned to get and set the span attributes, status, events, and etc.
366
+ """
367
+
368
+ def __init__(
369
+ self,
370
+ otel_span: OTelSpan,
371
+ trace_id: str,
372
+ span_type: str = SpanType.UNKNOWN,
373
+ ):
374
+ """
375
+ The `otel_span` argument takes an instance of OpenTelemetry Span class, which is
376
+ indeed a subclass of ReadableSpan. Thanks to this, the getter methods of the Span
377
+ class can be reused without any modification.
378
+
379
+ Note that the constructor doesn't call the super().__init__ method, because the Span
380
+ initialization logic is a bit different from the immutable span.
381
+ """
382
+ if not isinstance(otel_span, OTelReadableSpan):
383
+ raise MlflowException(
384
+ "The `otel_span` argument for the LiveSpan class must be an instance of "
385
+ f"trace.Span, but got {type(otel_span)}.",
386
+ INVALID_PARAMETER_VALUE,
387
+ )
388
+
389
+ self._span = otel_span
390
+ self._attributes = _SpanAttributesRegistry(otel_span)
391
+ self._attributes.set(SpanAttributeKey.REQUEST_ID, trace_id)
392
+ self._attributes.set(SpanAttributeKey.SPAN_TYPE, span_type)
393
+
394
+ def set_span_type(self, span_type: str):
395
+ """Set the type of the span."""
396
+ self.set_attribute(SpanAttributeKey.SPAN_TYPE, span_type)
397
+
398
+ def set_inputs(self, inputs: Any):
399
+ """Set the input values to the span."""
400
+ self.set_attribute(SpanAttributeKey.INPUTS, inputs)
401
+
402
+ def set_outputs(self, outputs: Any):
403
+ """Set the output values to the span."""
404
+ self.set_attribute(SpanAttributeKey.OUTPUTS, outputs)
405
+
406
+ def set_attributes(self, attributes: dict[str, Any]):
407
+ """
408
+ Set the attributes to the span. The attributes must be a dictionary of key-value pairs.
409
+ This method is additive, i.e. it will add new attributes to the existing ones. If an
410
+ attribute with the same key already exists, it will be overwritten.
411
+ """
412
+ if not isinstance(attributes, dict):
413
+ _logger.warning(
414
+ f"Attributes must be a dictionary, but got {type(attributes)}. Skipping."
415
+ )
416
+ return
417
+
418
+ for key, value in attributes.items():
419
+ self.set_attribute(key, value)
420
+
421
+ def set_attribute(self, key: str, value: Any):
422
+ """Set a single attribute to the span."""
423
+ self._attributes.set(key, value)
424
+
425
+ def set_status(self, status: Union[SpanStatusCode, str]):
426
+ """
427
+ Set the status of the span.
428
+
429
+ Args:
430
+ status: The status of the span. This can be a
431
+ :py:class:`SpanStatus <mlflow.entities.SpanStatus>` object or a string representing
432
+ of the status code defined in
433
+ :py:class:`SpanStatusCode <mlflow.entities.SpanStatusCode>`
434
+ e.g. ``"OK"``, ``"ERROR"``.
435
+ """
436
+ if isinstance(status, str):
437
+ status = SpanStatus(status)
438
+
439
+ # NB: We need to set the OpenTelemetry native StatusCode, because span's set_status
440
+ # method only accepts a StatusCode enum in their definition.
441
+ # https://github.com/open-telemetry/opentelemetry-python/blob/8ed71b15fb8fc9534529da8ce4a21e686248a8f3/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py#L949
442
+ # Working around this is possible, but requires some hack to handle automatic status
443
+ # propagation mechanism, so here we just use the native object that meets our
444
+ # current requirements at least. Nevertheless, declaring the new class extending
445
+ # the OpenTelemetry Status class so users code doesn't have to import the OTel's
446
+ # StatusCode object, which makes future migration easier.
447
+ self._span.set_status(status.to_otel_status())
448
+
449
+ def add_event(self, event: SpanEvent):
450
+ """
451
+ Add an event to the span.
452
+
453
+ Args:
454
+ event: The event to add to the span. This should be a
455
+ :py:class:`SpanEvent <mlflow.entities.SpanEvent>` object.
456
+ """
457
+ self._span.add_event(event.name, event.attributes, event.timestamp)
458
+
459
+ def record_exception(self, exception: Union[str, Exception]):
460
+ """
461
+ Record an exception on the span, adding an exception event and setting span status to ERROR.
462
+
463
+ Args:
464
+ exception: The exception to record. Can be an Exception instance or a string
465
+ describing the exception.
466
+ """
467
+ if isinstance(exception, Exception):
468
+ self.add_event(SpanEvent.from_exception(exception))
469
+ elif isinstance(exception, str):
470
+ self.add_event(SpanEvent.from_exception(Exception(exception)))
471
+ else:
472
+ raise MlflowException(
473
+ "The `exception` parameter must be an Exception instance or a string.",
474
+ INVALID_PARAMETER_VALUE,
475
+ )
476
+
477
+ self.set_status(SpanStatusCode.ERROR)
478
+
479
+ def end(
480
+ self,
481
+ outputs: Optional[Any] = None,
482
+ attributes: Optional[dict[str, Any]] = None,
483
+ status: Optional[Union[SpanStatus, str]] = None,
484
+ end_time_ns: Optional[int] = None,
485
+ ):
486
+ """
487
+ End the span.
488
+
489
+ outputs: Outputs to set on the span.
490
+ attributes: A dictionary of attributes to set on the span. If the span already has
491
+ attributes, the new attributes will be merged with the existing ones. If the same
492
+ key already exists, the new value will overwrite the old one.
493
+ status: The status of the span. This can be a
494
+ :py:class:`SpanStatus <mlflow.entities.SpanStatus>` object or a string
495
+ representing the status code defined in
496
+ :py:class:`SpanStatusCode <mlflow.entities.SpanStatusCode>`
497
+ e.g. ``"OK"``, ``"ERROR"``. The default status is OK.
498
+ end_time_ns: The end time of the span in nano seconds since the UNIX epoch.
499
+ If not provided, the current time will be used.
500
+
501
+ :meta private:
502
+ """
503
+ try:
504
+ self.set_attributes(attributes or {})
505
+ if outputs is not None:
506
+ self.set_outputs(outputs)
507
+ if status is not None:
508
+ self.set_status(status)
509
+
510
+ # NB: In OpenTelemetry, status code remains UNSET if not explicitly set
511
+ # by the user. However, there is not way to set the status when using
512
+ # @mlflow.trace decorator. Therefore, we just automatically set the status
513
+ # to OK if it is not ERROR.
514
+ if self.status.status_code != SpanStatusCode.ERROR:
515
+ self.set_status(SpanStatus(SpanStatusCode.OK))
516
+
517
+ # Apply span processors
518
+ apply_span_processors(self)
519
+
520
+ self._span.end(end_time=end_time_ns)
521
+
522
+ except Exception as e:
523
+ _logger.warning(
524
+ f"Failed to end span {self.span_id}: {e}. "
525
+ "For full traceback, set logging level to debug.",
526
+ exc_info=_logger.isEnabledFor(logging.DEBUG),
527
+ )
528
+
529
+ def from_dict(cls, data: dict[str, Any]) -> "Span":
530
+ raise NotImplementedError("The `from_dict` method is not supported for the LiveSpan class.")
531
+
532
+ def to_immutable_span(self) -> "Span":
533
+ """
534
+ Downcast the live span object to the immutable span.
535
+
536
+ :meta private:
537
+ """
538
+ # All state of the live span is already persisted in the OpenTelemetry span object.
539
+ return Span(self._span)
540
+
541
+ @classmethod
542
+ def from_immutable_span(
543
+ cls,
544
+ span: Span,
545
+ parent_span_id: Optional[str] = None,
546
+ trace_id: Optional[str] = None,
547
+ experiment_id: Optional[str] = None,
548
+ otel_trace_id: Optional[str] = None,
549
+ end_trace: bool = True,
550
+ ) -> "LiveSpan":
551
+ """
552
+ Create a new LiveSpan object from the given immutable span by
553
+ cloning the underlying OpenTelemetry span within current context.
554
+
555
+ This is particularly useful when we merging a remote trace into the current trace.
556
+ We cannot merge the remote trace directly, because it is already stored as an immutable
557
+ span, meaning that we cannot update metadata like trace ID, parent span ID,
558
+ which are necessary for merging the trace.
559
+
560
+ Args:
561
+ span: The immutable span object to clone.
562
+ parent_span_id: The parent span ID of the new span.
563
+ If it is None, the span will be created as a root span.
564
+ trace_id: The trace ID to be set on the new span. Specify this if you want to
565
+ create the new span with a particular trace ID.
566
+ experiment_id: The experiment ID to be set on the new span. If not specified, the
567
+ experiment ID will be set to the current experiment ID.
568
+ otel_trace_id: The OpenTelemetry trace ID of the new span in hex encoded format.
569
+ If not specified, the newly generated trace ID will be used.
570
+ end_trace: Whether to end the trace after cloning the span. Default is True.
571
+
572
+ Returns:
573
+ The new LiveSpan object with the same state as the original span.
574
+
575
+ :meta private:
576
+ """
577
+ from mlflow.tracing.trace_manager import InMemoryTraceManager
578
+
579
+ trace_manager = InMemoryTraceManager.get_instance()
580
+ parent_span = trace_manager.get_span_from_id(trace_id, parent_span_id)
581
+
582
+ # Create a new span with the same name, parent, and start time
583
+ otel_span = mlflow.tracing.provider.start_detached_span(
584
+ name=span.name,
585
+ parent=parent_span._span if parent_span else None,
586
+ start_time_ns=span.start_time_ns,
587
+ experiment_id=experiment_id,
588
+ )
589
+ # The latter one from attributes is the newly generated trace ID by the span processor.
590
+ trace_id = trace_id or json.loads(otel_span.attributes.get(SpanAttributeKey.REQUEST_ID))
591
+ clone_span = LiveSpan(otel_span, trace_id, span.span_type)
592
+
593
+ # Copy all the attributes, inputs, outputs, and events from the original span
594
+ clone_span.set_status(span.status)
595
+ clone_span.set_attributes(
596
+ {k: v for k, v in span.attributes.items() if k != SpanAttributeKey.REQUEST_ID}
597
+ )
598
+ if span.inputs:
599
+ clone_span.set_inputs(span.inputs)
600
+ if span.outputs:
601
+ clone_span.set_outputs(span.outputs)
602
+ for event in span.events:
603
+ clone_span.add_event(event)
604
+
605
+ # Update trace ID and span ID
606
+ context = span._span.get_span_context()
607
+ clone_span._span._context = SpanContext(
608
+ # Override otel_trace_id if provided, otherwise use the new trace ID
609
+ trace_id=decode_id(otel_trace_id) if otel_trace_id else otel_span.context.trace_id,
610
+ # Re-use same span ID as their ID space is local to the trace
611
+ span_id=context.span_id,
612
+ is_remote=context.is_remote,
613
+ # Override trace flag as if it is sampled within current context.
614
+ trace_flags=TraceFlags(TraceFlags.SAMPLED),
615
+ )
616
+
617
+ if end_trace:
618
+ clone_span.end(end_time_ns=span.end_time_ns)
619
+
620
+ return clone_span
621
+
622
+
623
+ NO_OP_SPAN_TRACE_ID = "MLFLOW_NO_OP_SPAN_TRACE_ID"
624
+
625
+
626
+ class NoOpSpan(Span):
627
+ """
628
+ No-op implementation of the Span interface.
629
+
630
+ This instance should be returned from the mlflow.start_span context manager when span
631
+ creation fails. This class should have exactly the same interface as the Span so that
632
+ user's setter calls do not raise runtime errors.
633
+
634
+ E.g.
635
+
636
+ .. code-block:: python
637
+
638
+ with mlflow.start_span("span_name") as span:
639
+ # Even if the span creation fails, the following calls should pass.
640
+ span.set_inputs({"x": 1})
641
+ # Do something
642
+
643
+ """
644
+
645
+ def __init__(self):
646
+ self._span = NonRecordingSpan(context=None)
647
+ self._attributes = {}
648
+
649
+ @property
650
+ def trace_id(self):
651
+ """
652
+ No-op span returns a special trace ID to distinguish it from the real spans.
653
+ """
654
+ return NO_OP_SPAN_TRACE_ID
655
+
656
+ @property
657
+ def span_id(self):
658
+ return None
659
+
660
+ @property
661
+ def name(self):
662
+ return None
663
+
664
+ @property
665
+ def start_time_ns(self):
666
+ return None
667
+
668
+ @property
669
+ def end_time_ns(self):
670
+ return None
671
+
672
+ @property
673
+ def context(self):
674
+ return None
675
+
676
+ @property
677
+ def parent_id(self):
678
+ return None
679
+
680
+ @property
681
+ def status(self):
682
+ return None
683
+
684
+ @property
685
+ def _trace_id(self):
686
+ return None
687
+
688
+ def set_inputs(self, inputs: dict[str, Any]):
689
+ pass
690
+
691
+ def set_outputs(self, outputs: dict[str, Any]):
692
+ pass
693
+
694
+ def set_attributes(self, attributes: dict[str, Any]):
695
+ pass
696
+
697
+ def set_attribute(self, key: str, value: Any):
698
+ pass
699
+
700
+ def set_status(self, status: SpanStatus):
701
+ pass
702
+
703
+ def add_event(self, event: SpanEvent):
704
+ pass
705
+
706
+ def record_exception(self, exception: Union[str, Exception]):
707
+ pass
708
+
709
+ def end(
710
+ self,
711
+ outputs: Optional[Any] = None,
712
+ attributes: Optional[dict[str, Any]] = None,
713
+ status: Optional[Union[SpanStatus, str]] = None,
714
+ end_time_ns: Optional[int] = None,
715
+ ):
716
+ pass
717
+
718
+
719
+ class _SpanAttributesRegistry:
720
+ """
721
+ A utility class to manage the span attributes.
722
+
723
+ In MLflow users can add arbitrary key-value pairs to the span attributes, however,
724
+ OpenTelemetry only allows a limited set of types to be stored in the attribute values.
725
+ Therefore, we serialize all values into JSON string before storing them in the span.
726
+ This class provides simple getter and setter methods to interact with the span attributes
727
+ without worrying about the serde process.
728
+ """
729
+
730
+ def __init__(self, otel_span: OTelSpan):
731
+ self._span = otel_span
732
+
733
+ def get_all(self) -> dict[str, Any]:
734
+ return {key: self.get(key) for key in self._span.attributes.keys()}
735
+
736
+ def get(self, key: str):
737
+ serialized_value = self._span.attributes.get(key)
738
+ if serialized_value:
739
+ try:
740
+ return json.loads(serialized_value)
741
+ except Exception as e:
742
+ _logger.warning(
743
+ f"Failed to get value for key {key}, make sure you set the attribute "
744
+ f"on mlflow Span class instead of directly to the OpenTelemetry span. {e}"
745
+ )
746
+
747
+ def set(self, key: str, value: Any):
748
+ if not isinstance(key, str):
749
+ _logger.warning(f"Attribute key must be a string, but got {type(key)}. Skipping.")
750
+ return
751
+
752
+ # NB: OpenTelemetry attribute can store not only string but also a few primitives like
753
+ # int, float, bool, and list of them. However, we serialize all into JSON string here
754
+ # for the simplicity in deserialization process.
755
+ self._span.set_attribute(key, json.dumps(value, cls=TraceJSONEncoder, ensure_ascii=False))
756
+
757
+
758
+ class _CachedSpanAttributesRegistry(_SpanAttributesRegistry):
759
+ """
760
+ A cache-enabled version of the SpanAttributesRegistry.
761
+
762
+ The caching helps to avoid the redundant deserialization of the attribute, however, it does
763
+ not handle the value change well. Therefore, this class should only be used for the persisted
764
+ spans that are immutable, and thus implemented as a subclass of _SpanAttributesRegistry.
765
+ """
766
+
767
+ @lru_cache(maxsize=128)
768
+ def get(self, key: str):
769
+ return super().get(key)
770
+
771
+ def set(self, key: str, value: Any):
772
+ raise MlflowException(
773
+ "The attributes of the immutable span must not be updated.", INVALID_PARAMETER_VALUE
774
+ )