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
@@ -0,0 +1,301 @@
|
|
1
|
+
import posixpath
|
2
|
+
from abc import ABC, abstractmethod
|
3
|
+
from dataclasses import dataclass, field
|
4
|
+
from enum import Enum
|
5
|
+
from typing import Any, Callable, Optional
|
6
|
+
|
7
|
+
from mlflow.entities.file_info import FileInfo
|
8
|
+
from mlflow.protos.databricks_artifacts_pb2 import (
|
9
|
+
DatabricksMlflowArtifactsService,
|
10
|
+
GetCredentialsForLoggedModelDownload,
|
11
|
+
GetCredentialsForLoggedModelUpload,
|
12
|
+
GetCredentialsForRead,
|
13
|
+
GetCredentialsForTraceDataDownload,
|
14
|
+
GetCredentialsForTraceDataUpload,
|
15
|
+
GetCredentialsForWrite,
|
16
|
+
)
|
17
|
+
from mlflow.protos.service_pb2 import (
|
18
|
+
GetLoggedModel,
|
19
|
+
GetRun,
|
20
|
+
ListArtifacts,
|
21
|
+
ListLoggedModelArtifacts,
|
22
|
+
MlflowService,
|
23
|
+
)
|
24
|
+
from mlflow.utils.proto_json_utils import message_to_json
|
25
|
+
from mlflow.utils.uri import extract_and_normalize_path
|
26
|
+
|
27
|
+
|
28
|
+
class _CredentialType(Enum):
|
29
|
+
READ = 1
|
30
|
+
WRITE = 2
|
31
|
+
|
32
|
+
|
33
|
+
@dataclass
|
34
|
+
class HttpHeader:
|
35
|
+
name: str
|
36
|
+
value: str
|
37
|
+
|
38
|
+
|
39
|
+
@dataclass
|
40
|
+
class ArtifactCredentialInfo:
|
41
|
+
signed_uri: str
|
42
|
+
type: Any
|
43
|
+
headers: list[HttpHeader] = field(default_factory=list)
|
44
|
+
|
45
|
+
|
46
|
+
@dataclass
|
47
|
+
class ListArtifactsPage:
|
48
|
+
# List of files in the current page
|
49
|
+
files: list[FileInfo]
|
50
|
+
# Token to fetch the next page of files
|
51
|
+
next_page_token: Optional[str] = None
|
52
|
+
|
53
|
+
@classmethod
|
54
|
+
def empty(cls):
|
55
|
+
return cls(files=[], next_page_token=None)
|
56
|
+
|
57
|
+
|
58
|
+
class _Resource(ABC):
|
59
|
+
"""
|
60
|
+
Represents a resource that `DatabricksArtifactRepository` interacts with.
|
61
|
+
"""
|
62
|
+
|
63
|
+
def __init__(self, id_: str, artifact_uri: str, call_endpoint: Callable[..., Any]):
|
64
|
+
self.id = id_
|
65
|
+
self.artifact_uri = artifact_uri
|
66
|
+
self._call_endpoint = call_endpoint
|
67
|
+
self._artifact_root = None
|
68
|
+
self._relative_path = None
|
69
|
+
|
70
|
+
@property
|
71
|
+
def call_endpoint(self) -> Callable[..., Any]:
|
72
|
+
return self._call_endpoint
|
73
|
+
|
74
|
+
@property
|
75
|
+
def artifact_root(self) -> str:
|
76
|
+
if self._artifact_root is None:
|
77
|
+
self._artifact_root = self.get_artifact_root()
|
78
|
+
return self._artifact_root
|
79
|
+
|
80
|
+
@property
|
81
|
+
def relative_path(self) -> str:
|
82
|
+
if self._relative_path is None:
|
83
|
+
# Fetch the artifact root for the MLflow resource associated with `artifact_uri` and
|
84
|
+
# compute the path of `artifact_uri` relative to the MLflow resource's artifact root
|
85
|
+
# All operations performed on this artifact repository will be performed relative to
|
86
|
+
# this computed location.
|
87
|
+
artifact_repo_root_path = extract_and_normalize_path(self.artifact_uri)
|
88
|
+
artifact_root_path = extract_and_normalize_path(self.artifact_root)
|
89
|
+
# If the paths are equal, then use empty string over "./" for ListArtifact compatibility
|
90
|
+
self._relative_path = (
|
91
|
+
""
|
92
|
+
if artifact_root_path == artifact_repo_root_path
|
93
|
+
else posixpath.relpath(artifact_repo_root_path, artifact_root_path)
|
94
|
+
)
|
95
|
+
return self._relative_path
|
96
|
+
|
97
|
+
@abstractmethod
|
98
|
+
def get_credentials(
|
99
|
+
self,
|
100
|
+
cred_type: _CredentialType,
|
101
|
+
paths: Optional[list[str]] = None,
|
102
|
+
page_token: Optional[str] = None,
|
103
|
+
) -> tuple[list[ArtifactCredentialInfo], Optional[str]]:
|
104
|
+
"""
|
105
|
+
Fetches read/write credentials for the specified paths.
|
106
|
+
"""
|
107
|
+
|
108
|
+
@abstractmethod
|
109
|
+
def get_artifact_root(self) -> str:
|
110
|
+
"""
|
111
|
+
Get the artifact root URI of this resource.
|
112
|
+
"""
|
113
|
+
|
114
|
+
@abstractmethod
|
115
|
+
def _list_artifacts(
|
116
|
+
self,
|
117
|
+
path: Optional[str] = None,
|
118
|
+
page_token: Optional[str] = None,
|
119
|
+
) -> ListArtifactsPage:
|
120
|
+
"""
|
121
|
+
List artifacts under the specified path.
|
122
|
+
"""
|
123
|
+
|
124
|
+
def list_artifacts(self, path: Optional[str] = None) -> list[FileInfo]:
|
125
|
+
"""
|
126
|
+
Handle pagination and return all artifacts under the specified path.
|
127
|
+
"""
|
128
|
+
files: list[FileInfo] = []
|
129
|
+
page_token: Optional[str] = None
|
130
|
+
while True:
|
131
|
+
page = self._list_artifacts(path, page_token)
|
132
|
+
files.extend(page.files)
|
133
|
+
if len(page.files) == 0 or not page.next_page_token:
|
134
|
+
break
|
135
|
+
page_token = page.next_page_token
|
136
|
+
|
137
|
+
return files
|
138
|
+
|
139
|
+
|
140
|
+
class _LoggedModel(_Resource):
|
141
|
+
def get_credentials(
|
142
|
+
self,
|
143
|
+
cred_type: _CredentialType,
|
144
|
+
paths: Optional[list[str]] = None,
|
145
|
+
page_token: Optional[str] = None,
|
146
|
+
) -> tuple[list[ArtifactCredentialInfo], Optional[str]]:
|
147
|
+
api = (
|
148
|
+
GetCredentialsForLoggedModelDownload
|
149
|
+
if cred_type == _CredentialType.READ
|
150
|
+
else GetCredentialsForLoggedModelUpload
|
151
|
+
)
|
152
|
+
payload = api(paths=paths, page_token=page_token)
|
153
|
+
response = self.call_endpoint(
|
154
|
+
DatabricksMlflowArtifactsService,
|
155
|
+
api,
|
156
|
+
message_to_json(payload),
|
157
|
+
path_params={"model_id": self.id},
|
158
|
+
)
|
159
|
+
credential_infos = [
|
160
|
+
ArtifactCredentialInfo(
|
161
|
+
signed_uri=c.credential_info.signed_uri,
|
162
|
+
type=c.credential_info.type,
|
163
|
+
headers=[HttpHeader(name=h.name, value=h.value) for h in c.credential_info.headers],
|
164
|
+
)
|
165
|
+
for c in response.credentials
|
166
|
+
]
|
167
|
+
return credential_infos, response.next_page_token
|
168
|
+
|
169
|
+
def get_artifact_root(self) -> str:
|
170
|
+
json_body = message_to_json(GetLoggedModel(model_id=self.id))
|
171
|
+
response = self.call_endpoint(
|
172
|
+
MlflowService, GetLoggedModel, json_body, path_params={"model_id": self.id}
|
173
|
+
)
|
174
|
+
return response.model.info.artifact_uri
|
175
|
+
|
176
|
+
def _list_artifacts(
|
177
|
+
self,
|
178
|
+
path: Optional[str] = None,
|
179
|
+
page_token: Optional[str] = None,
|
180
|
+
) -> ListArtifactsPage:
|
181
|
+
path = posixpath.join(self.relative_path, path) if path else self.relative_path
|
182
|
+
json_body = message_to_json(
|
183
|
+
ListLoggedModelArtifacts(page_token=page_token, artifact_directory_path=path)
|
184
|
+
)
|
185
|
+
response = self.call_endpoint(
|
186
|
+
MlflowService, ListLoggedModelArtifacts, json_body, path_params={"model_id": self.id}
|
187
|
+
)
|
188
|
+
files = response.files
|
189
|
+
# If `path` is a file, ListLoggedModelArtifacts returns a single list element with the
|
190
|
+
# same name as `path`. The list_artifacts API expects us to return an empty list in this
|
191
|
+
# case, so we do so here.
|
192
|
+
if len(files) == 1 and files[0].path == path and not files[0].is_dir:
|
193
|
+
return ListArtifactsPage.empty()
|
194
|
+
|
195
|
+
return ListArtifactsPage(
|
196
|
+
files=[
|
197
|
+
FileInfo(
|
198
|
+
posixpath.relpath(f.path, self.relative_path),
|
199
|
+
f.is_dir,
|
200
|
+
None if f.is_dir else f.file_size,
|
201
|
+
)
|
202
|
+
for f in files
|
203
|
+
],
|
204
|
+
next_page_token=response.next_page_token,
|
205
|
+
)
|
206
|
+
|
207
|
+
|
208
|
+
class _Run(_Resource):
|
209
|
+
def get_credentials(
|
210
|
+
self,
|
211
|
+
cred_type: _CredentialType,
|
212
|
+
paths: Optional[list[str]] = None,
|
213
|
+
page_token: Optional[str] = None,
|
214
|
+
) -> tuple[list[ArtifactCredentialInfo], Optional[str]]:
|
215
|
+
api = GetCredentialsForRead if cred_type == _CredentialType.READ else GetCredentialsForWrite
|
216
|
+
json_body = api(run_id=self.id, path=paths, page_token=page_token)
|
217
|
+
response = self.call_endpoint(
|
218
|
+
DatabricksMlflowArtifactsService, api, message_to_json(json_body)
|
219
|
+
)
|
220
|
+
credential_infos = [
|
221
|
+
ArtifactCredentialInfo(
|
222
|
+
signed_uri=c.signed_uri,
|
223
|
+
type=c.type,
|
224
|
+
headers=[HttpHeader(name=h.name, value=h.value) for h in c.headers],
|
225
|
+
)
|
226
|
+
for c in response.credential_infos
|
227
|
+
]
|
228
|
+
return credential_infos, response.next_page_token
|
229
|
+
|
230
|
+
def get_artifact_root(self) -> str:
|
231
|
+
json_body = message_to_json(GetRun(run_id=self.id))
|
232
|
+
run_response = self.call_endpoint(MlflowService, GetRun, json_body)
|
233
|
+
return run_response.run.info.artifact_uri
|
234
|
+
|
235
|
+
def _list_artifacts(
|
236
|
+
self,
|
237
|
+
path: Optional[str] = None,
|
238
|
+
page_token: Optional[str] = None,
|
239
|
+
) -> ListArtifactsPage:
|
240
|
+
path = posixpath.join(self.relative_path, path) if path else self.relative_path
|
241
|
+
json_body = message_to_json(
|
242
|
+
ListArtifacts(run_id=self.id, path=path, page_token=page_token),
|
243
|
+
)
|
244
|
+
response = self.call_endpoint(MlflowService, ListArtifacts, json_body)
|
245
|
+
files = response.files
|
246
|
+
# If `path` is a file, ListArtifacts returns a single list element with the
|
247
|
+
# same name as `path`. The list_artifacts API expects us to return an empty list in this
|
248
|
+
# case, so we do so here.
|
249
|
+
if len(files) == 1 and files[0].path == path and not files[0].is_dir:
|
250
|
+
return ListArtifactsPage.empty()
|
251
|
+
|
252
|
+
return ListArtifactsPage(
|
253
|
+
files=[
|
254
|
+
FileInfo(
|
255
|
+
posixpath.relpath(f.path, self.relative_path),
|
256
|
+
f.is_dir,
|
257
|
+
None if f.is_dir else f.file_size,
|
258
|
+
)
|
259
|
+
for f in files
|
260
|
+
],
|
261
|
+
next_page_token=response.next_page_token,
|
262
|
+
)
|
263
|
+
|
264
|
+
|
265
|
+
class _Trace(_Resource):
|
266
|
+
def get_artifact_root(self) -> str:
|
267
|
+
return None
|
268
|
+
|
269
|
+
def get_credentials(
|
270
|
+
self,
|
271
|
+
cred_type: _CredentialType,
|
272
|
+
paths: Optional[list[str]] = None,
|
273
|
+
page_token: Optional[str] = None,
|
274
|
+
timeout: Optional[int] = None,
|
275
|
+
) -> tuple[list[ArtifactCredentialInfo], Optional[str]]:
|
276
|
+
res = self.call_endpoint(
|
277
|
+
DatabricksMlflowArtifactsService,
|
278
|
+
(
|
279
|
+
GetCredentialsForTraceDataDownload
|
280
|
+
if cred_type == _CredentialType.READ
|
281
|
+
else GetCredentialsForTraceDataUpload
|
282
|
+
),
|
283
|
+
path_params={"request_id": self.id},
|
284
|
+
retry_timeout_seconds=timeout,
|
285
|
+
)
|
286
|
+
cred_inf = ArtifactCredentialInfo(
|
287
|
+
signed_uri=res.credential_info.signed_uri,
|
288
|
+
type=res.credential_info.type,
|
289
|
+
headers=[HttpHeader(name=h.name, value=h.value) for h in res.credential_info.headers],
|
290
|
+
)
|
291
|
+
return [cred_inf], None
|
292
|
+
|
293
|
+
def get_artifact_root(self) -> str:
|
294
|
+
raise NotImplementedError
|
295
|
+
|
296
|
+
def _list_artifacts(
|
297
|
+
self,
|
298
|
+
path: Optional[str] = None,
|
299
|
+
page_token: Optional[str] = None,
|
300
|
+
) -> ListArtifactsPage:
|
301
|
+
raise NotImplementedError
|
@@ -0,0 +1,93 @@
|
|
1
|
+
import logging
|
2
|
+
import re
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
from mlflow.entities import FileInfo
|
6
|
+
from mlflow.exceptions import MlflowException
|
7
|
+
from mlflow.store.artifact.artifact_repo import ArtifactRepository
|
8
|
+
from mlflow.store.artifact.databricks_artifact_repo import DatabricksArtifactRepository
|
9
|
+
from mlflow.store.artifact.databricks_sdk_artifact_repo import DatabricksSdkArtifactRepository
|
10
|
+
|
11
|
+
_logger = logging.getLogger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
_FALLBACK_MESSAGE_TEMPLATE = (
|
15
|
+
"Failed to perform {operation} operation using Databricks SDK, falling back to "
|
16
|
+
"DatabricksArtifactRepository. Original error: %s"
|
17
|
+
)
|
18
|
+
|
19
|
+
|
20
|
+
class DatabricksLoggedModelArtifactRepository(ArtifactRepository):
|
21
|
+
"""
|
22
|
+
Artifact repository for interacting with logged model artifacts in a Databricks workspace.
|
23
|
+
If operations using the Databricks SDK fail for any reason, this repository automatically
|
24
|
+
falls back to using the `DatabricksArtifactRepository`, ensuring operational resilience.
|
25
|
+
"""
|
26
|
+
|
27
|
+
# Matches URIs of the form:
|
28
|
+
# databricks/mlflow-tracking/<experiment_id>/logged_models/<model_id>/<relative_path>
|
29
|
+
_URI_REGEX = re.compile(
|
30
|
+
r"databricks/mlflow-tracking/(?P<experiment_id>[^/]+)/logged_models/(?P<model_id>[^/]+)(?P<relative_path>/.*)?$"
|
31
|
+
)
|
32
|
+
|
33
|
+
def __init__(self, artifact_uri: str, tracking_uri: Optional[str] = None) -> None:
|
34
|
+
super().__init__(artifact_uri, tracking_uri)
|
35
|
+
m = self._URI_REGEX.search(artifact_uri)
|
36
|
+
if not m:
|
37
|
+
raise MlflowException.invalid_parameter_value(
|
38
|
+
f"Invalid artifact URI: {artifact_uri}. Expected URI of the form "
|
39
|
+
f"databricks/mlflow-tracking/<EXP_ID>/logged_models/<MODEL_ID>"
|
40
|
+
)
|
41
|
+
experiment_id = m.group("experiment_id")
|
42
|
+
model_id = m.group("model_id")
|
43
|
+
relative_path = m.group("relative_path") or ""
|
44
|
+
root_path = (
|
45
|
+
f"/WorkspaceInternal/Mlflow/Artifacts/{experiment_id}/LoggedModels/{model_id}"
|
46
|
+
f"{relative_path}"
|
47
|
+
)
|
48
|
+
self.databricks_sdk_repo = DatabricksSdkArtifactRepository(root_path)
|
49
|
+
self.databricks_artifact_repo = DatabricksArtifactRepository(artifact_uri)
|
50
|
+
|
51
|
+
@staticmethod
|
52
|
+
def is_logged_model_uri(artifact_uri: str) -> bool:
|
53
|
+
return bool(DatabricksLoggedModelArtifactRepository._URI_REGEX.search(artifact_uri))
|
54
|
+
|
55
|
+
def log_artifact(self, local_file: str, artifact_path: Optional[str] = None) -> None:
|
56
|
+
try:
|
57
|
+
self.databricks_sdk_repo.log_artifact(local_file, artifact_path)
|
58
|
+
except Exception as e:
|
59
|
+
_logger.debug(
|
60
|
+
_FALLBACK_MESSAGE_TEMPLATE.format(operation="log_artifact") % str(e),
|
61
|
+
exc_info=True,
|
62
|
+
)
|
63
|
+
self.databricks_artifact_repo.log_artifact(local_file, artifact_path)
|
64
|
+
|
65
|
+
def log_artifacts(self, local_dir: str, artifact_path: Optional[str] = None) -> None:
|
66
|
+
try:
|
67
|
+
self.databricks_sdk_repo.log_artifacts(local_dir, artifact_path)
|
68
|
+
except Exception as e:
|
69
|
+
_logger.debug(
|
70
|
+
_FALLBACK_MESSAGE_TEMPLATE.format(operation="log_artifacts") % str(e),
|
71
|
+
exc_info=True,
|
72
|
+
)
|
73
|
+
self.databricks_artifact_repo.log_artifacts(local_dir, artifact_path)
|
74
|
+
|
75
|
+
def list_artifacts(self, path: Optional[str] = None) -> list[FileInfo]:
|
76
|
+
try:
|
77
|
+
return self.databricks_sdk_repo.list_artifacts(path)
|
78
|
+
except Exception as e:
|
79
|
+
_logger.debug(
|
80
|
+
_FALLBACK_MESSAGE_TEMPLATE.format(operation="list_artifacts") % str(e),
|
81
|
+
exc_info=True,
|
82
|
+
)
|
83
|
+
return self.databricks_artifact_repo.list_artifacts(path)
|
84
|
+
|
85
|
+
def _download_file(self, remote_file_path: str, local_path: str) -> None:
|
86
|
+
try:
|
87
|
+
self.databricks_sdk_repo._download_file(remote_file_path, local_path)
|
88
|
+
except Exception as e:
|
89
|
+
_logger.debug(
|
90
|
+
_FALLBACK_MESSAGE_TEMPLATE.format(operation="download_file") % str(e),
|
91
|
+
exc_info=True,
|
92
|
+
)
|
93
|
+
self.databricks_artifact_repo._download_file(remote_file_path, local_path)
|
@@ -0,0 +1,216 @@
|
|
1
|
+
import json
|
2
|
+
import logging
|
3
|
+
import os
|
4
|
+
import posixpath
|
5
|
+
from typing import Optional
|
6
|
+
|
7
|
+
import mlflow.tracking
|
8
|
+
from mlflow.entities import FileInfo
|
9
|
+
from mlflow.environment_variables import (
|
10
|
+
MLFLOW_ENABLE_MULTIPART_DOWNLOAD,
|
11
|
+
MLFLOW_MULTIPART_DOWNLOAD_CHUNK_SIZE,
|
12
|
+
)
|
13
|
+
from mlflow.exceptions import MlflowException
|
14
|
+
from mlflow.protos.databricks_pb2 import INVALID_PARAMETER_VALUE
|
15
|
+
from mlflow.store.artifact.artifact_repo import ArtifactRepository
|
16
|
+
from mlflow.store.artifact.utils.models import (
|
17
|
+
get_model_name_and_version,
|
18
|
+
is_using_databricks_registry,
|
19
|
+
)
|
20
|
+
from mlflow.utils.databricks_utils import (
|
21
|
+
get_databricks_host_creds,
|
22
|
+
warn_on_deprecated_cross_workspace_registry_uri,
|
23
|
+
)
|
24
|
+
from mlflow.utils.file_utils import (
|
25
|
+
download_chunk_retries,
|
26
|
+
download_file_using_http_uri,
|
27
|
+
parallelized_download_file_using_http_uri,
|
28
|
+
remove_on_error,
|
29
|
+
)
|
30
|
+
from mlflow.utils.rest_utils import http_request
|
31
|
+
from mlflow.utils.uri import get_databricks_profile_uri_from_artifact_uri
|
32
|
+
|
33
|
+
_logger = logging.getLogger(__name__)
|
34
|
+
# The constant REGISTRY_LIST_ARTIFACT_ENDPOINT is defined as @developer_stable
|
35
|
+
REGISTRY_LIST_ARTIFACTS_ENDPOINT = "/api/2.0/mlflow/model-versions/list-artifacts"
|
36
|
+
# The constant REGISTRY_ARTIFACT_PRESIGNED_URI_ENDPOINT is defined as @developer_stable
|
37
|
+
REGISTRY_ARTIFACT_PRESIGNED_URI_ENDPOINT = "/api/2.0/mlflow/model-versions/get-signed-download-uri"
|
38
|
+
|
39
|
+
|
40
|
+
class DatabricksModelsArtifactRepository(ArtifactRepository):
|
41
|
+
"""
|
42
|
+
Performs storage operations on artifacts controlled by a Databricks-hosted model registry.
|
43
|
+
|
44
|
+
Signed access URIs for the appropriate cloud storage locations are fetched from the
|
45
|
+
MLflow service and used to download model artifacts.
|
46
|
+
|
47
|
+
The artifact_uri is expected to be of the form
|
48
|
+
- `models:/<model_name>/<model_version>`
|
49
|
+
- `models:/<model_name>/<stage>` (refers to the latest model version in the given stage)
|
50
|
+
- `models:/<model_name>/latest` (refers to the latest of all model versions)
|
51
|
+
- `models://<profile>/<model_name>/<model_version or stage or 'latest'>`
|
52
|
+
|
53
|
+
Note : This artifact repository is meant is to be instantiated by the ModelsArtifactRepository
|
54
|
+
when the client is pointing to a Databricks-hosted model registry.
|
55
|
+
"""
|
56
|
+
|
57
|
+
def __init__(self, artifact_uri: str, tracking_uri: Optional[str] = None) -> None:
|
58
|
+
if not is_using_databricks_registry(artifact_uri):
|
59
|
+
raise MlflowException(
|
60
|
+
message="A valid databricks profile is required to instantiate this repository",
|
61
|
+
error_code=INVALID_PARAMETER_VALUE,
|
62
|
+
)
|
63
|
+
super().__init__(artifact_uri, tracking_uri)
|
64
|
+
from mlflow.tracking.client import MlflowClient
|
65
|
+
|
66
|
+
self.databricks_profile_uri = (
|
67
|
+
get_databricks_profile_uri_from_artifact_uri(artifact_uri) or mlflow.get_registry_uri()
|
68
|
+
)
|
69
|
+
warn_on_deprecated_cross_workspace_registry_uri(self.databricks_profile_uri)
|
70
|
+
client = MlflowClient(registry_uri=self.databricks_profile_uri)
|
71
|
+
self.model_name, self.model_version = get_model_name_and_version(client, artifact_uri)
|
72
|
+
# Use an isolated thread pool executor for chunk uploads/downloads to avoid a deadlock
|
73
|
+
# caused by waiting for a chunk-upload/download task within a file-upload/download task.
|
74
|
+
# See https://superfastpython.com/threadpoolexecutor-deadlock/#Deadlock_1_Submit_and_Wait_for_a_Task_Within_a_Task
|
75
|
+
# for more details
|
76
|
+
self.chunk_thread_pool = self._create_thread_pool()
|
77
|
+
|
78
|
+
def _call_endpoint(self, json, endpoint):
|
79
|
+
db_creds = get_databricks_host_creds(self.databricks_profile_uri)
|
80
|
+
return http_request(host_creds=db_creds, endpoint=endpoint, method="GET", params=json)
|
81
|
+
|
82
|
+
def _make_json_body(self, path, page_token=None):
|
83
|
+
body = {"name": self.model_name, "version": self.model_version, "path": path}
|
84
|
+
if page_token:
|
85
|
+
body["page_token"] = page_token
|
86
|
+
return body
|
87
|
+
|
88
|
+
def list_artifacts(self, path: Optional[str] = None) -> list[FileInfo]:
|
89
|
+
infos = []
|
90
|
+
page_token = None
|
91
|
+
if not path:
|
92
|
+
path = ""
|
93
|
+
while True:
|
94
|
+
json_body = self._make_json_body(path, page_token)
|
95
|
+
response = self._call_endpoint(json_body, REGISTRY_LIST_ARTIFACTS_ENDPOINT)
|
96
|
+
try:
|
97
|
+
response.raise_for_status()
|
98
|
+
json_response = json.loads(response.text)
|
99
|
+
except Exception:
|
100
|
+
raise MlflowException(
|
101
|
+
f"API request to list files under path `{path}` failed with status code "
|
102
|
+
f"{response.status_code}. Response body: {response.text}"
|
103
|
+
)
|
104
|
+
artifact_list = json_response.get("files", [])
|
105
|
+
next_page_token = json_response.get("next_page_token", None)
|
106
|
+
# If `path` is a file, ListArtifacts returns a single list element with the
|
107
|
+
# same name as `path`. The list_artifacts API expects us to return an empty list in this
|
108
|
+
# case, so we do so here.
|
109
|
+
if (
|
110
|
+
len(artifact_list) == 1
|
111
|
+
and artifact_list[0]["path"] == path
|
112
|
+
and not artifact_list[0]["is_dir"]
|
113
|
+
):
|
114
|
+
return []
|
115
|
+
for output_file in artifact_list:
|
116
|
+
artifact_size = None if output_file["is_dir"] else output_file["file_size"]
|
117
|
+
infos.append(FileInfo(output_file["path"], output_file["is_dir"], artifact_size))
|
118
|
+
if len(artifact_list) == 0 or not next_page_token:
|
119
|
+
break
|
120
|
+
page_token = next_page_token
|
121
|
+
return infos
|
122
|
+
|
123
|
+
# TODO: Change the implementation of this to match how databricks_artifact_repo.py handles this
|
124
|
+
def _get_signed_download_uri(self, path=None):
|
125
|
+
if not path:
|
126
|
+
path = ""
|
127
|
+
json_body = self._make_json_body(path)
|
128
|
+
response = self._call_endpoint(json_body, REGISTRY_ARTIFACT_PRESIGNED_URI_ENDPOINT)
|
129
|
+
try:
|
130
|
+
json_response = json.loads(response.text)
|
131
|
+
except ValueError:
|
132
|
+
raise MlflowException(
|
133
|
+
f"API request to get presigned uri to for file under path `{path}` failed with"
|
134
|
+
f" status code {response.status_code}. Response body: {response.text}"
|
135
|
+
)
|
136
|
+
return json_response.get("signed_uri", None), json_response.get("headers", None)
|
137
|
+
|
138
|
+
def _extract_headers_from_signed_url(self, headers):
|
139
|
+
if headers is None:
|
140
|
+
return {}
|
141
|
+
filtered_headers = filter(lambda h: "name" in h and "value" in h, headers)
|
142
|
+
return {header.get("name"): header.get("value") for header in filtered_headers}
|
143
|
+
|
144
|
+
def _parallelized_download_from_cloud(
|
145
|
+
self, signed_uri, headers, file_size, dst_local_file_path, dst_run_relative_artifact_path
|
146
|
+
):
|
147
|
+
from mlflow.utils.databricks_utils import get_databricks_env_vars
|
148
|
+
|
149
|
+
with remove_on_error(dst_local_file_path):
|
150
|
+
parallel_download_subproc_env = os.environ.copy()
|
151
|
+
parallel_download_subproc_env.update(
|
152
|
+
get_databricks_env_vars(self.databricks_profile_uri)
|
153
|
+
)
|
154
|
+
failed_downloads = parallelized_download_file_using_http_uri(
|
155
|
+
thread_pool_executor=self.chunk_thread_pool,
|
156
|
+
http_uri=signed_uri,
|
157
|
+
download_path=dst_local_file_path,
|
158
|
+
remote_file_path=dst_run_relative_artifact_path,
|
159
|
+
file_size=file_size,
|
160
|
+
# URI type is not known in this context
|
161
|
+
uri_type=None,
|
162
|
+
chunk_size=MLFLOW_MULTIPART_DOWNLOAD_CHUNK_SIZE.get(),
|
163
|
+
env=parallel_download_subproc_env,
|
164
|
+
headers=headers,
|
165
|
+
)
|
166
|
+
if failed_downloads:
|
167
|
+
new_signed_uri, new_headers = self._get_signed_download_uri(
|
168
|
+
dst_run_relative_artifact_path
|
169
|
+
)
|
170
|
+
new_headers = self._extract_headers_from_signed_url(new_headers)
|
171
|
+
download_chunk_retries(
|
172
|
+
chunks=list(failed_downloads),
|
173
|
+
http_uri=new_signed_uri,
|
174
|
+
headers=new_headers,
|
175
|
+
download_path=dst_local_file_path,
|
176
|
+
)
|
177
|
+
|
178
|
+
def _download_file(self, remote_file_path, local_path):
|
179
|
+
try:
|
180
|
+
parent_dir, _ = posixpath.split(remote_file_path)
|
181
|
+
file_infos = self.list_artifacts(parent_dir)
|
182
|
+
file_info = [info for info in file_infos if info.path == remote_file_path]
|
183
|
+
file_size = file_info[0].file_size if len(file_info) == 1 else None
|
184
|
+
signed_uri, raw_headers = self._get_signed_download_uri(remote_file_path)
|
185
|
+
headers = {}
|
186
|
+
if raw_headers is not None:
|
187
|
+
# Don't send None to _extract_headers_from_signed_url
|
188
|
+
headers = self._extract_headers_from_signed_url(raw_headers)
|
189
|
+
if (
|
190
|
+
not file_size
|
191
|
+
or file_size <= MLFLOW_MULTIPART_DOWNLOAD_CHUNK_SIZE.get()
|
192
|
+
or not MLFLOW_ENABLE_MULTIPART_DOWNLOAD.get()
|
193
|
+
):
|
194
|
+
download_file_using_http_uri(
|
195
|
+
signed_uri, local_path, MLFLOW_MULTIPART_DOWNLOAD_CHUNK_SIZE.get(), headers
|
196
|
+
)
|
197
|
+
else:
|
198
|
+
self._parallelized_download_from_cloud(
|
199
|
+
signed_uri,
|
200
|
+
headers,
|
201
|
+
file_size,
|
202
|
+
local_path,
|
203
|
+
remote_file_path,
|
204
|
+
)
|
205
|
+
|
206
|
+
except Exception as err:
|
207
|
+
raise MlflowException(err)
|
208
|
+
|
209
|
+
def log_artifact(self, local_file, artifact_path=None):
|
210
|
+
raise MlflowException("This repository does not support logging artifacts.")
|
211
|
+
|
212
|
+
def log_artifacts(self, local_dir, artifact_path=None):
|
213
|
+
raise MlflowException("This repository does not support logging artifacts.")
|
214
|
+
|
215
|
+
def delete_artifacts(self, artifact_path=None):
|
216
|
+
raise NotImplementedError("This artifact repository does not support deleting artifacts")
|