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.
- genesis_flow-1.0.0.dist-info/METADATA +822 -0
- genesis_flow-1.0.0.dist-info/RECORD +645 -0
- genesis_flow-1.0.0.dist-info/WHEEL +5 -0
- genesis_flow-1.0.0.dist-info/entry_points.txt +19 -0
- genesis_flow-1.0.0.dist-info/licenses/LICENSE.txt +202 -0
- genesis_flow-1.0.0.dist-info/top_level.txt +1 -0
- mlflow/__init__.py +367 -0
- mlflow/__main__.py +3 -0
- mlflow/ag2/__init__.py +56 -0
- mlflow/ag2/ag2_logger.py +294 -0
- mlflow/anthropic/__init__.py +40 -0
- mlflow/anthropic/autolog.py +129 -0
- mlflow/anthropic/chat.py +144 -0
- mlflow/artifacts/__init__.py +268 -0
- mlflow/autogen/__init__.py +144 -0
- mlflow/autogen/chat.py +142 -0
- mlflow/azure/__init__.py +26 -0
- mlflow/azure/auth_handler.py +257 -0
- mlflow/azure/client.py +319 -0
- mlflow/azure/config.py +120 -0
- mlflow/azure/connection_factory.py +340 -0
- mlflow/azure/exceptions.py +27 -0
- mlflow/azure/stores.py +327 -0
- mlflow/azure/utils.py +183 -0
- mlflow/bedrock/__init__.py +45 -0
- mlflow/bedrock/_autolog.py +202 -0
- mlflow/bedrock/chat.py +122 -0
- mlflow/bedrock/stream.py +160 -0
- mlflow/bedrock/utils.py +43 -0
- mlflow/cli.py +707 -0
- mlflow/client.py +12 -0
- mlflow/config/__init__.py +56 -0
- mlflow/crewai/__init__.py +79 -0
- mlflow/crewai/autolog.py +253 -0
- mlflow/crewai/chat.py +29 -0
- mlflow/data/__init__.py +75 -0
- mlflow/data/artifact_dataset_sources.py +170 -0
- mlflow/data/code_dataset_source.py +40 -0
- mlflow/data/dataset.py +123 -0
- mlflow/data/dataset_registry.py +168 -0
- mlflow/data/dataset_source.py +110 -0
- mlflow/data/dataset_source_registry.py +219 -0
- mlflow/data/delta_dataset_source.py +167 -0
- mlflow/data/digest_utils.py +108 -0
- mlflow/data/evaluation_dataset.py +562 -0
- mlflow/data/filesystem_dataset_source.py +81 -0
- mlflow/data/http_dataset_source.py +145 -0
- mlflow/data/huggingface_dataset.py +258 -0
- mlflow/data/huggingface_dataset_source.py +118 -0
- mlflow/data/meta_dataset.py +104 -0
- mlflow/data/numpy_dataset.py +223 -0
- mlflow/data/pandas_dataset.py +231 -0
- mlflow/data/polars_dataset.py +352 -0
- mlflow/data/pyfunc_dataset_mixin.py +31 -0
- mlflow/data/schema.py +76 -0
- mlflow/data/sources.py +1 -0
- mlflow/data/spark_dataset.py +406 -0
- mlflow/data/spark_dataset_source.py +74 -0
- mlflow/data/spark_delta_utils.py +118 -0
- mlflow/data/tensorflow_dataset.py +350 -0
- mlflow/data/uc_volume_dataset_source.py +81 -0
- mlflow/db.py +27 -0
- mlflow/dspy/__init__.py +17 -0
- mlflow/dspy/autolog.py +197 -0
- mlflow/dspy/callback.py +398 -0
- mlflow/dspy/constant.py +1 -0
- mlflow/dspy/load.py +93 -0
- mlflow/dspy/save.py +393 -0
- mlflow/dspy/util.py +109 -0
- mlflow/dspy/wrapper.py +226 -0
- mlflow/entities/__init__.py +104 -0
- mlflow/entities/_mlflow_object.py +52 -0
- mlflow/entities/assessment.py +545 -0
- mlflow/entities/assessment_error.py +80 -0
- mlflow/entities/assessment_source.py +141 -0
- mlflow/entities/dataset.py +92 -0
- mlflow/entities/dataset_input.py +51 -0
- mlflow/entities/dataset_summary.py +62 -0
- mlflow/entities/document.py +48 -0
- mlflow/entities/experiment.py +109 -0
- mlflow/entities/experiment_tag.py +35 -0
- mlflow/entities/file_info.py +45 -0
- mlflow/entities/input_tag.py +35 -0
- mlflow/entities/lifecycle_stage.py +35 -0
- mlflow/entities/logged_model.py +228 -0
- mlflow/entities/logged_model_input.py +26 -0
- mlflow/entities/logged_model_output.py +32 -0
- mlflow/entities/logged_model_parameter.py +46 -0
- mlflow/entities/logged_model_status.py +74 -0
- mlflow/entities/logged_model_tag.py +33 -0
- mlflow/entities/metric.py +200 -0
- mlflow/entities/model_registry/__init__.py +29 -0
- mlflow/entities/model_registry/_model_registry_entity.py +13 -0
- mlflow/entities/model_registry/model_version.py +243 -0
- mlflow/entities/model_registry/model_version_deployment_job_run_state.py +44 -0
- mlflow/entities/model_registry/model_version_deployment_job_state.py +70 -0
- mlflow/entities/model_registry/model_version_search.py +25 -0
- mlflow/entities/model_registry/model_version_stages.py +25 -0
- mlflow/entities/model_registry/model_version_status.py +35 -0
- mlflow/entities/model_registry/model_version_tag.py +35 -0
- mlflow/entities/model_registry/prompt.py +73 -0
- mlflow/entities/model_registry/prompt_version.py +244 -0
- mlflow/entities/model_registry/registered_model.py +175 -0
- mlflow/entities/model_registry/registered_model_alias.py +35 -0
- mlflow/entities/model_registry/registered_model_deployment_job_state.py +39 -0
- mlflow/entities/model_registry/registered_model_search.py +25 -0
- mlflow/entities/model_registry/registered_model_tag.py +35 -0
- mlflow/entities/multipart_upload.py +74 -0
- mlflow/entities/param.py +49 -0
- mlflow/entities/run.py +97 -0
- mlflow/entities/run_data.py +84 -0
- mlflow/entities/run_info.py +188 -0
- mlflow/entities/run_inputs.py +59 -0
- mlflow/entities/run_outputs.py +43 -0
- mlflow/entities/run_status.py +41 -0
- mlflow/entities/run_tag.py +36 -0
- mlflow/entities/source_type.py +31 -0
- mlflow/entities/span.py +774 -0
- mlflow/entities/span_event.py +96 -0
- mlflow/entities/span_status.py +102 -0
- mlflow/entities/trace.py +317 -0
- mlflow/entities/trace_data.py +71 -0
- mlflow/entities/trace_info.py +220 -0
- mlflow/entities/trace_info_v2.py +162 -0
- mlflow/entities/trace_location.py +173 -0
- mlflow/entities/trace_state.py +39 -0
- mlflow/entities/trace_status.py +68 -0
- mlflow/entities/view_type.py +51 -0
- mlflow/environment_variables.py +866 -0
- mlflow/evaluation/__init__.py +16 -0
- mlflow/evaluation/assessment.py +369 -0
- mlflow/evaluation/evaluation.py +411 -0
- mlflow/evaluation/evaluation_tag.py +61 -0
- mlflow/evaluation/fluent.py +48 -0
- mlflow/evaluation/utils.py +201 -0
- mlflow/exceptions.py +213 -0
- mlflow/experiments.py +140 -0
- mlflow/gemini/__init__.py +81 -0
- mlflow/gemini/autolog.py +186 -0
- mlflow/gemini/chat.py +261 -0
- mlflow/genai/__init__.py +71 -0
- mlflow/genai/datasets/__init__.py +67 -0
- mlflow/genai/datasets/evaluation_dataset.py +131 -0
- mlflow/genai/evaluation/__init__.py +3 -0
- mlflow/genai/evaluation/base.py +411 -0
- mlflow/genai/evaluation/constant.py +23 -0
- mlflow/genai/evaluation/utils.py +244 -0
- mlflow/genai/judges/__init__.py +21 -0
- mlflow/genai/judges/databricks.py +404 -0
- mlflow/genai/label_schemas/__init__.py +153 -0
- mlflow/genai/label_schemas/label_schemas.py +209 -0
- mlflow/genai/labeling/__init__.py +159 -0
- mlflow/genai/labeling/labeling.py +250 -0
- mlflow/genai/optimize/__init__.py +13 -0
- mlflow/genai/optimize/base.py +198 -0
- mlflow/genai/optimize/optimizers/__init__.py +4 -0
- mlflow/genai/optimize/optimizers/base_optimizer.py +38 -0
- mlflow/genai/optimize/optimizers/dspy_mipro_optimizer.py +221 -0
- mlflow/genai/optimize/optimizers/dspy_optimizer.py +91 -0
- mlflow/genai/optimize/optimizers/utils/dspy_mipro_callback.py +76 -0
- mlflow/genai/optimize/optimizers/utils/dspy_mipro_utils.py +18 -0
- mlflow/genai/optimize/types.py +75 -0
- mlflow/genai/optimize/util.py +30 -0
- mlflow/genai/prompts/__init__.py +206 -0
- mlflow/genai/scheduled_scorers.py +431 -0
- mlflow/genai/scorers/__init__.py +26 -0
- mlflow/genai/scorers/base.py +492 -0
- mlflow/genai/scorers/builtin_scorers.py +765 -0
- mlflow/genai/scorers/scorer_utils.py +138 -0
- mlflow/genai/scorers/validation.py +165 -0
- mlflow/genai/utils/data_validation.py +146 -0
- mlflow/genai/utils/enum_utils.py +23 -0
- mlflow/genai/utils/trace_utils.py +211 -0
- mlflow/groq/__init__.py +42 -0
- mlflow/groq/_groq_autolog.py +74 -0
- mlflow/johnsnowlabs/__init__.py +888 -0
- mlflow/langchain/__init__.py +24 -0
- mlflow/langchain/api_request_parallel_processor.py +330 -0
- mlflow/langchain/autolog.py +147 -0
- mlflow/langchain/chat_agent_langgraph.py +340 -0
- mlflow/langchain/constant.py +1 -0
- mlflow/langchain/constants.py +1 -0
- mlflow/langchain/databricks_dependencies.py +444 -0
- mlflow/langchain/langchain_tracer.py +597 -0
- mlflow/langchain/model.py +919 -0
- mlflow/langchain/output_parsers.py +142 -0
- mlflow/langchain/retriever_chain.py +153 -0
- mlflow/langchain/runnables.py +527 -0
- mlflow/langchain/utils/chat.py +402 -0
- mlflow/langchain/utils/logging.py +671 -0
- mlflow/langchain/utils/serialization.py +36 -0
- mlflow/legacy_databricks_cli/__init__.py +0 -0
- mlflow/legacy_databricks_cli/configure/__init__.py +0 -0
- mlflow/legacy_databricks_cli/configure/provider.py +482 -0
- mlflow/litellm/__init__.py +175 -0
- mlflow/llama_index/__init__.py +22 -0
- mlflow/llama_index/autolog.py +55 -0
- mlflow/llama_index/chat.py +43 -0
- mlflow/llama_index/constant.py +1 -0
- mlflow/llama_index/model.py +577 -0
- mlflow/llama_index/pyfunc_wrapper.py +332 -0
- mlflow/llama_index/serialize_objects.py +188 -0
- mlflow/llama_index/tracer.py +561 -0
- mlflow/metrics/__init__.py +479 -0
- mlflow/metrics/base.py +39 -0
- mlflow/metrics/genai/__init__.py +25 -0
- mlflow/metrics/genai/base.py +101 -0
- mlflow/metrics/genai/genai_metric.py +771 -0
- mlflow/metrics/genai/metric_definitions.py +450 -0
- mlflow/metrics/genai/model_utils.py +371 -0
- mlflow/metrics/genai/prompt_template.py +68 -0
- mlflow/metrics/genai/prompts/__init__.py +0 -0
- mlflow/metrics/genai/prompts/v1.py +422 -0
- mlflow/metrics/genai/utils.py +6 -0
- mlflow/metrics/metric_definitions.py +619 -0
- mlflow/mismatch.py +34 -0
- mlflow/mistral/__init__.py +34 -0
- mlflow/mistral/autolog.py +71 -0
- mlflow/mistral/chat.py +135 -0
- mlflow/ml_package_versions.py +452 -0
- mlflow/models/__init__.py +97 -0
- mlflow/models/auth_policy.py +83 -0
- mlflow/models/cli.py +354 -0
- mlflow/models/container/__init__.py +294 -0
- mlflow/models/container/scoring_server/__init__.py +0 -0
- mlflow/models/container/scoring_server/nginx.conf +39 -0
- mlflow/models/dependencies_schemas.py +287 -0
- mlflow/models/display_utils.py +158 -0
- mlflow/models/docker_utils.py +211 -0
- mlflow/models/evaluation/__init__.py +23 -0
- mlflow/models/evaluation/_shap_patch.py +64 -0
- mlflow/models/evaluation/artifacts.py +194 -0
- mlflow/models/evaluation/base.py +1811 -0
- mlflow/models/evaluation/calibration_curve.py +109 -0
- mlflow/models/evaluation/default_evaluator.py +996 -0
- mlflow/models/evaluation/deprecated.py +23 -0
- mlflow/models/evaluation/evaluator_registry.py +80 -0
- mlflow/models/evaluation/evaluators/classifier.py +704 -0
- mlflow/models/evaluation/evaluators/default.py +233 -0
- mlflow/models/evaluation/evaluators/regressor.py +96 -0
- mlflow/models/evaluation/evaluators/shap.py +296 -0
- mlflow/models/evaluation/lift_curve.py +178 -0
- mlflow/models/evaluation/utils/metric.py +123 -0
- mlflow/models/evaluation/utils/trace.py +179 -0
- mlflow/models/evaluation/validation.py +434 -0
- mlflow/models/flavor_backend.py +93 -0
- mlflow/models/flavor_backend_registry.py +53 -0
- mlflow/models/model.py +1639 -0
- mlflow/models/model_config.py +150 -0
- mlflow/models/notebook_resources/agent_evaluation_template.html +235 -0
- mlflow/models/notebook_resources/eval_with_dataset_example.py +22 -0
- mlflow/models/notebook_resources/eval_with_synthetic_example.py +22 -0
- mlflow/models/python_api.py +369 -0
- mlflow/models/rag_signatures.py +128 -0
- mlflow/models/resources.py +321 -0
- mlflow/models/signature.py +662 -0
- mlflow/models/utils.py +2054 -0
- mlflow/models/wheeled_model.py +280 -0
- mlflow/openai/__init__.py +57 -0
- mlflow/openai/_agent_tracer.py +364 -0
- mlflow/openai/api_request_parallel_processor.py +131 -0
- mlflow/openai/autolog.py +509 -0
- mlflow/openai/constant.py +1 -0
- mlflow/openai/model.py +824 -0
- mlflow/openai/utils/chat_schema.py +367 -0
- mlflow/optuna/__init__.py +3 -0
- mlflow/optuna/storage.py +646 -0
- mlflow/plugins/__init__.py +72 -0
- mlflow/plugins/base.py +358 -0
- mlflow/plugins/builtin/__init__.py +24 -0
- mlflow/plugins/builtin/pytorch_plugin.py +150 -0
- mlflow/plugins/builtin/sklearn_plugin.py +158 -0
- mlflow/plugins/builtin/transformers_plugin.py +187 -0
- mlflow/plugins/cli.py +321 -0
- mlflow/plugins/discovery.py +340 -0
- mlflow/plugins/manager.py +465 -0
- mlflow/plugins/registry.py +316 -0
- mlflow/plugins/templates/framework_plugin_template.py +329 -0
- mlflow/prompt/constants.py +20 -0
- mlflow/prompt/promptlab_model.py +197 -0
- mlflow/prompt/registry_utils.py +248 -0
- mlflow/promptflow/__init__.py +495 -0
- mlflow/protos/__init__.py +0 -0
- mlflow/protos/assessments_pb2.py +174 -0
- mlflow/protos/databricks_artifacts_pb2.py +489 -0
- mlflow/protos/databricks_filesystem_service_pb2.py +196 -0
- mlflow/protos/databricks_managed_catalog_messages_pb2.py +95 -0
- mlflow/protos/databricks_managed_catalog_service_pb2.py +86 -0
- mlflow/protos/databricks_pb2.py +267 -0
- mlflow/protos/databricks_trace_server_pb2.py +374 -0
- mlflow/protos/databricks_uc_registry_messages_pb2.py +1249 -0
- mlflow/protos/databricks_uc_registry_service_pb2.py +170 -0
- mlflow/protos/facet_feature_statistics_pb2.py +296 -0
- mlflow/protos/internal_pb2.py +77 -0
- mlflow/protos/mlflow_artifacts_pb2.py +336 -0
- mlflow/protos/model_registry_pb2.py +1073 -0
- mlflow/protos/scalapb/__init__.py +0 -0
- mlflow/protos/scalapb/scalapb_pb2.py +104 -0
- mlflow/protos/service_pb2.py +2600 -0
- mlflow/protos/unity_catalog_oss_messages_pb2.py +457 -0
- mlflow/protos/unity_catalog_oss_service_pb2.py +130 -0
- mlflow/protos/unity_catalog_prompt_messages_pb2.py +447 -0
- mlflow/protos/unity_catalog_prompt_messages_pb2_grpc.py +24 -0
- mlflow/protos/unity_catalog_prompt_service_pb2.py +164 -0
- mlflow/protos/unity_catalog_prompt_service_pb2_grpc.py +785 -0
- mlflow/py.typed +0 -0
- mlflow/pydantic_ai/__init__.py +57 -0
- mlflow/pydantic_ai/autolog.py +173 -0
- mlflow/pyfunc/__init__.py +3844 -0
- mlflow/pyfunc/_mlflow_pyfunc_backend_predict.py +61 -0
- mlflow/pyfunc/backend.py +523 -0
- mlflow/pyfunc/context.py +78 -0
- mlflow/pyfunc/dbconnect_artifact_cache.py +144 -0
- mlflow/pyfunc/loaders/__init__.py +7 -0
- mlflow/pyfunc/loaders/chat_agent.py +117 -0
- mlflow/pyfunc/loaders/chat_model.py +125 -0
- mlflow/pyfunc/loaders/code_model.py +31 -0
- mlflow/pyfunc/loaders/responses_agent.py +112 -0
- mlflow/pyfunc/mlserver.py +46 -0
- mlflow/pyfunc/model.py +1473 -0
- mlflow/pyfunc/scoring_server/__init__.py +604 -0
- mlflow/pyfunc/scoring_server/app.py +7 -0
- mlflow/pyfunc/scoring_server/client.py +146 -0
- mlflow/pyfunc/spark_model_cache.py +48 -0
- mlflow/pyfunc/stdin_server.py +44 -0
- mlflow/pyfunc/utils/__init__.py +3 -0
- mlflow/pyfunc/utils/data_validation.py +224 -0
- mlflow/pyfunc/utils/environment.py +22 -0
- mlflow/pyfunc/utils/input_converter.py +47 -0
- mlflow/pyfunc/utils/serving_data_parser.py +11 -0
- mlflow/pytorch/__init__.py +1171 -0
- mlflow/pytorch/_lightning_autolog.py +580 -0
- mlflow/pytorch/_pytorch_autolog.py +50 -0
- mlflow/pytorch/pickle_module.py +35 -0
- mlflow/rfunc/__init__.py +42 -0
- mlflow/rfunc/backend.py +134 -0
- mlflow/runs.py +89 -0
- mlflow/server/__init__.py +302 -0
- mlflow/server/auth/__init__.py +1224 -0
- mlflow/server/auth/__main__.py +4 -0
- mlflow/server/auth/basic_auth.ini +6 -0
- mlflow/server/auth/cli.py +11 -0
- mlflow/server/auth/client.py +537 -0
- mlflow/server/auth/config.py +34 -0
- mlflow/server/auth/db/__init__.py +0 -0
- mlflow/server/auth/db/cli.py +18 -0
- mlflow/server/auth/db/migrations/__init__.py +0 -0
- mlflow/server/auth/db/migrations/alembic.ini +110 -0
- mlflow/server/auth/db/migrations/env.py +76 -0
- mlflow/server/auth/db/migrations/versions/8606fa83a998_initial_migration.py +51 -0
- mlflow/server/auth/db/migrations/versions/__init__.py +0 -0
- mlflow/server/auth/db/models.py +67 -0
- mlflow/server/auth/db/utils.py +37 -0
- mlflow/server/auth/entities.py +165 -0
- mlflow/server/auth/logo.py +14 -0
- mlflow/server/auth/permissions.py +65 -0
- mlflow/server/auth/routes.py +18 -0
- mlflow/server/auth/sqlalchemy_store.py +263 -0
- mlflow/server/graphql/__init__.py +0 -0
- mlflow/server/graphql/autogenerated_graphql_schema.py +353 -0
- mlflow/server/graphql/graphql_custom_scalars.py +24 -0
- mlflow/server/graphql/graphql_errors.py +15 -0
- mlflow/server/graphql/graphql_no_batching.py +89 -0
- mlflow/server/graphql/graphql_schema_extensions.py +74 -0
- mlflow/server/handlers.py +3217 -0
- mlflow/server/prometheus_exporter.py +17 -0
- mlflow/server/validation.py +30 -0
- mlflow/shap/__init__.py +691 -0
- mlflow/sklearn/__init__.py +1994 -0
- mlflow/sklearn/utils.py +1041 -0
- mlflow/smolagents/__init__.py +66 -0
- mlflow/smolagents/autolog.py +139 -0
- mlflow/smolagents/chat.py +29 -0
- mlflow/store/__init__.py +10 -0
- mlflow/store/_unity_catalog/__init__.py +1 -0
- mlflow/store/_unity_catalog/lineage/__init__.py +1 -0
- mlflow/store/_unity_catalog/lineage/constants.py +2 -0
- mlflow/store/_unity_catalog/registry/__init__.py +6 -0
- mlflow/store/_unity_catalog/registry/prompt_info.py +75 -0
- mlflow/store/_unity_catalog/registry/rest_store.py +1740 -0
- mlflow/store/_unity_catalog/registry/uc_oss_rest_store.py +507 -0
- mlflow/store/_unity_catalog/registry/utils.py +121 -0
- mlflow/store/artifact/__init__.py +0 -0
- mlflow/store/artifact/artifact_repo.py +472 -0
- mlflow/store/artifact/artifact_repository_registry.py +154 -0
- mlflow/store/artifact/azure_blob_artifact_repo.py +275 -0
- mlflow/store/artifact/azure_data_lake_artifact_repo.py +295 -0
- mlflow/store/artifact/cli.py +141 -0
- mlflow/store/artifact/cloud_artifact_repo.py +332 -0
- mlflow/store/artifact/databricks_artifact_repo.py +729 -0
- mlflow/store/artifact/databricks_artifact_repo_resources.py +301 -0
- mlflow/store/artifact/databricks_logged_model_artifact_repo.py +93 -0
- mlflow/store/artifact/databricks_models_artifact_repo.py +216 -0
- mlflow/store/artifact/databricks_sdk_artifact_repo.py +134 -0
- mlflow/store/artifact/databricks_sdk_models_artifact_repo.py +97 -0
- mlflow/store/artifact/dbfs_artifact_repo.py +240 -0
- mlflow/store/artifact/ftp_artifact_repo.py +132 -0
- mlflow/store/artifact/gcs_artifact_repo.py +296 -0
- mlflow/store/artifact/hdfs_artifact_repo.py +209 -0
- mlflow/store/artifact/http_artifact_repo.py +218 -0
- mlflow/store/artifact/local_artifact_repo.py +142 -0
- mlflow/store/artifact/mlflow_artifacts_repo.py +94 -0
- mlflow/store/artifact/models_artifact_repo.py +259 -0
- mlflow/store/artifact/optimized_s3_artifact_repo.py +356 -0
- mlflow/store/artifact/presigned_url_artifact_repo.py +173 -0
- mlflow/store/artifact/r2_artifact_repo.py +70 -0
- mlflow/store/artifact/runs_artifact_repo.py +265 -0
- mlflow/store/artifact/s3_artifact_repo.py +330 -0
- mlflow/store/artifact/sftp_artifact_repo.py +141 -0
- mlflow/store/artifact/uc_volume_artifact_repo.py +76 -0
- mlflow/store/artifact/unity_catalog_models_artifact_repo.py +168 -0
- mlflow/store/artifact/unity_catalog_oss_models_artifact_repo.py +168 -0
- mlflow/store/artifact/utils/__init__.py +0 -0
- mlflow/store/artifact/utils/models.py +148 -0
- mlflow/store/db/__init__.py +0 -0
- mlflow/store/db/base_sql_model.py +3 -0
- mlflow/store/db/db_types.py +10 -0
- mlflow/store/db/utils.py +314 -0
- mlflow/store/db_migrations/__init__.py +0 -0
- mlflow/store/db_migrations/alembic.ini +74 -0
- mlflow/store/db_migrations/env.py +84 -0
- mlflow/store/db_migrations/versions/0584bdc529eb_add_cascading_deletion_to_datasets_from_experiments.py +88 -0
- mlflow/store/db_migrations/versions/0a8213491aaa_drop_duplicate_killed_constraint.py +49 -0
- mlflow/store/db_migrations/versions/0c779009ac13_add_deleted_time_field_to_runs_table.py +24 -0
- mlflow/store/db_migrations/versions/181f10493468_allow_nulls_for_metric_values.py +35 -0
- mlflow/store/db_migrations/versions/27a6a02d2cf1_add_model_version_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/2b4d017a5e9b_add_model_registry_tables_to_db.py +77 -0
- mlflow/store/db_migrations/versions/2d6e25af4d3e_increase_max_param_val_length.py +33 -0
- mlflow/store/db_migrations/versions/3500859a5d39_add_model_aliases_table.py +50 -0
- mlflow/store/db_migrations/versions/39d1c3be5f05_add_is_nan_constraint_for_metrics_tables_if_necessary.py +41 -0
- mlflow/store/db_migrations/versions/400f98739977_add_logged_model_tables.py +123 -0
- mlflow/store/db_migrations/versions/4465047574b1_increase_max_dataset_schema_size.py +38 -0
- mlflow/store/db_migrations/versions/451aebb31d03_add_metric_step.py +35 -0
- mlflow/store/db_migrations/versions/5b0e9adcef9c_add_cascade_deletion_to_trace_tables_fk.py +40 -0
- mlflow/store/db_migrations/versions/6953534de441_add_step_to_inputs_table.py +25 -0
- mlflow/store/db_migrations/versions/728d730b5ebd_add_registered_model_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/7ac759974ad8_update_run_tags_with_larger_limit.py +36 -0
- mlflow/store/db_migrations/versions/7f2a7d5fae7d_add_datasets_inputs_input_tags_tables.py +82 -0
- mlflow/store/db_migrations/versions/84291f40a231_add_run_link_to_model_version.py +26 -0
- mlflow/store/db_migrations/versions/867495a8f9d4_add_trace_tables.py +90 -0
- mlflow/store/db_migrations/versions/89d4b8295536_create_latest_metrics_table.py +169 -0
- mlflow/store/db_migrations/versions/90e64c465722_migrate_user_column_to_tags.py +64 -0
- mlflow/store/db_migrations/versions/97727af70f4d_creation_time_last_update_time_experiments.py +25 -0
- mlflow/store/db_migrations/versions/__init__.py +0 -0
- mlflow/store/db_migrations/versions/a8c4a736bde6_allow_nulls_for_run_id.py +27 -0
- mlflow/store/db_migrations/versions/acf3f17fdcc7_add_storage_location_field_to_model_.py +29 -0
- mlflow/store/db_migrations/versions/bd07f7e963c5_create_index_on_run_uuid.py +26 -0
- mlflow/store/db_migrations/versions/bda7b8c39065_increase_model_version_tag_value_limit.py +38 -0
- mlflow/store/db_migrations/versions/c48cb773bb87_reset_default_value_for_is_nan_in_metrics_table_for_mysql.py +41 -0
- mlflow/store/db_migrations/versions/cbc13b556ace_add_v3_trace_schema_columns.py +31 -0
- mlflow/store/db_migrations/versions/cc1f77228345_change_param_value_length_to_500.py +34 -0
- mlflow/store/db_migrations/versions/cfd24bdc0731_update_run_status_constraint_with_killed.py +78 -0
- mlflow/store/db_migrations/versions/df50e92ffc5e_add_experiment_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/f5a4f2784254_increase_run_tag_value_limit.py +36 -0
- mlflow/store/entities/__init__.py +3 -0
- mlflow/store/entities/paged_list.py +18 -0
- mlflow/store/model_registry/__init__.py +10 -0
- mlflow/store/model_registry/abstract_store.py +1081 -0
- mlflow/store/model_registry/base_rest_store.py +44 -0
- mlflow/store/model_registry/databricks_workspace_model_registry_rest_store.py +37 -0
- mlflow/store/model_registry/dbmodels/__init__.py +0 -0
- mlflow/store/model_registry/dbmodels/models.py +206 -0
- mlflow/store/model_registry/file_store.py +1091 -0
- mlflow/store/model_registry/rest_store.py +481 -0
- mlflow/store/model_registry/sqlalchemy_store.py +1286 -0
- mlflow/store/tracking/__init__.py +23 -0
- mlflow/store/tracking/abstract_store.py +816 -0
- mlflow/store/tracking/dbmodels/__init__.py +0 -0
- mlflow/store/tracking/dbmodels/initial_models.py +243 -0
- mlflow/store/tracking/dbmodels/models.py +1073 -0
- mlflow/store/tracking/file_store.py +2438 -0
- mlflow/store/tracking/postgres_managed_identity.py +146 -0
- mlflow/store/tracking/rest_store.py +1131 -0
- mlflow/store/tracking/sqlalchemy_store.py +2785 -0
- mlflow/system_metrics/__init__.py +61 -0
- mlflow/system_metrics/metrics/__init__.py +0 -0
- mlflow/system_metrics/metrics/base_metrics_monitor.py +32 -0
- mlflow/system_metrics/metrics/cpu_monitor.py +23 -0
- mlflow/system_metrics/metrics/disk_monitor.py +21 -0
- mlflow/system_metrics/metrics/gpu_monitor.py +71 -0
- mlflow/system_metrics/metrics/network_monitor.py +34 -0
- mlflow/system_metrics/metrics/rocm_monitor.py +123 -0
- mlflow/system_metrics/system_metrics_monitor.py +198 -0
- mlflow/tracing/__init__.py +16 -0
- mlflow/tracing/assessment.py +356 -0
- mlflow/tracing/client.py +531 -0
- mlflow/tracing/config.py +125 -0
- mlflow/tracing/constant.py +105 -0
- mlflow/tracing/destination.py +81 -0
- mlflow/tracing/display/__init__.py +40 -0
- mlflow/tracing/display/display_handler.py +196 -0
- mlflow/tracing/export/async_export_queue.py +186 -0
- mlflow/tracing/export/inference_table.py +138 -0
- mlflow/tracing/export/mlflow_v3.py +137 -0
- mlflow/tracing/export/utils.py +70 -0
- mlflow/tracing/fluent.py +1417 -0
- mlflow/tracing/processor/base_mlflow.py +199 -0
- mlflow/tracing/processor/inference_table.py +175 -0
- mlflow/tracing/processor/mlflow_v3.py +47 -0
- mlflow/tracing/processor/otel.py +73 -0
- mlflow/tracing/provider.py +487 -0
- mlflow/tracing/trace_manager.py +200 -0
- mlflow/tracing/utils/__init__.py +616 -0
- mlflow/tracing/utils/artifact_utils.py +28 -0
- mlflow/tracing/utils/copy.py +55 -0
- mlflow/tracing/utils/environment.py +55 -0
- mlflow/tracing/utils/exception.py +21 -0
- mlflow/tracing/utils/once.py +35 -0
- mlflow/tracing/utils/otlp.py +63 -0
- mlflow/tracing/utils/processor.py +54 -0
- mlflow/tracing/utils/search.py +292 -0
- mlflow/tracing/utils/timeout.py +250 -0
- mlflow/tracing/utils/token.py +19 -0
- mlflow/tracing/utils/truncation.py +124 -0
- mlflow/tracing/utils/warning.py +76 -0
- mlflow/tracking/__init__.py +39 -0
- mlflow/tracking/_model_registry/__init__.py +1 -0
- mlflow/tracking/_model_registry/client.py +764 -0
- mlflow/tracking/_model_registry/fluent.py +853 -0
- mlflow/tracking/_model_registry/registry.py +67 -0
- mlflow/tracking/_model_registry/utils.py +251 -0
- mlflow/tracking/_tracking_service/__init__.py +0 -0
- mlflow/tracking/_tracking_service/client.py +883 -0
- mlflow/tracking/_tracking_service/registry.py +56 -0
- mlflow/tracking/_tracking_service/utils.py +275 -0
- mlflow/tracking/artifact_utils.py +179 -0
- mlflow/tracking/client.py +5900 -0
- mlflow/tracking/context/__init__.py +0 -0
- mlflow/tracking/context/abstract_context.py +35 -0
- mlflow/tracking/context/databricks_cluster_context.py +15 -0
- mlflow/tracking/context/databricks_command_context.py +15 -0
- mlflow/tracking/context/databricks_job_context.py +49 -0
- mlflow/tracking/context/databricks_notebook_context.py +41 -0
- mlflow/tracking/context/databricks_repo_context.py +43 -0
- mlflow/tracking/context/default_context.py +51 -0
- mlflow/tracking/context/git_context.py +32 -0
- mlflow/tracking/context/registry.py +98 -0
- mlflow/tracking/context/system_environment_context.py +15 -0
- mlflow/tracking/default_experiment/__init__.py +1 -0
- mlflow/tracking/default_experiment/abstract_context.py +43 -0
- mlflow/tracking/default_experiment/databricks_notebook_experiment_provider.py +44 -0
- mlflow/tracking/default_experiment/registry.py +75 -0
- mlflow/tracking/fluent.py +3595 -0
- mlflow/tracking/metric_value_conversion_utils.py +93 -0
- mlflow/tracking/multimedia.py +206 -0
- mlflow/tracking/registry.py +86 -0
- mlflow/tracking/request_auth/__init__.py +0 -0
- mlflow/tracking/request_auth/abstract_request_auth_provider.py +34 -0
- mlflow/tracking/request_auth/registry.py +60 -0
- mlflow/tracking/request_header/__init__.py +0 -0
- mlflow/tracking/request_header/abstract_request_header_provider.py +36 -0
- mlflow/tracking/request_header/databricks_request_header_provider.py +38 -0
- mlflow/tracking/request_header/default_request_header_provider.py +17 -0
- mlflow/tracking/request_header/registry.py +79 -0
- mlflow/transformers/__init__.py +2982 -0
- mlflow/transformers/flavor_config.py +258 -0
- mlflow/transformers/hub_utils.py +83 -0
- mlflow/transformers/llm_inference_utils.py +468 -0
- mlflow/transformers/model_io.py +301 -0
- mlflow/transformers/peft.py +51 -0
- mlflow/transformers/signature.py +183 -0
- mlflow/transformers/torch_utils.py +55 -0
- mlflow/types/__init__.py +21 -0
- mlflow/types/agent.py +270 -0
- mlflow/types/chat.py +240 -0
- mlflow/types/llm.py +935 -0
- mlflow/types/responses.py +139 -0
- mlflow/types/responses_helpers.py +416 -0
- mlflow/types/schema.py +1505 -0
- mlflow/types/type_hints.py +647 -0
- mlflow/types/utils.py +753 -0
- mlflow/utils/__init__.py +283 -0
- mlflow/utils/_capture_modules.py +256 -0
- mlflow/utils/_capture_transformers_modules.py +75 -0
- mlflow/utils/_spark_utils.py +201 -0
- mlflow/utils/_unity_catalog_oss_utils.py +97 -0
- mlflow/utils/_unity_catalog_utils.py +479 -0
- mlflow/utils/annotations.py +218 -0
- mlflow/utils/arguments_utils.py +16 -0
- mlflow/utils/async_logging/__init__.py +1 -0
- mlflow/utils/async_logging/async_artifacts_logging_queue.py +258 -0
- mlflow/utils/async_logging/async_logging_queue.py +366 -0
- mlflow/utils/async_logging/run_artifact.py +38 -0
- mlflow/utils/async_logging/run_batch.py +58 -0
- mlflow/utils/async_logging/run_operations.py +49 -0
- mlflow/utils/autologging_utils/__init__.py +737 -0
- mlflow/utils/autologging_utils/client.py +432 -0
- mlflow/utils/autologging_utils/config.py +33 -0
- mlflow/utils/autologging_utils/events.py +294 -0
- mlflow/utils/autologging_utils/logging_and_warnings.py +328 -0
- mlflow/utils/autologging_utils/metrics_queue.py +71 -0
- mlflow/utils/autologging_utils/safety.py +1104 -0
- mlflow/utils/autologging_utils/versioning.py +95 -0
- mlflow/utils/checkpoint_utils.py +206 -0
- mlflow/utils/class_utils.py +6 -0
- mlflow/utils/cli_args.py +257 -0
- mlflow/utils/conda.py +354 -0
- mlflow/utils/credentials.py +231 -0
- mlflow/utils/data_utils.py +17 -0
- mlflow/utils/databricks_utils.py +1436 -0
- mlflow/utils/docstring_utils.py +477 -0
- mlflow/utils/doctor.py +133 -0
- mlflow/utils/download_cloud_file_chunk.py +43 -0
- mlflow/utils/env_manager.py +16 -0
- mlflow/utils/env_pack.py +131 -0
- mlflow/utils/environment.py +1009 -0
- mlflow/utils/exception_utils.py +14 -0
- mlflow/utils/file_utils.py +978 -0
- mlflow/utils/git_utils.py +77 -0
- mlflow/utils/gorilla.py +797 -0
- mlflow/utils/import_hooks/__init__.py +363 -0
- mlflow/utils/lazy_load.py +51 -0
- mlflow/utils/logging_utils.py +168 -0
- mlflow/utils/mime_type_utils.py +58 -0
- mlflow/utils/mlflow_tags.py +103 -0
- mlflow/utils/model_utils.py +486 -0
- mlflow/utils/name_utils.py +346 -0
- mlflow/utils/nfs_on_spark.py +62 -0
- mlflow/utils/openai_utils.py +164 -0
- mlflow/utils/os.py +12 -0
- mlflow/utils/oss_registry_utils.py +29 -0
- mlflow/utils/plugins.py +17 -0
- mlflow/utils/process.py +182 -0
- mlflow/utils/promptlab_utils.py +146 -0
- mlflow/utils/proto_json_utils.py +743 -0
- mlflow/utils/pydantic_utils.py +54 -0
- mlflow/utils/request_utils.py +279 -0
- mlflow/utils/requirements_utils.py +704 -0
- mlflow/utils/rest_utils.py +673 -0
- mlflow/utils/search_logged_model_utils.py +127 -0
- mlflow/utils/search_utils.py +2111 -0
- mlflow/utils/secure_loading.py +221 -0
- mlflow/utils/security_validation.py +384 -0
- mlflow/utils/server_cli_utils.py +61 -0
- mlflow/utils/spark_utils.py +15 -0
- mlflow/utils/string_utils.py +138 -0
- mlflow/utils/thread_utils.py +63 -0
- mlflow/utils/time.py +54 -0
- mlflow/utils/timeout.py +42 -0
- mlflow/utils/uri.py +572 -0
- mlflow/utils/validation.py +662 -0
- mlflow/utils/virtualenv.py +458 -0
- mlflow/utils/warnings_utils.py +25 -0
- mlflow/utils/yaml_utils.py +179 -0
- mlflow/version.py +24 -0
mlflow/azure/utils.py
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
"""Utility functions for Azure authentication."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
import time
|
6
|
+
import logging
|
7
|
+
from datetime import datetime, timedelta
|
8
|
+
from typing import Any, Optional
|
9
|
+
from urllib.parse import parse_qs, urlparse
|
10
|
+
|
11
|
+
logger = logging.getLogger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
def is_token_expired(token_expiry: Optional[datetime], buffer_seconds: int = 300) -> bool:
|
15
|
+
"""Check if a token is expired or will expire within the buffer time.
|
16
|
+
|
17
|
+
Args:
|
18
|
+
token_expiry: Token expiration datetime
|
19
|
+
buffer_seconds: Buffer time in seconds before actual expiry
|
20
|
+
|
21
|
+
Returns:
|
22
|
+
True if token is expired or will expire soon
|
23
|
+
"""
|
24
|
+
if not token_expiry:
|
25
|
+
return True
|
26
|
+
|
27
|
+
buffer_time = timedelta(seconds=buffer_seconds)
|
28
|
+
return datetime.utcnow() + buffer_time >= token_expiry
|
29
|
+
|
30
|
+
|
31
|
+
def parse_connection_string(connection_string: str) -> dict[str, Any]:
|
32
|
+
"""Parse a PostgreSQL connection string and extract components.
|
33
|
+
|
34
|
+
Args:
|
35
|
+
connection_string: PostgreSQL connection string
|
36
|
+
|
37
|
+
Returns:
|
38
|
+
Dictionary with connection components
|
39
|
+
"""
|
40
|
+
# Handle azure-postgres:// scheme by converting to postgresql:// for parsing
|
41
|
+
original_scheme = connection_string.split("://")[0] if "://" in connection_string else "unknown"
|
42
|
+
if connection_string.startswith("azure-postgres://"):
|
43
|
+
connection_string = connection_string.replace("azure-postgres://", "postgresql://", 1)
|
44
|
+
|
45
|
+
parsed = urlparse(connection_string)
|
46
|
+
|
47
|
+
# Parse query parameters
|
48
|
+
query_params = {}
|
49
|
+
if parsed.query:
|
50
|
+
query_params = {k: v[0] if len(v) == 1 else v for k, v in parse_qs(parsed.query).items()}
|
51
|
+
|
52
|
+
return {
|
53
|
+
"scheme": original_scheme, # Use original scheme (azure-postgres or postgresql)
|
54
|
+
"username": parsed.username,
|
55
|
+
"password": parsed.password,
|
56
|
+
"hostname": parsed.hostname,
|
57
|
+
"port": parsed.port or 5432,
|
58
|
+
"database": parsed.path.lstrip("/") if parsed.path else "",
|
59
|
+
"params": query_params,
|
60
|
+
}
|
61
|
+
|
62
|
+
|
63
|
+
def build_connection_string(
|
64
|
+
username: str,
|
65
|
+
password: str,
|
66
|
+
hostname: str,
|
67
|
+
port: int = 5432,
|
68
|
+
database: str = "postgres",
|
69
|
+
**params: Any,
|
70
|
+
) -> str:
|
71
|
+
"""Build a PostgreSQL connection string.
|
72
|
+
|
73
|
+
Args:
|
74
|
+
username: Database username
|
75
|
+
password: Database password
|
76
|
+
hostname: Database hostname
|
77
|
+
port: Database port
|
78
|
+
database: Database name
|
79
|
+
**params: Additional connection parameters
|
80
|
+
|
81
|
+
Returns:
|
82
|
+
PostgreSQL connection string
|
83
|
+
"""
|
84
|
+
param_string = ""
|
85
|
+
if params:
|
86
|
+
param_string = "?" + "&".join(f"{k}={v}" for k, v in params.items())
|
87
|
+
|
88
|
+
return f"postgresql://{username}:{password}@{hostname}:{port}/{database}{param_string}"
|
89
|
+
|
90
|
+
|
91
|
+
def sanitize_connection_string_for_logging(connection_string: str) -> str:
|
92
|
+
"""Sanitize connection string for safe logging by removing sensitive information.
|
93
|
+
|
94
|
+
Args:
|
95
|
+
connection_string: Original connection string
|
96
|
+
|
97
|
+
Returns:
|
98
|
+
Sanitized connection string with password masked
|
99
|
+
"""
|
100
|
+
try:
|
101
|
+
parsed = parse_connection_string(connection_string)
|
102
|
+
|
103
|
+
# Mask password
|
104
|
+
masked_password = "***" if parsed.get("password") else None
|
105
|
+
|
106
|
+
# Rebuild without sensitive info
|
107
|
+
safe_parts = []
|
108
|
+
safe_parts.append(f"scheme={parsed.get('scheme', 'unknown')}")
|
109
|
+
safe_parts.append(f"host={parsed.get('hostname', 'unknown')}")
|
110
|
+
safe_parts.append(f"port={parsed.get('port', 5432)}")
|
111
|
+
safe_parts.append(f"database={parsed.get('database', 'unknown')}")
|
112
|
+
safe_parts.append(f"user={parsed.get('username', 'unknown')}")
|
113
|
+
|
114
|
+
if masked_password:
|
115
|
+
safe_parts.append("password=***")
|
116
|
+
|
117
|
+
return " | ".join(safe_parts)
|
118
|
+
|
119
|
+
except Exception as e:
|
120
|
+
logger.warning("Failed to sanitize connection string", extra={"error": str(e)})
|
121
|
+
return "connection_string=<unable_to_parse>"
|
122
|
+
|
123
|
+
|
124
|
+
def exponential_backoff(attempt: int, base_delay: float = 1.0, max_delay: float = 60.0) -> float:
|
125
|
+
"""Calculate exponential backoff delay.
|
126
|
+
|
127
|
+
Args:
|
128
|
+
attempt: Current attempt number (0-indexed)
|
129
|
+
base_delay: Base delay in seconds
|
130
|
+
max_delay: Maximum delay in seconds
|
131
|
+
|
132
|
+
Returns:
|
133
|
+
Delay in seconds
|
134
|
+
"""
|
135
|
+
delay = base_delay * (2**attempt)
|
136
|
+
return min(delay, max_delay)
|
137
|
+
|
138
|
+
|
139
|
+
def retry_on_exception(
|
140
|
+
func: callable,
|
141
|
+
max_retries: int = 3,
|
142
|
+
base_delay: float = 1.0,
|
143
|
+
exceptions: tuple = (Exception,),
|
144
|
+
) -> Any:
|
145
|
+
"""Retry a function with exponential backoff.
|
146
|
+
|
147
|
+
Args:
|
148
|
+
func: Function to retry
|
149
|
+
max_retries: Maximum number of retries
|
150
|
+
base_delay: Base delay between retries
|
151
|
+
exceptions: Exception types to catch and retry on
|
152
|
+
|
153
|
+
Returns:
|
154
|
+
Function result
|
155
|
+
|
156
|
+
Raises:
|
157
|
+
Last exception if all retries failed
|
158
|
+
"""
|
159
|
+
last_exception = None
|
160
|
+
|
161
|
+
for attempt in range(max_retries + 1):
|
162
|
+
try:
|
163
|
+
return func()
|
164
|
+
except exceptions as e:
|
165
|
+
last_exception = e
|
166
|
+
|
167
|
+
if attempt == max_retries:
|
168
|
+
logger.error(
|
169
|
+
"Function failed after all retries",
|
170
|
+
extra={"attempt": attempt, "max_retries": max_retries, "error": str(e)},
|
171
|
+
)
|
172
|
+
raise
|
173
|
+
|
174
|
+
delay = exponential_backoff(attempt, base_delay)
|
175
|
+
logger.warning(
|
176
|
+
"Function failed, retrying",
|
177
|
+
extra={"attempt": attempt, "delay": delay, "error": str(e)},
|
178
|
+
)
|
179
|
+
|
180
|
+
time.sleep(delay)
|
181
|
+
|
182
|
+
# This should never be reached
|
183
|
+
raise last_exception or Exception("Unexpected error in retry logic")
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
from mlflow.utils.annotations import experimental
|
4
|
+
from mlflow.utils.autologging_utils import autologging_integration, safe_patch
|
5
|
+
|
6
|
+
_logger = logging.getLogger(__name__)
|
7
|
+
|
8
|
+
FLAVOR_NAME = "bedrock"
|
9
|
+
|
10
|
+
|
11
|
+
@experimental(version="2.20.0")
|
12
|
+
@autologging_integration(FLAVOR_NAME)
|
13
|
+
def autolog(
|
14
|
+
log_traces: bool = True,
|
15
|
+
disable: bool = False,
|
16
|
+
silent: bool = False,
|
17
|
+
):
|
18
|
+
"""
|
19
|
+
Enables (or disables) and configures autologging from Amazon Bedrock to MLflow.
|
20
|
+
Only synchronous calls are supported. Asynchronous APIs and streaming are not recorded.
|
21
|
+
|
22
|
+
Args:
|
23
|
+
log_traces: If ``True``, traces are logged for Bedrock models.
|
24
|
+
If ``False``, no traces are collected during inference. Default to ``True``.
|
25
|
+
disable: If ``True``, disables the Bedrock autologging. Default to ``False``.
|
26
|
+
silent: If ``True``, suppress all event logs and warnings from MLflow during Bedrock
|
27
|
+
autologging. If ``False``, show all events and warnings.
|
28
|
+
"""
|
29
|
+
from botocore.client import ClientCreator
|
30
|
+
|
31
|
+
from mlflow.bedrock._autolog import patched_create_client
|
32
|
+
|
33
|
+
# NB: In boto3, the client class for each service is dynamically created at
|
34
|
+
# runtime via the ClientCreator factory class. Therefore, we cannot patch
|
35
|
+
# the service client directly, and instead patch the factory to return
|
36
|
+
# a patched client class.
|
37
|
+
safe_patch(FLAVOR_NAME, ClientCreator, "create_client", patched_create_client)
|
38
|
+
|
39
|
+
# Since we patch the ClientCreator factory, it only takes effect for new client instances.
|
40
|
+
if log_traces:
|
41
|
+
_logger.info(
|
42
|
+
"Enabled auto-tracing for Bedrock. Note that MLflow can only trace boto3 "
|
43
|
+
"service clients that are created after this call. If you have already "
|
44
|
+
"created one, please recreate the client by calling `boto3.client`."
|
45
|
+
)
|
@@ -0,0 +1,202 @@
|
|
1
|
+
import io
|
2
|
+
import json
|
3
|
+
import logging
|
4
|
+
from typing import Any, Optional, Union
|
5
|
+
|
6
|
+
from botocore.client import BaseClient
|
7
|
+
from botocore.response import StreamingBody
|
8
|
+
|
9
|
+
import mlflow
|
10
|
+
from mlflow.bedrock import FLAVOR_NAME
|
11
|
+
from mlflow.bedrock.chat import convert_message_to_mlflow_chat, convert_tool_to_mlflow_chat_tool
|
12
|
+
from mlflow.bedrock.stream import ConverseStreamWrapper, InvokeModelStreamWrapper
|
13
|
+
from mlflow.bedrock.utils import skip_if_trace_disabled
|
14
|
+
from mlflow.entities import SpanType
|
15
|
+
from mlflow.tracing.fluent import start_span_no_context
|
16
|
+
from mlflow.tracing.utils import set_span_chat_messages, set_span_chat_tools
|
17
|
+
from mlflow.utils.autologging_utils import safe_patch
|
18
|
+
|
19
|
+
_BEDROCK_RUNTIME_SERVICE_NAME = "bedrock-runtime"
|
20
|
+
_BEDROCK_SPAN_PREFIX = "BedrockRuntime."
|
21
|
+
|
22
|
+
_logger = logging.getLogger(__name__)
|
23
|
+
|
24
|
+
|
25
|
+
def patched_create_client(original, self, *args, **kwargs):
|
26
|
+
"""
|
27
|
+
Patched version of the boto3 ClientCreator.create_client method that returns
|
28
|
+
a patched client class.
|
29
|
+
"""
|
30
|
+
if kwargs.get("service_name") != _BEDROCK_RUNTIME_SERVICE_NAME:
|
31
|
+
return original(self, *args, **kwargs)
|
32
|
+
|
33
|
+
client = original(self, *args, **kwargs)
|
34
|
+
patch_bedrock_runtime_client(client.__class__)
|
35
|
+
|
36
|
+
return client
|
37
|
+
|
38
|
+
|
39
|
+
def patch_bedrock_runtime_client(client_class: type[BaseClient]):
|
40
|
+
"""
|
41
|
+
Patch the BedrockRuntime client to log traces and models.
|
42
|
+
"""
|
43
|
+
# The most basic model invocation API
|
44
|
+
safe_patch(FLAVOR_NAME, client_class, "invoke_model", _patched_invoke_model)
|
45
|
+
safe_patch(
|
46
|
+
FLAVOR_NAME,
|
47
|
+
client_class,
|
48
|
+
"invoke_model_with_response_stream",
|
49
|
+
_patched_invoke_model_with_response_stream,
|
50
|
+
)
|
51
|
+
|
52
|
+
if hasattr(client_class, "converse"):
|
53
|
+
# The new "converse" API was introduced in boto3 1.35 to access all models
|
54
|
+
# with the consistent chat format.
|
55
|
+
# https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock-runtime/client/converse.html
|
56
|
+
safe_patch(FLAVOR_NAME, client_class, "converse", _patched_converse)
|
57
|
+
|
58
|
+
if hasattr(client_class, "converse_stream"):
|
59
|
+
safe_patch(FLAVOR_NAME, client_class, "converse_stream", _patched_converse_stream)
|
60
|
+
|
61
|
+
|
62
|
+
@skip_if_trace_disabled
|
63
|
+
def _patched_invoke_model(original, self, *args, **kwargs):
|
64
|
+
with mlflow.start_span(name=f"{_BEDROCK_SPAN_PREFIX}{original.__name__}") as span:
|
65
|
+
# NB: Bedrock client doesn't accept any positional arguments
|
66
|
+
span.set_inputs(kwargs)
|
67
|
+
|
68
|
+
result = original(self, *args, **kwargs)
|
69
|
+
|
70
|
+
result["body"] = _buffer_stream(result["body"])
|
71
|
+
parsed_response_body = _parse_invoke_model_response_body(result["body"])
|
72
|
+
|
73
|
+
# Determine the span type based on the key in the response body.
|
74
|
+
# As of 2024 Dec 9th, all supported embedding models in Bedrock returns the response body
|
75
|
+
# with the key "embedding". This might change in the future.
|
76
|
+
span_type = SpanType.EMBEDDING if "embedding" in parsed_response_body else SpanType.LLM
|
77
|
+
span.set_span_type(span_type)
|
78
|
+
span.set_outputs({**result, "body": parsed_response_body})
|
79
|
+
|
80
|
+
return result
|
81
|
+
|
82
|
+
|
83
|
+
@skip_if_trace_disabled
|
84
|
+
def _patched_invoke_model_with_response_stream(original, self, *args, **kwargs):
|
85
|
+
span = start_span_no_context(
|
86
|
+
name=f"{_BEDROCK_SPAN_PREFIX}{original.__name__}",
|
87
|
+
# NB: Since we don't inspect the response body for this method, the span type is unknown.
|
88
|
+
# We assume it is LLM as using streaming for embedding is not common.
|
89
|
+
span_type=SpanType.LLM,
|
90
|
+
inputs=kwargs,
|
91
|
+
)
|
92
|
+
|
93
|
+
result = original(self, *args, **kwargs)
|
94
|
+
|
95
|
+
# To avoid consuming the stream during serialization, set dummy outputs for the span.
|
96
|
+
span.set_outputs({**result, "body": "EventStream"})
|
97
|
+
|
98
|
+
result["body"] = InvokeModelStreamWrapper(stream=result["body"], span=span)
|
99
|
+
return result
|
100
|
+
|
101
|
+
|
102
|
+
def _buffer_stream(raw_stream: StreamingBody) -> StreamingBody:
|
103
|
+
"""
|
104
|
+
Create a buffered stream from the raw byte stream.
|
105
|
+
|
106
|
+
The boto3's invoke_model() API returns the LLM response as a byte stream.
|
107
|
+
We need to read the stream data to set the span outputs, however, the stream
|
108
|
+
can only be read once and not seekable (https://github.com/boto/boto3/issues/564).
|
109
|
+
To work around this, we create a buffered stream that can be read multiple times.
|
110
|
+
"""
|
111
|
+
buffered_response = io.BytesIO(raw_stream.read())
|
112
|
+
buffered_response.seek(0)
|
113
|
+
return StreamingBody(buffered_response, raw_stream._content_length)
|
114
|
+
|
115
|
+
|
116
|
+
def _parse_invoke_model_response_body(response_body: StreamingBody) -> Union[dict[str, Any], str]:
|
117
|
+
content = response_body.read()
|
118
|
+
try:
|
119
|
+
return json.loads(content)
|
120
|
+
except Exception:
|
121
|
+
# When failed to parse the response body as JSON, return the raw response
|
122
|
+
return content
|
123
|
+
finally:
|
124
|
+
# Reset the stream position to the beginning
|
125
|
+
response_body._raw_stream.seek(0)
|
126
|
+
# Boto3 uses this attribute to validate the amount of data read from the stream matches
|
127
|
+
# the content length, so we need to reset it as well.
|
128
|
+
# https://github.com/boto/botocore/blob/f88e981cb1a6cd0c64bc89da262ab76f9bfa9b7d/botocore/response.py#L164C17-L164C32
|
129
|
+
response_body._amount_read = 0
|
130
|
+
|
131
|
+
|
132
|
+
@skip_if_trace_disabled
|
133
|
+
def _patched_converse(original, self, *args, **kwargs):
|
134
|
+
with mlflow.start_span(
|
135
|
+
name=f"{_BEDROCK_SPAN_PREFIX}{original.__name__}",
|
136
|
+
span_type=SpanType.CHAT_MODEL,
|
137
|
+
) as span:
|
138
|
+
# NB: Bedrock client doesn't accept any positional arguments
|
139
|
+
span.set_inputs(kwargs)
|
140
|
+
_set_tool_attributes(span, kwargs)
|
141
|
+
|
142
|
+
result = None
|
143
|
+
try:
|
144
|
+
result = original(self, *args, **kwargs)
|
145
|
+
span.set_outputs(result)
|
146
|
+
finally:
|
147
|
+
_set_chat_messages_attributes(span, kwargs.get("messages", []), result)
|
148
|
+
return result
|
149
|
+
|
150
|
+
|
151
|
+
@skip_if_trace_disabled
|
152
|
+
def _patched_converse_stream(original, self, *args, **kwargs):
|
153
|
+
# NB: Do not use fluent API to create a span for streaming response. If we do so,
|
154
|
+
# the span context will remain active until the stream is fully exhausted, which
|
155
|
+
# can lead to super hard-to-debug issues.
|
156
|
+
span = start_span_no_context(
|
157
|
+
name=f"{_BEDROCK_SPAN_PREFIX}{original.__name__}",
|
158
|
+
span_type=SpanType.CHAT_MODEL,
|
159
|
+
inputs=kwargs,
|
160
|
+
)
|
161
|
+
_set_tool_attributes(span, kwargs)
|
162
|
+
|
163
|
+
result = original(self, *args, **kwargs)
|
164
|
+
|
165
|
+
if span:
|
166
|
+
result["stream"] = ConverseStreamWrapper(
|
167
|
+
stream=result["stream"],
|
168
|
+
span=span,
|
169
|
+
inputs=kwargs,
|
170
|
+
)
|
171
|
+
|
172
|
+
return result
|
173
|
+
|
174
|
+
|
175
|
+
def _set_chat_messages_attributes(
|
176
|
+
span, messages: list[dict[str, Any]], response: Optional[dict[str, Any]]
|
177
|
+
):
|
178
|
+
"""
|
179
|
+
Extract standard chat span attributes for the Bedrock Converse API call.
|
180
|
+
|
181
|
+
NB: We only support standard attribute extraction for the Converse API, because
|
182
|
+
the InvokeModel API exposes the raw API spec from each LLM provider, hence
|
183
|
+
maintaining the compatibility for all providers is significantly cumbersome.
|
184
|
+
"""
|
185
|
+
try:
|
186
|
+
messages = [*messages] # shallow copy to avoid appending to the original list
|
187
|
+
if response:
|
188
|
+
messages.append(response["output"]["message"])
|
189
|
+
messages = [convert_message_to_mlflow_chat(msg) for msg in messages]
|
190
|
+
set_span_chat_messages(span, messages)
|
191
|
+
except Exception as e:
|
192
|
+
_logger.debug(f"Failed to set messages for {span}. Error: {e}")
|
193
|
+
|
194
|
+
|
195
|
+
def _set_tool_attributes(span, kwargs):
|
196
|
+
"""Extract tool attributes for the Bedrock Converse API call."""
|
197
|
+
if tool_config := kwargs.get("toolConfig"):
|
198
|
+
try:
|
199
|
+
tools = [convert_tool_to_mlflow_chat_tool(tool) for tool in tool_config["tools"]]
|
200
|
+
set_span_chat_tools(span, tools)
|
201
|
+
except Exception as e:
|
202
|
+
_logger.debug(f"Failed to set tools for {span}. Error: {e}")
|
mlflow/bedrock/chat.py
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
import base64
|
2
|
+
import json
|
3
|
+
import logging
|
4
|
+
from typing import Any, Optional, Union
|
5
|
+
|
6
|
+
from mlflow.types.chat import (
|
7
|
+
ChatMessage,
|
8
|
+
ChatTool,
|
9
|
+
Function,
|
10
|
+
FunctionToolDefinition,
|
11
|
+
ImageContentPart,
|
12
|
+
ImageUrl,
|
13
|
+
TextContentPart,
|
14
|
+
ToolCall,
|
15
|
+
)
|
16
|
+
|
17
|
+
_logger = logging.getLogger(__name__)
|
18
|
+
|
19
|
+
|
20
|
+
def convert_message_to_mlflow_chat(message: dict[str, Any]) -> ChatMessage:
|
21
|
+
"""
|
22
|
+
Convert Bedrock Converse API's message object into MLflow's standard format (OpenAI compatible).
|
23
|
+
|
24
|
+
Ref: https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Message.html
|
25
|
+
|
26
|
+
Args:
|
27
|
+
message: Bedrock Converse API's message object.
|
28
|
+
|
29
|
+
Returns:
|
30
|
+
ChatMessage: MLflow's standard chat message object.
|
31
|
+
"""
|
32
|
+
role = message["role"]
|
33
|
+
contents = []
|
34
|
+
tool_calls = []
|
35
|
+
tool_call_id = None
|
36
|
+
for content in message["content"]:
|
37
|
+
if tool_call := content.get("toolUse"):
|
38
|
+
input = tool_call.get("input")
|
39
|
+
tool_calls.append(
|
40
|
+
ToolCall(
|
41
|
+
id=tool_call["toolUseId"],
|
42
|
+
function=Function(
|
43
|
+
name=tool_call["name"],
|
44
|
+
arguments=input if isinstance(input, str) else json.dumps(input),
|
45
|
+
),
|
46
|
+
type="function",
|
47
|
+
)
|
48
|
+
)
|
49
|
+
elif tool_result := content.get("toolResult"):
|
50
|
+
tool_call_id = tool_result["toolUseId"]
|
51
|
+
# "tool_result" content corresponds to the "tool" message in OpenAI.
|
52
|
+
# https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ToolResultContentBlock.html
|
53
|
+
role = "tool"
|
54
|
+
for content in tool_result["content"]:
|
55
|
+
parsed_content = _parse_content(content)
|
56
|
+
if parsed_content:
|
57
|
+
contents.append(parsed_content)
|
58
|
+
else:
|
59
|
+
parsed_content = _parse_content(content)
|
60
|
+
if parsed_content:
|
61
|
+
contents.append(parsed_content)
|
62
|
+
|
63
|
+
message = ChatMessage(role=role, content=contents)
|
64
|
+
if tool_calls:
|
65
|
+
message.tool_calls = tool_calls
|
66
|
+
if tool_call_id:
|
67
|
+
message.tool_call_id = tool_call_id
|
68
|
+
return message
|
69
|
+
|
70
|
+
|
71
|
+
def _parse_content(content: dict[str, Any]) -> Optional[Union[TextContentPart, ImageContentPart]]:
|
72
|
+
"""
|
73
|
+
Parse a single content block in the Bedrock message object.
|
74
|
+
|
75
|
+
Some content types like video and document are not supported by OpenAI's spec. This
|
76
|
+
function returns None for those content types.
|
77
|
+
|
78
|
+
Ref: https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ContentBlock.html
|
79
|
+
"""
|
80
|
+
if text := content.get("text"):
|
81
|
+
return TextContentPart(text=text, type="text")
|
82
|
+
elif json_content := content.get("json"):
|
83
|
+
return TextContentPart(text=json.dumps(json_content), type="text")
|
84
|
+
elif image := content.get("image"):
|
85
|
+
# Bedrock support passing images in both raw bytes and base64 encoded strings.
|
86
|
+
# OpenAI spec only supports base64 encoded images, so we encode the raw bytes to base64.
|
87
|
+
# https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ImageBlock.html
|
88
|
+
image_bytes = image["source"]["bytes"]
|
89
|
+
if isinstance(image_bytes, bytes):
|
90
|
+
data = base64.b64encode(image_bytes).decode("utf-8")
|
91
|
+
else:
|
92
|
+
data = image_bytes
|
93
|
+
format = "image/" + image["format"]
|
94
|
+
image_url = ImageUrl(url=f"data:{format};base64,{data}", detail="auto")
|
95
|
+
return ImageContentPart(type="image_url", image_url=image_url)
|
96
|
+
# NB: Video and Document content type are not supported by OpenAI's spec, so recording as text.
|
97
|
+
else:
|
98
|
+
_logger.debug(f"Received an unsupported content type: {list(content.keys())[0]}")
|
99
|
+
return None
|
100
|
+
|
101
|
+
|
102
|
+
def convert_tool_to_mlflow_chat_tool(tool: dict[str, Any]) -> ChatTool:
|
103
|
+
"""
|
104
|
+
Convert Bedrock tool definition into MLflow's standard format (OpenAI compatible).
|
105
|
+
|
106
|
+
Ref: https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Tool.html
|
107
|
+
|
108
|
+
Args:
|
109
|
+
tool: A dictionary represents a single tool definition in the input request.
|
110
|
+
|
111
|
+
Returns:
|
112
|
+
ChatTool: MLflow's standard tool definition object.
|
113
|
+
"""
|
114
|
+
tool_spec = tool["toolSpec"]
|
115
|
+
return ChatTool(
|
116
|
+
type="function",
|
117
|
+
function=FunctionToolDefinition(
|
118
|
+
name=tool_spec["name"],
|
119
|
+
description=tool_spec.get("description"),
|
120
|
+
parameters=tool_spec["inputSchema"].get("json"),
|
121
|
+
),
|
122
|
+
)
|