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,218 @@
|
|
1
|
+
import logging
|
2
|
+
import os
|
3
|
+
import posixpath
|
4
|
+
|
5
|
+
import requests
|
6
|
+
from requests import HTTPError
|
7
|
+
|
8
|
+
from mlflow.entities import FileInfo
|
9
|
+
from mlflow.entities.multipart_upload import (
|
10
|
+
CreateMultipartUploadResponse,
|
11
|
+
MultipartUploadCredential,
|
12
|
+
MultipartUploadPart,
|
13
|
+
)
|
14
|
+
from mlflow.environment_variables import (
|
15
|
+
MLFLOW_ENABLE_PROXY_MULTIPART_UPLOAD,
|
16
|
+
MLFLOW_MULTIPART_UPLOAD_CHUNK_SIZE,
|
17
|
+
MLFLOW_MULTIPART_UPLOAD_MINIMUM_FILE_SIZE,
|
18
|
+
)
|
19
|
+
from mlflow.exceptions import MlflowException, _UnsupportedMultipartUploadException
|
20
|
+
from mlflow.store.artifact.artifact_repo import (
|
21
|
+
ArtifactRepository,
|
22
|
+
MultipartUploadMixin,
|
23
|
+
verify_artifact_path,
|
24
|
+
)
|
25
|
+
from mlflow.store.artifact.cloud_artifact_repo import _complete_futures, _compute_num_chunks
|
26
|
+
from mlflow.utils.credentials import get_default_host_creds
|
27
|
+
from mlflow.utils.file_utils import read_chunk, relative_path_to_artifact_path
|
28
|
+
from mlflow.utils.mime_type_utils import _guess_mime_type
|
29
|
+
from mlflow.utils.rest_utils import augmented_raise_for_status, http_request
|
30
|
+
from mlflow.utils.uri import validate_path_is_safe
|
31
|
+
|
32
|
+
_logger = logging.getLogger(__name__)
|
33
|
+
|
34
|
+
|
35
|
+
class HttpArtifactRepository(ArtifactRepository, MultipartUploadMixin):
|
36
|
+
"""Stores artifacts in a remote artifact storage using HTTP requests"""
|
37
|
+
|
38
|
+
@property
|
39
|
+
def _host_creds(self):
|
40
|
+
return get_default_host_creds(self.artifact_uri)
|
41
|
+
|
42
|
+
def log_artifact(self, local_file, artifact_path=None):
|
43
|
+
verify_artifact_path(artifact_path)
|
44
|
+
|
45
|
+
# Try to perform multipart upload if the file is large.
|
46
|
+
# If the server does not support, or if the upload failed, revert to normal upload.
|
47
|
+
if (
|
48
|
+
MLFLOW_ENABLE_PROXY_MULTIPART_UPLOAD.get()
|
49
|
+
and os.path.getsize(local_file) >= MLFLOW_MULTIPART_UPLOAD_MINIMUM_FILE_SIZE.get()
|
50
|
+
):
|
51
|
+
try:
|
52
|
+
self._try_multipart_upload(local_file, artifact_path)
|
53
|
+
return
|
54
|
+
except _UnsupportedMultipartUploadException:
|
55
|
+
pass
|
56
|
+
|
57
|
+
file_name = os.path.basename(local_file)
|
58
|
+
mime_type = _guess_mime_type(file_name)
|
59
|
+
paths = (artifact_path, file_name) if artifact_path else (file_name,)
|
60
|
+
endpoint = posixpath.join("/", *paths)
|
61
|
+
extra_headers = {"Content-Type": mime_type}
|
62
|
+
with open(local_file, "rb") as f:
|
63
|
+
resp = http_request(
|
64
|
+
self._host_creds, endpoint, "PUT", data=f, extra_headers=extra_headers
|
65
|
+
)
|
66
|
+
augmented_raise_for_status(resp)
|
67
|
+
|
68
|
+
def log_artifacts(self, local_dir, artifact_path=None):
|
69
|
+
local_dir = os.path.abspath(local_dir)
|
70
|
+
for root, _, filenames in os.walk(local_dir):
|
71
|
+
if root == local_dir:
|
72
|
+
artifact_dir = artifact_path
|
73
|
+
else:
|
74
|
+
rel_path = os.path.relpath(root, local_dir)
|
75
|
+
rel_path = relative_path_to_artifact_path(rel_path)
|
76
|
+
artifact_dir = (
|
77
|
+
posixpath.join(artifact_path, rel_path) if artifact_path else rel_path
|
78
|
+
)
|
79
|
+
for f in filenames:
|
80
|
+
self.log_artifact(os.path.join(root, f), artifact_dir)
|
81
|
+
|
82
|
+
def list_artifacts(self, path=None):
|
83
|
+
endpoint = "/mlflow-artifacts/artifacts"
|
84
|
+
url, tail = self.artifact_uri.split(endpoint, maxsplit=1)
|
85
|
+
root = tail.lstrip("/")
|
86
|
+
params = {"path": posixpath.join(root, path) if path else root}
|
87
|
+
host_creds = get_default_host_creds(url)
|
88
|
+
resp = http_request(host_creds, endpoint, "GET", params=params)
|
89
|
+
augmented_raise_for_status(resp)
|
90
|
+
file_infos = []
|
91
|
+
for f in resp.json().get("files", []):
|
92
|
+
validated_path = validate_path_is_safe(f["path"])
|
93
|
+
file_info = FileInfo(
|
94
|
+
posixpath.join(path, validated_path) if path else validated_path,
|
95
|
+
f["is_dir"],
|
96
|
+
int(f["file_size"]) if ("file_size" in f) else None,
|
97
|
+
)
|
98
|
+
file_infos.append(file_info)
|
99
|
+
|
100
|
+
return sorted(file_infos, key=lambda f: f.path)
|
101
|
+
|
102
|
+
def _download_file(self, remote_file_path, local_path):
|
103
|
+
endpoint = posixpath.join("/", remote_file_path)
|
104
|
+
resp = http_request(self._host_creds, endpoint, "GET", stream=True)
|
105
|
+
augmented_raise_for_status(resp)
|
106
|
+
with open(local_path, "wb") as f:
|
107
|
+
chunk_size = 1024 * 1024 # 1 MB
|
108
|
+
for chunk in resp.iter_content(chunk_size=chunk_size):
|
109
|
+
f.write(chunk)
|
110
|
+
|
111
|
+
def delete_artifacts(self, artifact_path=None):
|
112
|
+
endpoint = posixpath.join("/", artifact_path) if artifact_path else "/"
|
113
|
+
resp = http_request(self._host_creds, endpoint, "DELETE", stream=True)
|
114
|
+
augmented_raise_for_status(resp)
|
115
|
+
|
116
|
+
def _construct_mpu_uri_and_path(self, base_endpoint, artifact_path):
|
117
|
+
uri, path = self.artifact_uri.split("/mlflow-artifacts/artifacts", maxsplit=1)
|
118
|
+
path = path.strip("/")
|
119
|
+
endpoint = (
|
120
|
+
posixpath.join(base_endpoint, path, artifact_path)
|
121
|
+
if artifact_path
|
122
|
+
else posixpath.join(base_endpoint, path)
|
123
|
+
)
|
124
|
+
return uri, endpoint
|
125
|
+
|
126
|
+
def create_multipart_upload(self, local_file, num_parts=1, artifact_path=None):
|
127
|
+
uri, endpoint = self._construct_mpu_uri_and_path(
|
128
|
+
"/mlflow-artifacts/mpu/create", artifact_path
|
129
|
+
)
|
130
|
+
host_creds = get_default_host_creds(uri)
|
131
|
+
params = {
|
132
|
+
"path": local_file,
|
133
|
+
"num_parts": num_parts,
|
134
|
+
}
|
135
|
+
resp = http_request(host_creds, endpoint, "POST", json=params)
|
136
|
+
augmented_raise_for_status(resp)
|
137
|
+
return CreateMultipartUploadResponse.from_dict(resp.json())
|
138
|
+
|
139
|
+
def complete_multipart_upload(self, local_file, upload_id, parts=None, artifact_path=None):
|
140
|
+
uri, endpoint = self._construct_mpu_uri_and_path(
|
141
|
+
"/mlflow-artifacts/mpu/complete", artifact_path
|
142
|
+
)
|
143
|
+
host_creds = get_default_host_creds(uri)
|
144
|
+
params = {
|
145
|
+
"path": local_file,
|
146
|
+
"upload_id": upload_id,
|
147
|
+
"parts": [part.to_dict() for part in parts],
|
148
|
+
}
|
149
|
+
resp = http_request(host_creds, endpoint, "POST", json=params)
|
150
|
+
augmented_raise_for_status(resp)
|
151
|
+
|
152
|
+
def abort_multipart_upload(self, local_file, upload_id, artifact_path=None):
|
153
|
+
uri, endpoint = self._construct_mpu_uri_and_path(
|
154
|
+
"/mlflow-artifacts/mpu/abort", artifact_path
|
155
|
+
)
|
156
|
+
host_creds = get_default_host_creds(uri)
|
157
|
+
params = {
|
158
|
+
"path": local_file,
|
159
|
+
"upload_id": upload_id,
|
160
|
+
}
|
161
|
+
resp = http_request(host_creds, endpoint, "POST", json=params)
|
162
|
+
augmented_raise_for_status(resp)
|
163
|
+
|
164
|
+
@staticmethod
|
165
|
+
def _upload_part(credential: MultipartUploadCredential, local_file, size, start_byte):
|
166
|
+
data = read_chunk(local_file, size, start_byte)
|
167
|
+
response = requests.put(credential.url, data=data, headers=credential.headers)
|
168
|
+
augmented_raise_for_status(response)
|
169
|
+
return MultipartUploadPart(
|
170
|
+
part_number=credential.part_number,
|
171
|
+
etag=response.headers.get("ETag", ""),
|
172
|
+
url=credential.url,
|
173
|
+
)
|
174
|
+
|
175
|
+
def _try_multipart_upload(self, local_file, artifact_path=None):
|
176
|
+
"""
|
177
|
+
Attempts to perform multipart upload to log an artifact.
|
178
|
+
Returns if the multipart upload is successful.
|
179
|
+
Raises UnsupportedMultipartUploadException if multipart upload is unsupported.
|
180
|
+
"""
|
181
|
+
chunk_size = MLFLOW_MULTIPART_UPLOAD_CHUNK_SIZE.get()
|
182
|
+
num_parts = _compute_num_chunks(local_file, chunk_size)
|
183
|
+
|
184
|
+
try:
|
185
|
+
create = self.create_multipart_upload(local_file, num_parts, artifact_path)
|
186
|
+
except HTTPError as e:
|
187
|
+
# return False if server does not support multipart upload
|
188
|
+
error_message = e.response.json().get("message", "")
|
189
|
+
if isinstance(error_message, str) and error_message.startswith(
|
190
|
+
_UnsupportedMultipartUploadException.MESSAGE
|
191
|
+
):
|
192
|
+
raise _UnsupportedMultipartUploadException()
|
193
|
+
raise
|
194
|
+
|
195
|
+
try:
|
196
|
+
futures = {}
|
197
|
+
for i, credential in enumerate(create.credentials):
|
198
|
+
future = self.thread_pool.submit(
|
199
|
+
self._upload_part,
|
200
|
+
credential=credential,
|
201
|
+
local_file=local_file,
|
202
|
+
size=chunk_size,
|
203
|
+
start_byte=chunk_size * i,
|
204
|
+
)
|
205
|
+
futures[future] = credential.part_number
|
206
|
+
|
207
|
+
parts, errors = _complete_futures(futures, local_file)
|
208
|
+
if errors:
|
209
|
+
raise MlflowException(
|
210
|
+
f"Failed to upload at least one part of {local_file}. Errors: {errors}"
|
211
|
+
)
|
212
|
+
|
213
|
+
parts = sorted(parts.values(), key=lambda part: part.part_number)
|
214
|
+
self.complete_multipart_upload(local_file, create.upload_id, parts, artifact_path)
|
215
|
+
except Exception as e:
|
216
|
+
self.abort_multipart_upload(local_file, create.upload_id, artifact_path)
|
217
|
+
_logger.warning(f"Failed to upload file {local_file} using multipart upload: {e}")
|
218
|
+
raise
|
@@ -0,0 +1,142 @@
|
|
1
|
+
import os
|
2
|
+
import shutil
|
3
|
+
from typing import Any, Optional
|
4
|
+
|
5
|
+
from mlflow.store.artifact.artifact_repo import (
|
6
|
+
ArtifactRepository,
|
7
|
+
try_read_trace_data,
|
8
|
+
verify_artifact_path,
|
9
|
+
)
|
10
|
+
from mlflow.tracing.utils.artifact_utils import TRACE_DATA_FILE_NAME
|
11
|
+
from mlflow.utils.file_utils import (
|
12
|
+
get_file_info,
|
13
|
+
list_all,
|
14
|
+
local_file_uri_to_path,
|
15
|
+
mkdir,
|
16
|
+
relative_path_to_artifact_path,
|
17
|
+
)
|
18
|
+
from mlflow.utils.uri import validate_path_is_safe
|
19
|
+
|
20
|
+
|
21
|
+
class LocalArtifactRepository(ArtifactRepository):
|
22
|
+
"""Stores artifacts as files in a local directory."""
|
23
|
+
|
24
|
+
def __init__(self, artifact_uri: str, tracking_uri: Optional[str] = None) -> None:
|
25
|
+
super().__init__(artifact_uri, tracking_uri)
|
26
|
+
self._artifact_dir = local_file_uri_to_path(self.artifact_uri)
|
27
|
+
|
28
|
+
@property
|
29
|
+
def artifact_dir(self):
|
30
|
+
return self._artifact_dir
|
31
|
+
|
32
|
+
def log_artifact(self, local_file, artifact_path=None):
|
33
|
+
verify_artifact_path(artifact_path)
|
34
|
+
# NOTE: The artifact_path is expected to be in posix format.
|
35
|
+
# Posix paths work fine on windows but just in case we normalize it here.
|
36
|
+
if artifact_path:
|
37
|
+
artifact_path = os.path.normpath(artifact_path)
|
38
|
+
|
39
|
+
artifact_dir = (
|
40
|
+
os.path.join(self.artifact_dir, artifact_path) if artifact_path else self.artifact_dir
|
41
|
+
)
|
42
|
+
if not os.path.exists(artifact_dir):
|
43
|
+
mkdir(artifact_dir)
|
44
|
+
try:
|
45
|
+
shutil.copy2(local_file, os.path.join(artifact_dir, os.path.basename(local_file)))
|
46
|
+
except shutil.SameFileError:
|
47
|
+
pass
|
48
|
+
|
49
|
+
def _is_directory(self, artifact_path):
|
50
|
+
# NOTE: The path is expected to be in posix format.
|
51
|
+
# Posix paths work fine on windows but just in case we normalize it here.
|
52
|
+
path = os.path.normpath(artifact_path) if artifact_path else ""
|
53
|
+
list_dir = os.path.join(self.artifact_dir, path) if path else self.artifact_dir
|
54
|
+
return os.path.isdir(list_dir)
|
55
|
+
|
56
|
+
def log_artifacts(self, local_dir, artifact_path=None):
|
57
|
+
verify_artifact_path(artifact_path)
|
58
|
+
# NOTE: The artifact_path is expected to be in posix format.
|
59
|
+
# Posix paths work fine on windows but just in case we normalize it here.
|
60
|
+
if artifact_path:
|
61
|
+
artifact_path = os.path.normpath(artifact_path)
|
62
|
+
artifact_dir = (
|
63
|
+
os.path.join(self.artifact_dir, artifact_path) if artifact_path else self.artifact_dir
|
64
|
+
)
|
65
|
+
if not os.path.exists(artifact_dir):
|
66
|
+
mkdir(artifact_dir)
|
67
|
+
shutil.copytree(src=local_dir, dst=artifact_dir, dirs_exist_ok=True)
|
68
|
+
|
69
|
+
def download_artifacts(self, artifact_path, dst_path=None):
|
70
|
+
"""
|
71
|
+
Artifacts tracked by ``LocalArtifactRepository`` already exist on the local filesystem.
|
72
|
+
If ``dst_path`` is ``None``, the absolute filesystem path of the specified artifact is
|
73
|
+
returned. If ``dst_path`` is not ``None``, the local artifact is copied to ``dst_path``.
|
74
|
+
|
75
|
+
Args:
|
76
|
+
artifact_path: Relative source path to the desired artifacts.
|
77
|
+
dst_path: Absolute path of the local filesystem destination directory to which to
|
78
|
+
download the specified artifacts. This directory must already exist. If
|
79
|
+
unspecified, the absolute path of the local artifact will be returned.
|
80
|
+
|
81
|
+
Returns:
|
82
|
+
Absolute path of the local filesystem location containing the desired artifacts.
|
83
|
+
"""
|
84
|
+
if dst_path:
|
85
|
+
return super().download_artifacts(artifact_path, dst_path)
|
86
|
+
# NOTE: The artifact_path is expected to be a relative path in posix format.
|
87
|
+
# Posix paths work fine on windows but just in case we normalize it here.
|
88
|
+
artifact_path = validate_path_is_safe(artifact_path)
|
89
|
+
local_artifact_path = os.path.join(self.artifact_dir, os.path.normpath(artifact_path))
|
90
|
+
if not os.path.exists(local_artifact_path):
|
91
|
+
raise OSError(f"No such file or directory: '{local_artifact_path}'")
|
92
|
+
return os.path.abspath(local_artifact_path)
|
93
|
+
|
94
|
+
def list_artifacts(self, path=None):
|
95
|
+
# NOTE: The path is expected to be in posix format.
|
96
|
+
# Posix paths work fine on windows but just in case we normalize it here.
|
97
|
+
if path:
|
98
|
+
path = os.path.normpath(path)
|
99
|
+
list_dir = os.path.join(self.artifact_dir, path) if path else self.artifact_dir
|
100
|
+
if os.path.isdir(list_dir):
|
101
|
+
artifact_files = list_all(list_dir, full_path=True)
|
102
|
+
infos = [
|
103
|
+
get_file_info(
|
104
|
+
f, relative_path_to_artifact_path(os.path.relpath(f, self.artifact_dir))
|
105
|
+
)
|
106
|
+
for f in artifact_files
|
107
|
+
]
|
108
|
+
return sorted(infos, key=lambda f: f.path)
|
109
|
+
else:
|
110
|
+
return []
|
111
|
+
|
112
|
+
def _download_file(self, remote_file_path, local_path):
|
113
|
+
# NOTE: The remote_file_path is expected to be a relative path in posix format.
|
114
|
+
# Posix paths work fine on windows but just in case we normalize it here.
|
115
|
+
remote_file_path = validate_path_is_safe(remote_file_path)
|
116
|
+
remote_file_path = os.path.join(self.artifact_dir, os.path.normpath(remote_file_path))
|
117
|
+
shutil.copy2(remote_file_path, local_path)
|
118
|
+
|
119
|
+
def delete_artifacts(self, artifact_path=None):
|
120
|
+
artifact_path = local_file_uri_to_path(
|
121
|
+
os.path.join(self._artifact_dir, artifact_path) if artifact_path else self._artifact_dir
|
122
|
+
)
|
123
|
+
|
124
|
+
if os.path.exists(artifact_path):
|
125
|
+
if os.path.isfile(artifact_path):
|
126
|
+
os.remove(artifact_path)
|
127
|
+
else:
|
128
|
+
shutil.rmtree(artifact_path)
|
129
|
+
|
130
|
+
def download_trace_data(self) -> dict[str, Any]:
|
131
|
+
"""
|
132
|
+
Download the trace data.
|
133
|
+
|
134
|
+
Returns:
|
135
|
+
The trace data as a dictionary.
|
136
|
+
|
137
|
+
Raises:
|
138
|
+
- `MlflowTraceDataNotFound`: The trace data is not found.
|
139
|
+
- `MlflowTraceDataCorrupted`: The trace data is corrupted.
|
140
|
+
"""
|
141
|
+
trace_data_path = os.path.join(self.artifact_dir, TRACE_DATA_FILE_NAME)
|
142
|
+
return try_read_trace_data(trace_data_path)
|
@@ -0,0 +1,94 @@
|
|
1
|
+
import re
|
2
|
+
from typing import Optional
|
3
|
+
from urllib.parse import urlparse, urlunparse
|
4
|
+
|
5
|
+
from mlflow.exceptions import MlflowException
|
6
|
+
from mlflow.store.artifact.http_artifact_repo import HttpArtifactRepository
|
7
|
+
from mlflow.tracking._tracking_service.utils import get_tracking_uri
|
8
|
+
|
9
|
+
|
10
|
+
def _check_if_host_is_numeric(hostname):
|
11
|
+
if hostname:
|
12
|
+
try:
|
13
|
+
float(hostname)
|
14
|
+
return True
|
15
|
+
except ValueError:
|
16
|
+
return False
|
17
|
+
else:
|
18
|
+
return False
|
19
|
+
|
20
|
+
|
21
|
+
def _validate_port_mapped_to_hostname(uri_parse):
|
22
|
+
# This check is to catch an mlflow-artifacts uri that has a port designated but no
|
23
|
+
# hostname specified. `urllib.parse.urlparse` will treat such a uri as a filesystem
|
24
|
+
# definition, mapping the provided port as a hostname value if this condition is not
|
25
|
+
# validated.
|
26
|
+
if uri_parse.hostname and _check_if_host_is_numeric(uri_parse.hostname) and not uri_parse.port:
|
27
|
+
raise MlflowException(
|
28
|
+
"The mlflow-artifacts uri was supplied with a port number: "
|
29
|
+
f"{uri_parse.hostname}, but no host was defined."
|
30
|
+
)
|
31
|
+
|
32
|
+
|
33
|
+
def _validate_uri_scheme(parsed_uri):
|
34
|
+
allowable_schemes = {"http", "https"}
|
35
|
+
if parsed_uri.scheme not in allowable_schemes:
|
36
|
+
raise MlflowException(
|
37
|
+
"When an mlflow-artifacts URI was supplied, the tracking URI must be a valid "
|
38
|
+
f"http or https URI, but it was currently set to {parsed_uri.geturl()}. "
|
39
|
+
"Perhaps you forgot to set the tracking URI to the running MLflow server. "
|
40
|
+
"To set the tracking URI, use either of the following methods:\n"
|
41
|
+
"1. Set the MLFLOW_TRACKING_URI environment variable to the desired tracking URI. "
|
42
|
+
"`export MLFLOW_TRACKING_URI=http://localhost:5000`\n"
|
43
|
+
"2. Set the tracking URI programmatically by calling `mlflow.set_tracking_uri`. "
|
44
|
+
"`mlflow.set_tracking_uri('http://localhost:5000')`"
|
45
|
+
)
|
46
|
+
|
47
|
+
|
48
|
+
class MlflowArtifactsRepository(HttpArtifactRepository):
|
49
|
+
"""Scheme wrapper around HttpArtifactRepository for mlflow-artifacts server functionality"""
|
50
|
+
|
51
|
+
def __init__(self, artifact_uri: str, tracking_uri: Optional[str] = None) -> None:
|
52
|
+
effective_tracking_uri = tracking_uri or get_tracking_uri()
|
53
|
+
super().__init__(self.resolve_uri(artifact_uri, effective_tracking_uri), tracking_uri)
|
54
|
+
|
55
|
+
@classmethod
|
56
|
+
def resolve_uri(cls, artifact_uri, tracking_uri):
|
57
|
+
base_url = "/api/2.0/mlflow-artifacts/artifacts"
|
58
|
+
|
59
|
+
track_parse = urlparse(tracking_uri)
|
60
|
+
|
61
|
+
uri_parse = urlparse(artifact_uri)
|
62
|
+
|
63
|
+
# Check to ensure that a port is present with no hostname
|
64
|
+
_validate_port_mapped_to_hostname(uri_parse)
|
65
|
+
|
66
|
+
# Check that tracking uri is http or https
|
67
|
+
_validate_uri_scheme(track_parse)
|
68
|
+
|
69
|
+
if uri_parse.path == "/": # root directory; build simple path
|
70
|
+
resolved = f"{base_url}{uri_parse.path}"
|
71
|
+
elif uri_parse.path == base_url: # for operations like list artifacts
|
72
|
+
resolved = base_url
|
73
|
+
else:
|
74
|
+
resolved = f"{track_parse.path}/{base_url}/{uri_parse.path}"
|
75
|
+
resolved = re.sub("//+", "/", resolved)
|
76
|
+
|
77
|
+
resolved_artifacts_uri = urlunparse(
|
78
|
+
(
|
79
|
+
# scheme
|
80
|
+
track_parse.scheme,
|
81
|
+
# netloc
|
82
|
+
uri_parse.netloc if uri_parse.netloc else track_parse.netloc,
|
83
|
+
# path
|
84
|
+
resolved,
|
85
|
+
# params
|
86
|
+
"",
|
87
|
+
# query
|
88
|
+
"",
|
89
|
+
# fragment
|
90
|
+
"",
|
91
|
+
)
|
92
|
+
)
|
93
|
+
|
94
|
+
return resolved_artifacts_uri.replace("///", "/").rstrip("/")
|