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,221 @@
1
+ """
2
+ Genesis-Flow Secure Model Loading
3
+
4
+ This module provides secure alternatives to pickle-based model loading,
5
+ addressing security vulnerabilities in model deserialization.
6
+ """
7
+
8
+ import io
9
+ import pickle
10
+ import cloudpickle
11
+ import logging
12
+ import hashlib
13
+ from typing import Any, Set, Optional, Union, Type
14
+ from pathlib import Path
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ # Allowlist of safe classes that can be unpickled
19
+ SAFE_PICKLE_CLASSES = {
20
+ # NumPy types
21
+ 'numpy.ndarray',
22
+ 'numpy.dtype',
23
+ 'numpy.int32', 'numpy.int64', 'numpy.float32', 'numpy.float64',
24
+ 'numpy.bool_', 'numpy.str_',
25
+
26
+ # Pandas types
27
+ 'pandas.core.frame.DataFrame',
28
+ 'pandas.core.series.Series',
29
+ 'pandas.core.index.Index',
30
+ 'pandas.core.dtypes.dtypes.CategoricalDtype',
31
+
32
+ # Scikit-learn estimators (core models only)
33
+ 'sklearn.linear_model._base.LinearRegression',
34
+ 'sklearn.linear_model._logistic.LogisticRegression',
35
+ 'sklearn.ensemble._forest.RandomForestClassifier',
36
+ 'sklearn.ensemble._forest.RandomForestRegressor',
37
+ 'sklearn.tree._classes.DecisionTreeClassifier',
38
+ 'sklearn.tree._classes.DecisionTreeRegressor',
39
+ 'sklearn.svm._classes.SVC',
40
+ 'sklearn.svm._classes.SVR',
41
+
42
+ # Standard Python types
43
+ 'builtins.dict', 'builtins.list', 'builtins.tuple', 'builtins.set',
44
+ 'builtins.str', 'builtins.int', 'builtins.float', 'builtins.bool',
45
+
46
+ # Collections
47
+ 'collections.OrderedDict',
48
+ 'collections.defaultdict',
49
+
50
+ # Genesis-Flow internal types
51
+ 'mlflow.models.signature.ModelSignature',
52
+ 'mlflow.types.schema.Schema',
53
+ }
54
+
55
+ class RestrictedUnpickler(pickle.Unpickler):
56
+ """
57
+ Secure unpickler that only allows safe, whitelisted classes.
58
+
59
+ This prevents arbitrary code execution during model deserialization
60
+ by restricting which classes can be instantiated.
61
+ """
62
+
63
+ def __init__(self, file, *, safe_classes: Optional[Set[str]] = None):
64
+ super().__init__(file)
65
+ self.safe_classes = safe_classes or SAFE_PICKLE_CLASSES
66
+
67
+ def find_class(self, module: str, name: str) -> Type:
68
+ """
69
+ Override to restrict class loading to safe classes only.
70
+
71
+ Args:
72
+ module: Module name
73
+ name: Class name
74
+
75
+ Returns:
76
+ Class object if safe
77
+
78
+ Raises:
79
+ SecurityError: If class is not in allowlist
80
+ """
81
+ full_name = f"{module}.{name}"
82
+
83
+ # Check if the class is in our safe list
84
+ if full_name in self.safe_classes:
85
+ logger.debug(f"Loading safe class: {full_name}")
86
+ return super().find_class(module, name)
87
+
88
+ # Additional check for known safe modules
89
+ safe_modules = {
90
+ 'numpy': ['ndarray', 'dtype', 'int32', 'int64', 'float32', 'float64', 'bool_'],
91
+ 'pandas': ['DataFrame', 'Series', 'Index'],
92
+ 'builtins': ['dict', 'list', 'tuple', 'set', 'str', 'int', 'float', 'bool'],
93
+ }
94
+
95
+ if module in safe_modules and name in safe_modules[module]:
96
+ logger.debug(f"Loading safe module class: {full_name}")
97
+ return super().find_class(module, name)
98
+
99
+ # Log and block unsafe class
100
+ logger.warning(f"Blocked potentially unsafe class: {full_name}")
101
+ raise pickle.UnpicklingError(
102
+ f"Security: Class '{full_name}' is not in the allowlist. "
103
+ f"If this is a legitimate model class, add it to SAFE_PICKLE_CLASSES."
104
+ )
105
+
106
+ class SecureModelLoader:
107
+ """
108
+ Secure model loading with multiple safety mechanisms.
109
+ """
110
+
111
+ @staticmethod
112
+ def calculate_file_hash(file_path: Union[str, Path]) -> str:
113
+ """Calculate SHA256 hash of a file for integrity checking."""
114
+ hasher = hashlib.sha256()
115
+ with open(file_path, 'rb') as f:
116
+ for chunk in iter(lambda: f.read(4096), b""):
117
+ hasher.update(chunk)
118
+ return hasher.hexdigest()
119
+
120
+ @staticmethod
121
+ def safe_pickle_load(file_path: Union[str, Path], *, safe_classes: Optional[Set[str]] = None) -> Any:
122
+ """
123
+ Safely load a pickle file using restricted unpickler.
124
+
125
+ Args:
126
+ file_path: Path to pickle file
127
+ safe_classes: Optional custom set of safe classes
128
+
129
+ Returns:
130
+ Unpickled object
131
+
132
+ Raises:
133
+ SecurityError: If file contains unsafe classes
134
+ FileNotFoundError: If file doesn't exist
135
+ """
136
+ file_path = Path(file_path)
137
+
138
+ if not file_path.exists():
139
+ raise FileNotFoundError(f"Model file not found: {file_path}")
140
+
141
+ # Log file hash for audit trail
142
+ file_hash = SecureModelLoader.calculate_file_hash(file_path)
143
+ logger.info(f"Loading model file {file_path.name} (SHA256: {file_hash[:16]}...)")
144
+
145
+ try:
146
+ with open(file_path, 'rb') as f:
147
+ unpickler = RestrictedUnpickler(f, safe_classes=safe_classes)
148
+ model = unpickler.load()
149
+ logger.info(f"Successfully loaded model of type: {type(model).__name__}")
150
+ return model
151
+ except pickle.UnpicklingError as e:
152
+ logger.error(f"Security: Unsafe model file rejected: {e}")
153
+ raise SecurityError(f"Model file contains unsafe content: {e}") from e
154
+ except Exception as e:
155
+ logger.error(f"Error loading model: {e}")
156
+ raise
157
+
158
+ @staticmethod
159
+ def safe_cloudpickle_load(file_path: Union[str, Path], *, safe_classes: Optional[Set[str]] = None) -> Any:
160
+ """
161
+ Safely load a cloudpickle file using restricted unpickler.
162
+
163
+ Args:
164
+ file_path: Path to cloudpickle file
165
+ safe_classes: Optional custom set of safe classes
166
+
167
+ Returns:
168
+ Unpickled object
169
+ """
170
+ file_path = Path(file_path)
171
+
172
+ if not file_path.exists():
173
+ raise FileNotFoundError(f"Model file not found: {file_path}")
174
+
175
+ # Calculate file hash for audit trail
176
+ file_hash = SecureModelLoader.calculate_file_hash(file_path)
177
+ logger.info(f"Loading cloudpickle file {file_path.name} (SHA256: {file_hash[:16]}...)")
178
+
179
+ try:
180
+ with open(file_path, 'rb') as f:
181
+ # Use cloudpickle's load with our custom unpickler
182
+ # Note: This is a simplified approach - in practice, cloudpickle's
183
+ # load function would need to be modified to accept a custom unpickler
184
+ unpickler = RestrictedUnpickler(f, safe_classes=safe_classes)
185
+ model = unpickler.load()
186
+ logger.info(f"Successfully loaded cloudpickle model of type: {type(model).__name__}")
187
+ return model
188
+ except pickle.UnpicklingError as e:
189
+ logger.error(f"Security: Unsafe cloudpickle file rejected: {e}")
190
+ raise SecurityError(f"CloudPickle file contains unsafe content: {e}") from e
191
+ except Exception as e:
192
+ logger.error(f"Error loading cloudpickle model: {e}")
193
+ raise
194
+
195
+ class SecurityError(Exception):
196
+ """Exception raised for security-related model loading issues."""
197
+ pass
198
+
199
+ def add_safe_class(class_name: str) -> None:
200
+ """
201
+ Add a class to the safe loading allowlist.
202
+
203
+ Args:
204
+ class_name: Full class name (e.g., 'mymodule.MyClass')
205
+ """
206
+ SAFE_PICKLE_CLASSES.add(class_name)
207
+ logger.info(f"Added {class_name} to safe loading allowlist")
208
+
209
+ def remove_safe_class(class_name: str) -> None:
210
+ """
211
+ Remove a class from the safe loading allowlist.
212
+
213
+ Args:
214
+ class_name: Full class name to remove
215
+ """
216
+ SAFE_PICKLE_CLASSES.discard(class_name)
217
+ logger.info(f"Removed {class_name} from safe loading allowlist")
218
+
219
+ def get_safe_classes() -> Set[str]:
220
+ """Return a copy of the current safe classes set."""
221
+ return SAFE_PICKLE_CLASSES.copy()
@@ -0,0 +1,384 @@
1
+ """
2
+ Genesis-Flow Security Validation
3
+
4
+ This module provides comprehensive input validation to prevent
5
+ injection attacks, path traversal, and other security vulnerabilities.
6
+ """
7
+
8
+ import os
9
+ import re
10
+ import logging
11
+ from pathlib import Path
12
+ from typing import Union, Optional
13
+ from urllib.parse import urlparse
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+ class SecurityValidationError(Exception):
18
+ """Exception raised for security validation failures."""
19
+ pass
20
+
21
+ class InputValidator:
22
+ """
23
+ Comprehensive input validation for Genesis-Flow.
24
+ """
25
+
26
+ # Safe characters for different input types
27
+ SAFE_NAME_PATTERN = re.compile(r'^[a-zA-Z0-9_\-\.]+$')
28
+ SAFE_TAG_KEY_PATTERN = re.compile(r'^[a-zA-Z0-9_\-\.\/]+$')
29
+ SAFE_TAG_VALUE_PATTERN = re.compile(r'^[a-zA-Z0-9_\-\.\s\/\:\@]+$')
30
+
31
+ # Maximum lengths to prevent DoS
32
+ MAX_NAME_LENGTH = 256
33
+ MAX_TAG_KEY_LENGTH = 250
34
+ MAX_TAG_VALUE_LENGTH = 5000
35
+ MAX_DESCRIPTION_LENGTH = 10000
36
+ MAX_ARTIFACT_PATH_LENGTH = 1000
37
+
38
+ @staticmethod
39
+ def validate_experiment_name(name: str) -> str:
40
+ """
41
+ Validate experiment name against injection attacks.
42
+
43
+ Args:
44
+ name: Experiment name to validate
45
+
46
+ Returns:
47
+ Validated name
48
+
49
+ Raises:
50
+ SecurityValidationError: If name is invalid
51
+ """
52
+ if not name or not isinstance(name, str):
53
+ raise SecurityValidationError("Experiment name must be a non-empty string")
54
+
55
+ if len(name) > InputValidator.MAX_NAME_LENGTH:
56
+ raise SecurityValidationError(
57
+ f"Experiment name too long (max {InputValidator.MAX_NAME_LENGTH} chars)"
58
+ )
59
+
60
+ # Check for dangerous characters
61
+ if not InputValidator.SAFE_NAME_PATTERN.match(name):
62
+ raise SecurityValidationError(
63
+ "Experiment name contains invalid characters. "
64
+ "Only alphanumeric, dash, underscore, and dot allowed."
65
+ )
66
+
67
+ # Prevent directory traversal
68
+ if '..' in name or '/' in name or '\\' in name:
69
+ raise SecurityValidationError("Experiment name cannot contain path traversal sequences")
70
+
71
+ logger.debug(f"Validated experiment name: {name}")
72
+ return name
73
+
74
+ @staticmethod
75
+ def validate_run_name(name: Optional[str]) -> Optional[str]:
76
+ """
77
+ Validate run name.
78
+
79
+ Args:
80
+ name: Run name to validate (can be None)
81
+
82
+ Returns:
83
+ Validated name or None
84
+ """
85
+ if name is None:
86
+ return None
87
+
88
+ if not isinstance(name, str):
89
+ raise SecurityValidationError("Run name must be a string")
90
+
91
+ if len(name) > InputValidator.MAX_NAME_LENGTH:
92
+ raise SecurityValidationError(
93
+ f"Run name too long (max {InputValidator.MAX_NAME_LENGTH} chars)"
94
+ )
95
+
96
+ # Allow more flexible run names but still prevent injection
97
+ if '..' in name or '\x00' in name:
98
+ raise SecurityValidationError("Run name contains invalid sequences")
99
+
100
+ return name
101
+
102
+ @staticmethod
103
+ def validate_tag_key(key: str) -> str:
104
+ """
105
+ Validate tag key.
106
+
107
+ Args:
108
+ key: Tag key to validate
109
+
110
+ Returns:
111
+ Validated key
112
+ """
113
+ if not key or not isinstance(key, str):
114
+ raise SecurityValidationError("Tag key must be a non-empty string")
115
+
116
+ if len(key) > InputValidator.MAX_TAG_KEY_LENGTH:
117
+ raise SecurityValidationError(
118
+ f"Tag key too long (max {InputValidator.MAX_TAG_KEY_LENGTH} chars)"
119
+ )
120
+
121
+ if not InputValidator.SAFE_TAG_KEY_PATTERN.match(key):
122
+ raise SecurityValidationError(
123
+ "Tag key contains invalid characters"
124
+ )
125
+
126
+ return key
127
+
128
+ @staticmethod
129
+ def validate_tag_value(value: str) -> str:
130
+ """
131
+ Validate tag value.
132
+
133
+ Args:
134
+ value: Tag value to validate
135
+
136
+ Returns:
137
+ Validated value
138
+ """
139
+ if not isinstance(value, str):
140
+ raise SecurityValidationError("Tag value must be a string")
141
+
142
+ if len(value) > InputValidator.MAX_TAG_VALUE_LENGTH:
143
+ raise SecurityValidationError(
144
+ f"Tag value too long (max {InputValidator.MAX_TAG_VALUE_LENGTH} chars)"
145
+ )
146
+
147
+ # Check for control characters and potential injection
148
+ if '\x00' in value or '\r' in value:
149
+ raise SecurityValidationError("Tag value contains invalid control characters")
150
+
151
+ return value
152
+
153
+ @staticmethod
154
+ def validate_artifact_path(path: str, base_path: Optional[str] = None) -> str:
155
+ """
156
+ Validate artifact path to prevent path traversal attacks.
157
+
158
+ Args:
159
+ path: Artifact path to validate
160
+ base_path: Optional base path for additional validation
161
+
162
+ Returns:
163
+ Validated path
164
+
165
+ Raises:
166
+ SecurityValidationError: If path is unsafe
167
+ """
168
+ if not path or not isinstance(path, str):
169
+ raise SecurityValidationError("Artifact path must be a non-empty string")
170
+
171
+ if len(path) > InputValidator.MAX_ARTIFACT_PATH_LENGTH:
172
+ raise SecurityValidationError(
173
+ f"Artifact path too long (max {InputValidator.MAX_ARTIFACT_PATH_LENGTH} chars)"
174
+ )
175
+
176
+ # Normalize the path to resolve any relative components
177
+ normalized_path = os.path.normpath(path)
178
+
179
+ # Check for path traversal attempts
180
+ if '..' in normalized_path or normalized_path.startswith('/'):
181
+ raise SecurityValidationError("Artifact path contains path traversal sequences")
182
+
183
+ # Additional check if base path provided
184
+ if base_path:
185
+ base = Path(base_path).resolve()
186
+ try:
187
+ target = (base / normalized_path).resolve()
188
+ # Ensure target is within base directory
189
+ target.relative_to(base)
190
+ except ValueError:
191
+ raise SecurityValidationError("Artifact path escapes base directory")
192
+
193
+ logger.debug(f"Validated artifact path: {normalized_path}")
194
+ return normalized_path
195
+
196
+ @staticmethod
197
+ def validate_metric_key(key: str) -> str:
198
+ """
199
+ Validate metric key.
200
+
201
+ Args:
202
+ key: Metric key to validate
203
+
204
+ Returns:
205
+ Validated key
206
+ """
207
+ if not key or not isinstance(key, str):
208
+ raise SecurityValidationError("Metric key must be a non-empty string")
209
+
210
+ if len(key) > InputValidator.MAX_TAG_KEY_LENGTH:
211
+ raise SecurityValidationError(
212
+ f"Metric key too long (max {InputValidator.MAX_TAG_KEY_LENGTH} chars)"
213
+ )
214
+
215
+ # Metric keys should be more restrictive
216
+ if not re.match(r'^[a-zA-Z0-9_\-\.]+$', key):
217
+ raise SecurityValidationError(
218
+ "Metric key contains invalid characters. "
219
+ "Only alphanumeric, dash, underscore, and dot allowed."
220
+ )
221
+
222
+ return key
223
+
224
+ @staticmethod
225
+ def validate_param_key(key: str) -> str:
226
+ """
227
+ Validate parameter key.
228
+
229
+ Args:
230
+ key: Parameter key to validate
231
+
232
+ Returns:
233
+ Validated key
234
+ """
235
+ if not key or not isinstance(key, str):
236
+ raise SecurityValidationError("Parameter key must be a non-empty string")
237
+
238
+ if len(key) > InputValidator.MAX_TAG_KEY_LENGTH:
239
+ raise SecurityValidationError(
240
+ f"Parameter key too long (max {InputValidator.MAX_TAG_KEY_LENGTH} chars)"
241
+ )
242
+
243
+ # Parameter keys should be restrictive
244
+ if not re.match(r'^[a-zA-Z0-9_\-\.]+$', key):
245
+ raise SecurityValidationError(
246
+ "Parameter key contains invalid characters. "
247
+ "Only alphanumeric, dash, underscore, and dot allowed."
248
+ )
249
+
250
+ return key
251
+
252
+ @staticmethod
253
+ def validate_param_value(value: Union[str, int, float]) -> str:
254
+ """
255
+ Validate parameter value.
256
+
257
+ Args:
258
+ value: Parameter value to validate
259
+
260
+ Returns:
261
+ Validated value as string
262
+ """
263
+ if value is None:
264
+ raise SecurityValidationError("Parameter value cannot be None")
265
+
266
+ # Convert to string if needed
267
+ str_value = str(value)
268
+
269
+ if len(str_value) > InputValidator.MAX_TAG_VALUE_LENGTH:
270
+ raise SecurityValidationError(
271
+ f"Parameter value too long (max {InputValidator.MAX_TAG_VALUE_LENGTH} chars)"
272
+ )
273
+
274
+ # Check for control characters
275
+ if '\x00' in str_value or '\r' in str_value:
276
+ raise SecurityValidationError("Parameter value contains invalid control characters")
277
+
278
+ return str_value
279
+
280
+ @staticmethod
281
+ def validate_model_name(name: str) -> str:
282
+ """
283
+ Validate registered model name.
284
+
285
+ Args:
286
+ name: Model name to validate
287
+
288
+ Returns:
289
+ Validated name
290
+ """
291
+ if not name or not isinstance(name, str):
292
+ raise SecurityValidationError("Model name must be a non-empty string")
293
+
294
+ if len(name) > InputValidator.MAX_NAME_LENGTH:
295
+ raise SecurityValidationError(
296
+ f"Model name too long (max {InputValidator.MAX_NAME_LENGTH} chars)"
297
+ )
298
+
299
+ # Model names should be safe for file systems and URLs
300
+ if not re.match(r'^[a-zA-Z0-9_\-\.]+$', name):
301
+ raise SecurityValidationError(
302
+ "Model name contains invalid characters. "
303
+ "Only alphanumeric, dash, underscore, and dot allowed."
304
+ )
305
+
306
+ # Prevent directory traversal
307
+ if '..' in name:
308
+ raise SecurityValidationError("Model name cannot contain '..'")
309
+
310
+ return name
311
+
312
+ @staticmethod
313
+ def validate_uri(uri: str, allowed_schemes: Optional[set] = None) -> str:
314
+ """
315
+ Validate URI for safety.
316
+
317
+ Args:
318
+ uri: URI to validate
319
+ allowed_schemes: Set of allowed URI schemes
320
+
321
+ Returns:
322
+ Validated URI
323
+ """
324
+ if not uri or not isinstance(uri, str):
325
+ raise SecurityValidationError("URI must be a non-empty string")
326
+
327
+ if allowed_schemes is None:
328
+ allowed_schemes = {'http', 'https', 'file', 's3', 'gs', 'azure'}
329
+
330
+ try:
331
+ parsed = urlparse(uri)
332
+ except Exception as e:
333
+ raise SecurityValidationError(f"Invalid URI format: {e}")
334
+
335
+ if parsed.scheme and parsed.scheme not in allowed_schemes:
336
+ raise SecurityValidationError(
337
+ f"URI scheme '{parsed.scheme}' not allowed. "
338
+ f"Allowed schemes: {sorted(allowed_schemes)}"
339
+ )
340
+
341
+ # Check for potential SSRF attacks
342
+ if parsed.hostname:
343
+ # Block private/local addresses for HTTP schemes
344
+ if parsed.scheme in ('http', 'https'):
345
+ if parsed.hostname.lower() in ('localhost', '127.0.0.1', '0.0.0.0'):
346
+ raise SecurityValidationError("URI points to localhost/loopback address")
347
+
348
+ # Block private IP ranges (basic check)
349
+ if (parsed.hostname.startswith('192.168.') or
350
+ parsed.hostname.startswith('10.') or
351
+ parsed.hostname.startswith('172.')):
352
+ raise SecurityValidationError("URI points to private IP address")
353
+
354
+ return uri
355
+
356
+ def secure_filename(filename: str) -> str:
357
+ """
358
+ Secure a filename by removing/replacing dangerous characters.
359
+
360
+ Args:
361
+ filename: Original filename
362
+
363
+ Returns:
364
+ Secured filename
365
+ """
366
+ if not filename:
367
+ raise SecurityValidationError("Filename cannot be empty")
368
+
369
+ # Remove path components
370
+ filename = os.path.basename(filename)
371
+
372
+ # Replace dangerous characters
373
+ filename = re.sub(r'[^\w\-_\.]', '_', filename)
374
+
375
+ # Ensure it doesn't start with dot (hidden file)
376
+ if filename.startswith('.'):
377
+ filename = '_' + filename[1:]
378
+
379
+ # Ensure reasonable length
380
+ if len(filename) > 255:
381
+ name, ext = os.path.splitext(filename)
382
+ filename = name[:251-len(ext)] + ext
383
+
384
+ return filename
@@ -0,0 +1,61 @@
1
+ """
2
+ Utilities for MLflow cli server config validation and resolving.
3
+ NOTE: these functions are intended to be used as utilities for the cli click-based interface.
4
+ Do not use for any other purpose as the potential Exceptions being raised will be misleading
5
+ for users.
6
+ """
7
+
8
+ import click
9
+
10
+ from mlflow.store.tracking import DEFAULT_ARTIFACTS_URI, DEFAULT_LOCAL_FILE_AND_ARTIFACT_PATH
11
+ from mlflow.utils.logging_utils import eprint
12
+ from mlflow.utils.uri import is_local_uri
13
+
14
+
15
+ def resolve_default_artifact_root(
16
+ serve_artifacts: bool,
17
+ default_artifact_root: str,
18
+ backend_store_uri: str,
19
+ resolve_to_local: bool = False,
20
+ ) -> str:
21
+ if serve_artifacts and not default_artifact_root:
22
+ default_artifact_root = DEFAULT_ARTIFACTS_URI
23
+ elif not serve_artifacts and not default_artifact_root:
24
+ if is_local_uri(backend_store_uri):
25
+ default_artifact_root = backend_store_uri
26
+ elif resolve_to_local:
27
+ default_artifact_root = DEFAULT_LOCAL_FILE_AND_ARTIFACT_PATH
28
+ else:
29
+ msg = (
30
+ "Option 'default-artifact-root' is required when backend store is not "
31
+ "local file based and artifact serving is disabled."
32
+ )
33
+ eprint(msg)
34
+ raise click.UsageError(message=msg)
35
+ return default_artifact_root
36
+
37
+
38
+ def _is_default_backend_store_uri(backend_store_uri: str) -> bool:
39
+ """Utility function to validate if the configured backend store uri location is set as the
40
+ default value for MLflow server.
41
+
42
+ Args:
43
+ backend_store_uri: The value set for the backend store uri for MLflow server artifact
44
+ handling.
45
+
46
+ Returns:
47
+ bool True if the default value is set.
48
+
49
+ """
50
+ return backend_store_uri == DEFAULT_LOCAL_FILE_AND_ARTIFACT_PATH
51
+
52
+
53
+ def artifacts_only_config_validation(artifacts_only: bool, backend_store_uri: str) -> None:
54
+ if artifacts_only and not _is_default_backend_store_uri(backend_store_uri):
55
+ msg = (
56
+ "You are starting a tracking server in `--artifacts-only` mode and have provided a "
57
+ f"value for `--backend_store_uri`: '{backend_store_uri}'. A tracking server in "
58
+ "`--artifacts-only` mode cannot have a value set for `--backend_store_uri` to "
59
+ "properly proxy access to the artifact storage location."
60
+ )
61
+ raise click.UsageError(message=msg)
@@ -0,0 +1,15 @@
1
+ def is_spark_connect_mode():
2
+ try:
3
+ from pyspark.sql.utils import is_remote
4
+ except ImportError:
5
+ return False
6
+ return is_remote()
7
+
8
+
9
+ def get_spark_dataframe_type():
10
+ if is_spark_connect_mode():
11
+ from pyspark.sql.connect.dataframe import DataFrame as SparkDataFrame
12
+ else:
13
+ from pyspark.sql import DataFrame as SparkDataFrame
14
+
15
+ return SparkDataFrame