genesis-flow 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- genesis_flow-1.0.0.dist-info/METADATA +822 -0
- genesis_flow-1.0.0.dist-info/RECORD +645 -0
- genesis_flow-1.0.0.dist-info/WHEEL +5 -0
- genesis_flow-1.0.0.dist-info/entry_points.txt +19 -0
- genesis_flow-1.0.0.dist-info/licenses/LICENSE.txt +202 -0
- genesis_flow-1.0.0.dist-info/top_level.txt +1 -0
- mlflow/__init__.py +367 -0
- mlflow/__main__.py +3 -0
- mlflow/ag2/__init__.py +56 -0
- mlflow/ag2/ag2_logger.py +294 -0
- mlflow/anthropic/__init__.py +40 -0
- mlflow/anthropic/autolog.py +129 -0
- mlflow/anthropic/chat.py +144 -0
- mlflow/artifacts/__init__.py +268 -0
- mlflow/autogen/__init__.py +144 -0
- mlflow/autogen/chat.py +142 -0
- mlflow/azure/__init__.py +26 -0
- mlflow/azure/auth_handler.py +257 -0
- mlflow/azure/client.py +319 -0
- mlflow/azure/config.py +120 -0
- mlflow/azure/connection_factory.py +340 -0
- mlflow/azure/exceptions.py +27 -0
- mlflow/azure/stores.py +327 -0
- mlflow/azure/utils.py +183 -0
- mlflow/bedrock/__init__.py +45 -0
- mlflow/bedrock/_autolog.py +202 -0
- mlflow/bedrock/chat.py +122 -0
- mlflow/bedrock/stream.py +160 -0
- mlflow/bedrock/utils.py +43 -0
- mlflow/cli.py +707 -0
- mlflow/client.py +12 -0
- mlflow/config/__init__.py +56 -0
- mlflow/crewai/__init__.py +79 -0
- mlflow/crewai/autolog.py +253 -0
- mlflow/crewai/chat.py +29 -0
- mlflow/data/__init__.py +75 -0
- mlflow/data/artifact_dataset_sources.py +170 -0
- mlflow/data/code_dataset_source.py +40 -0
- mlflow/data/dataset.py +123 -0
- mlflow/data/dataset_registry.py +168 -0
- mlflow/data/dataset_source.py +110 -0
- mlflow/data/dataset_source_registry.py +219 -0
- mlflow/data/delta_dataset_source.py +167 -0
- mlflow/data/digest_utils.py +108 -0
- mlflow/data/evaluation_dataset.py +562 -0
- mlflow/data/filesystem_dataset_source.py +81 -0
- mlflow/data/http_dataset_source.py +145 -0
- mlflow/data/huggingface_dataset.py +258 -0
- mlflow/data/huggingface_dataset_source.py +118 -0
- mlflow/data/meta_dataset.py +104 -0
- mlflow/data/numpy_dataset.py +223 -0
- mlflow/data/pandas_dataset.py +231 -0
- mlflow/data/polars_dataset.py +352 -0
- mlflow/data/pyfunc_dataset_mixin.py +31 -0
- mlflow/data/schema.py +76 -0
- mlflow/data/sources.py +1 -0
- mlflow/data/spark_dataset.py +406 -0
- mlflow/data/spark_dataset_source.py +74 -0
- mlflow/data/spark_delta_utils.py +118 -0
- mlflow/data/tensorflow_dataset.py +350 -0
- mlflow/data/uc_volume_dataset_source.py +81 -0
- mlflow/db.py +27 -0
- mlflow/dspy/__init__.py +17 -0
- mlflow/dspy/autolog.py +197 -0
- mlflow/dspy/callback.py +398 -0
- mlflow/dspy/constant.py +1 -0
- mlflow/dspy/load.py +93 -0
- mlflow/dspy/save.py +393 -0
- mlflow/dspy/util.py +109 -0
- mlflow/dspy/wrapper.py +226 -0
- mlflow/entities/__init__.py +104 -0
- mlflow/entities/_mlflow_object.py +52 -0
- mlflow/entities/assessment.py +545 -0
- mlflow/entities/assessment_error.py +80 -0
- mlflow/entities/assessment_source.py +141 -0
- mlflow/entities/dataset.py +92 -0
- mlflow/entities/dataset_input.py +51 -0
- mlflow/entities/dataset_summary.py +62 -0
- mlflow/entities/document.py +48 -0
- mlflow/entities/experiment.py +109 -0
- mlflow/entities/experiment_tag.py +35 -0
- mlflow/entities/file_info.py +45 -0
- mlflow/entities/input_tag.py +35 -0
- mlflow/entities/lifecycle_stage.py +35 -0
- mlflow/entities/logged_model.py +228 -0
- mlflow/entities/logged_model_input.py +26 -0
- mlflow/entities/logged_model_output.py +32 -0
- mlflow/entities/logged_model_parameter.py +46 -0
- mlflow/entities/logged_model_status.py +74 -0
- mlflow/entities/logged_model_tag.py +33 -0
- mlflow/entities/metric.py +200 -0
- mlflow/entities/model_registry/__init__.py +29 -0
- mlflow/entities/model_registry/_model_registry_entity.py +13 -0
- mlflow/entities/model_registry/model_version.py +243 -0
- mlflow/entities/model_registry/model_version_deployment_job_run_state.py +44 -0
- mlflow/entities/model_registry/model_version_deployment_job_state.py +70 -0
- mlflow/entities/model_registry/model_version_search.py +25 -0
- mlflow/entities/model_registry/model_version_stages.py +25 -0
- mlflow/entities/model_registry/model_version_status.py +35 -0
- mlflow/entities/model_registry/model_version_tag.py +35 -0
- mlflow/entities/model_registry/prompt.py +73 -0
- mlflow/entities/model_registry/prompt_version.py +244 -0
- mlflow/entities/model_registry/registered_model.py +175 -0
- mlflow/entities/model_registry/registered_model_alias.py +35 -0
- mlflow/entities/model_registry/registered_model_deployment_job_state.py +39 -0
- mlflow/entities/model_registry/registered_model_search.py +25 -0
- mlflow/entities/model_registry/registered_model_tag.py +35 -0
- mlflow/entities/multipart_upload.py +74 -0
- mlflow/entities/param.py +49 -0
- mlflow/entities/run.py +97 -0
- mlflow/entities/run_data.py +84 -0
- mlflow/entities/run_info.py +188 -0
- mlflow/entities/run_inputs.py +59 -0
- mlflow/entities/run_outputs.py +43 -0
- mlflow/entities/run_status.py +41 -0
- mlflow/entities/run_tag.py +36 -0
- mlflow/entities/source_type.py +31 -0
- mlflow/entities/span.py +774 -0
- mlflow/entities/span_event.py +96 -0
- mlflow/entities/span_status.py +102 -0
- mlflow/entities/trace.py +317 -0
- mlflow/entities/trace_data.py +71 -0
- mlflow/entities/trace_info.py +220 -0
- mlflow/entities/trace_info_v2.py +162 -0
- mlflow/entities/trace_location.py +173 -0
- mlflow/entities/trace_state.py +39 -0
- mlflow/entities/trace_status.py +68 -0
- mlflow/entities/view_type.py +51 -0
- mlflow/environment_variables.py +866 -0
- mlflow/evaluation/__init__.py +16 -0
- mlflow/evaluation/assessment.py +369 -0
- mlflow/evaluation/evaluation.py +411 -0
- mlflow/evaluation/evaluation_tag.py +61 -0
- mlflow/evaluation/fluent.py +48 -0
- mlflow/evaluation/utils.py +201 -0
- mlflow/exceptions.py +213 -0
- mlflow/experiments.py +140 -0
- mlflow/gemini/__init__.py +81 -0
- mlflow/gemini/autolog.py +186 -0
- mlflow/gemini/chat.py +261 -0
- mlflow/genai/__init__.py +71 -0
- mlflow/genai/datasets/__init__.py +67 -0
- mlflow/genai/datasets/evaluation_dataset.py +131 -0
- mlflow/genai/evaluation/__init__.py +3 -0
- mlflow/genai/evaluation/base.py +411 -0
- mlflow/genai/evaluation/constant.py +23 -0
- mlflow/genai/evaluation/utils.py +244 -0
- mlflow/genai/judges/__init__.py +21 -0
- mlflow/genai/judges/databricks.py +404 -0
- mlflow/genai/label_schemas/__init__.py +153 -0
- mlflow/genai/label_schemas/label_schemas.py +209 -0
- mlflow/genai/labeling/__init__.py +159 -0
- mlflow/genai/labeling/labeling.py +250 -0
- mlflow/genai/optimize/__init__.py +13 -0
- mlflow/genai/optimize/base.py +198 -0
- mlflow/genai/optimize/optimizers/__init__.py +4 -0
- mlflow/genai/optimize/optimizers/base_optimizer.py +38 -0
- mlflow/genai/optimize/optimizers/dspy_mipro_optimizer.py +221 -0
- mlflow/genai/optimize/optimizers/dspy_optimizer.py +91 -0
- mlflow/genai/optimize/optimizers/utils/dspy_mipro_callback.py +76 -0
- mlflow/genai/optimize/optimizers/utils/dspy_mipro_utils.py +18 -0
- mlflow/genai/optimize/types.py +75 -0
- mlflow/genai/optimize/util.py +30 -0
- mlflow/genai/prompts/__init__.py +206 -0
- mlflow/genai/scheduled_scorers.py +431 -0
- mlflow/genai/scorers/__init__.py +26 -0
- mlflow/genai/scorers/base.py +492 -0
- mlflow/genai/scorers/builtin_scorers.py +765 -0
- mlflow/genai/scorers/scorer_utils.py +138 -0
- mlflow/genai/scorers/validation.py +165 -0
- mlflow/genai/utils/data_validation.py +146 -0
- mlflow/genai/utils/enum_utils.py +23 -0
- mlflow/genai/utils/trace_utils.py +211 -0
- mlflow/groq/__init__.py +42 -0
- mlflow/groq/_groq_autolog.py +74 -0
- mlflow/johnsnowlabs/__init__.py +888 -0
- mlflow/langchain/__init__.py +24 -0
- mlflow/langchain/api_request_parallel_processor.py +330 -0
- mlflow/langchain/autolog.py +147 -0
- mlflow/langchain/chat_agent_langgraph.py +340 -0
- mlflow/langchain/constant.py +1 -0
- mlflow/langchain/constants.py +1 -0
- mlflow/langchain/databricks_dependencies.py +444 -0
- mlflow/langchain/langchain_tracer.py +597 -0
- mlflow/langchain/model.py +919 -0
- mlflow/langchain/output_parsers.py +142 -0
- mlflow/langchain/retriever_chain.py +153 -0
- mlflow/langchain/runnables.py +527 -0
- mlflow/langchain/utils/chat.py +402 -0
- mlflow/langchain/utils/logging.py +671 -0
- mlflow/langchain/utils/serialization.py +36 -0
- mlflow/legacy_databricks_cli/__init__.py +0 -0
- mlflow/legacy_databricks_cli/configure/__init__.py +0 -0
- mlflow/legacy_databricks_cli/configure/provider.py +482 -0
- mlflow/litellm/__init__.py +175 -0
- mlflow/llama_index/__init__.py +22 -0
- mlflow/llama_index/autolog.py +55 -0
- mlflow/llama_index/chat.py +43 -0
- mlflow/llama_index/constant.py +1 -0
- mlflow/llama_index/model.py +577 -0
- mlflow/llama_index/pyfunc_wrapper.py +332 -0
- mlflow/llama_index/serialize_objects.py +188 -0
- mlflow/llama_index/tracer.py +561 -0
- mlflow/metrics/__init__.py +479 -0
- mlflow/metrics/base.py +39 -0
- mlflow/metrics/genai/__init__.py +25 -0
- mlflow/metrics/genai/base.py +101 -0
- mlflow/metrics/genai/genai_metric.py +771 -0
- mlflow/metrics/genai/metric_definitions.py +450 -0
- mlflow/metrics/genai/model_utils.py +371 -0
- mlflow/metrics/genai/prompt_template.py +68 -0
- mlflow/metrics/genai/prompts/__init__.py +0 -0
- mlflow/metrics/genai/prompts/v1.py +422 -0
- mlflow/metrics/genai/utils.py +6 -0
- mlflow/metrics/metric_definitions.py +619 -0
- mlflow/mismatch.py +34 -0
- mlflow/mistral/__init__.py +34 -0
- mlflow/mistral/autolog.py +71 -0
- mlflow/mistral/chat.py +135 -0
- mlflow/ml_package_versions.py +452 -0
- mlflow/models/__init__.py +97 -0
- mlflow/models/auth_policy.py +83 -0
- mlflow/models/cli.py +354 -0
- mlflow/models/container/__init__.py +294 -0
- mlflow/models/container/scoring_server/__init__.py +0 -0
- mlflow/models/container/scoring_server/nginx.conf +39 -0
- mlflow/models/dependencies_schemas.py +287 -0
- mlflow/models/display_utils.py +158 -0
- mlflow/models/docker_utils.py +211 -0
- mlflow/models/evaluation/__init__.py +23 -0
- mlflow/models/evaluation/_shap_patch.py +64 -0
- mlflow/models/evaluation/artifacts.py +194 -0
- mlflow/models/evaluation/base.py +1811 -0
- mlflow/models/evaluation/calibration_curve.py +109 -0
- mlflow/models/evaluation/default_evaluator.py +996 -0
- mlflow/models/evaluation/deprecated.py +23 -0
- mlflow/models/evaluation/evaluator_registry.py +80 -0
- mlflow/models/evaluation/evaluators/classifier.py +704 -0
- mlflow/models/evaluation/evaluators/default.py +233 -0
- mlflow/models/evaluation/evaluators/regressor.py +96 -0
- mlflow/models/evaluation/evaluators/shap.py +296 -0
- mlflow/models/evaluation/lift_curve.py +178 -0
- mlflow/models/evaluation/utils/metric.py +123 -0
- mlflow/models/evaluation/utils/trace.py +179 -0
- mlflow/models/evaluation/validation.py +434 -0
- mlflow/models/flavor_backend.py +93 -0
- mlflow/models/flavor_backend_registry.py +53 -0
- mlflow/models/model.py +1639 -0
- mlflow/models/model_config.py +150 -0
- mlflow/models/notebook_resources/agent_evaluation_template.html +235 -0
- mlflow/models/notebook_resources/eval_with_dataset_example.py +22 -0
- mlflow/models/notebook_resources/eval_with_synthetic_example.py +22 -0
- mlflow/models/python_api.py +369 -0
- mlflow/models/rag_signatures.py +128 -0
- mlflow/models/resources.py +321 -0
- mlflow/models/signature.py +662 -0
- mlflow/models/utils.py +2054 -0
- mlflow/models/wheeled_model.py +280 -0
- mlflow/openai/__init__.py +57 -0
- mlflow/openai/_agent_tracer.py +364 -0
- mlflow/openai/api_request_parallel_processor.py +131 -0
- mlflow/openai/autolog.py +509 -0
- mlflow/openai/constant.py +1 -0
- mlflow/openai/model.py +824 -0
- mlflow/openai/utils/chat_schema.py +367 -0
- mlflow/optuna/__init__.py +3 -0
- mlflow/optuna/storage.py +646 -0
- mlflow/plugins/__init__.py +72 -0
- mlflow/plugins/base.py +358 -0
- mlflow/plugins/builtin/__init__.py +24 -0
- mlflow/plugins/builtin/pytorch_plugin.py +150 -0
- mlflow/plugins/builtin/sklearn_plugin.py +158 -0
- mlflow/plugins/builtin/transformers_plugin.py +187 -0
- mlflow/plugins/cli.py +321 -0
- mlflow/plugins/discovery.py +340 -0
- mlflow/plugins/manager.py +465 -0
- mlflow/plugins/registry.py +316 -0
- mlflow/plugins/templates/framework_plugin_template.py +329 -0
- mlflow/prompt/constants.py +20 -0
- mlflow/prompt/promptlab_model.py +197 -0
- mlflow/prompt/registry_utils.py +248 -0
- mlflow/promptflow/__init__.py +495 -0
- mlflow/protos/__init__.py +0 -0
- mlflow/protos/assessments_pb2.py +174 -0
- mlflow/protos/databricks_artifacts_pb2.py +489 -0
- mlflow/protos/databricks_filesystem_service_pb2.py +196 -0
- mlflow/protos/databricks_managed_catalog_messages_pb2.py +95 -0
- mlflow/protos/databricks_managed_catalog_service_pb2.py +86 -0
- mlflow/protos/databricks_pb2.py +267 -0
- mlflow/protos/databricks_trace_server_pb2.py +374 -0
- mlflow/protos/databricks_uc_registry_messages_pb2.py +1249 -0
- mlflow/protos/databricks_uc_registry_service_pb2.py +170 -0
- mlflow/protos/facet_feature_statistics_pb2.py +296 -0
- mlflow/protos/internal_pb2.py +77 -0
- mlflow/protos/mlflow_artifacts_pb2.py +336 -0
- mlflow/protos/model_registry_pb2.py +1073 -0
- mlflow/protos/scalapb/__init__.py +0 -0
- mlflow/protos/scalapb/scalapb_pb2.py +104 -0
- mlflow/protos/service_pb2.py +2600 -0
- mlflow/protos/unity_catalog_oss_messages_pb2.py +457 -0
- mlflow/protos/unity_catalog_oss_service_pb2.py +130 -0
- mlflow/protos/unity_catalog_prompt_messages_pb2.py +447 -0
- mlflow/protos/unity_catalog_prompt_messages_pb2_grpc.py +24 -0
- mlflow/protos/unity_catalog_prompt_service_pb2.py +164 -0
- mlflow/protos/unity_catalog_prompt_service_pb2_grpc.py +785 -0
- mlflow/py.typed +0 -0
- mlflow/pydantic_ai/__init__.py +57 -0
- mlflow/pydantic_ai/autolog.py +173 -0
- mlflow/pyfunc/__init__.py +3844 -0
- mlflow/pyfunc/_mlflow_pyfunc_backend_predict.py +61 -0
- mlflow/pyfunc/backend.py +523 -0
- mlflow/pyfunc/context.py +78 -0
- mlflow/pyfunc/dbconnect_artifact_cache.py +144 -0
- mlflow/pyfunc/loaders/__init__.py +7 -0
- mlflow/pyfunc/loaders/chat_agent.py +117 -0
- mlflow/pyfunc/loaders/chat_model.py +125 -0
- mlflow/pyfunc/loaders/code_model.py +31 -0
- mlflow/pyfunc/loaders/responses_agent.py +112 -0
- mlflow/pyfunc/mlserver.py +46 -0
- mlflow/pyfunc/model.py +1473 -0
- mlflow/pyfunc/scoring_server/__init__.py +604 -0
- mlflow/pyfunc/scoring_server/app.py +7 -0
- mlflow/pyfunc/scoring_server/client.py +146 -0
- mlflow/pyfunc/spark_model_cache.py +48 -0
- mlflow/pyfunc/stdin_server.py +44 -0
- mlflow/pyfunc/utils/__init__.py +3 -0
- mlflow/pyfunc/utils/data_validation.py +224 -0
- mlflow/pyfunc/utils/environment.py +22 -0
- mlflow/pyfunc/utils/input_converter.py +47 -0
- mlflow/pyfunc/utils/serving_data_parser.py +11 -0
- mlflow/pytorch/__init__.py +1171 -0
- mlflow/pytorch/_lightning_autolog.py +580 -0
- mlflow/pytorch/_pytorch_autolog.py +50 -0
- mlflow/pytorch/pickle_module.py +35 -0
- mlflow/rfunc/__init__.py +42 -0
- mlflow/rfunc/backend.py +134 -0
- mlflow/runs.py +89 -0
- mlflow/server/__init__.py +302 -0
- mlflow/server/auth/__init__.py +1224 -0
- mlflow/server/auth/__main__.py +4 -0
- mlflow/server/auth/basic_auth.ini +6 -0
- mlflow/server/auth/cli.py +11 -0
- mlflow/server/auth/client.py +537 -0
- mlflow/server/auth/config.py +34 -0
- mlflow/server/auth/db/__init__.py +0 -0
- mlflow/server/auth/db/cli.py +18 -0
- mlflow/server/auth/db/migrations/__init__.py +0 -0
- mlflow/server/auth/db/migrations/alembic.ini +110 -0
- mlflow/server/auth/db/migrations/env.py +76 -0
- mlflow/server/auth/db/migrations/versions/8606fa83a998_initial_migration.py +51 -0
- mlflow/server/auth/db/migrations/versions/__init__.py +0 -0
- mlflow/server/auth/db/models.py +67 -0
- mlflow/server/auth/db/utils.py +37 -0
- mlflow/server/auth/entities.py +165 -0
- mlflow/server/auth/logo.py +14 -0
- mlflow/server/auth/permissions.py +65 -0
- mlflow/server/auth/routes.py +18 -0
- mlflow/server/auth/sqlalchemy_store.py +263 -0
- mlflow/server/graphql/__init__.py +0 -0
- mlflow/server/graphql/autogenerated_graphql_schema.py +353 -0
- mlflow/server/graphql/graphql_custom_scalars.py +24 -0
- mlflow/server/graphql/graphql_errors.py +15 -0
- mlflow/server/graphql/graphql_no_batching.py +89 -0
- mlflow/server/graphql/graphql_schema_extensions.py +74 -0
- mlflow/server/handlers.py +3217 -0
- mlflow/server/prometheus_exporter.py +17 -0
- mlflow/server/validation.py +30 -0
- mlflow/shap/__init__.py +691 -0
- mlflow/sklearn/__init__.py +1994 -0
- mlflow/sklearn/utils.py +1041 -0
- mlflow/smolagents/__init__.py +66 -0
- mlflow/smolagents/autolog.py +139 -0
- mlflow/smolagents/chat.py +29 -0
- mlflow/store/__init__.py +10 -0
- mlflow/store/_unity_catalog/__init__.py +1 -0
- mlflow/store/_unity_catalog/lineage/__init__.py +1 -0
- mlflow/store/_unity_catalog/lineage/constants.py +2 -0
- mlflow/store/_unity_catalog/registry/__init__.py +6 -0
- mlflow/store/_unity_catalog/registry/prompt_info.py +75 -0
- mlflow/store/_unity_catalog/registry/rest_store.py +1740 -0
- mlflow/store/_unity_catalog/registry/uc_oss_rest_store.py +507 -0
- mlflow/store/_unity_catalog/registry/utils.py +121 -0
- mlflow/store/artifact/__init__.py +0 -0
- mlflow/store/artifact/artifact_repo.py +472 -0
- mlflow/store/artifact/artifact_repository_registry.py +154 -0
- mlflow/store/artifact/azure_blob_artifact_repo.py +275 -0
- mlflow/store/artifact/azure_data_lake_artifact_repo.py +295 -0
- mlflow/store/artifact/cli.py +141 -0
- mlflow/store/artifact/cloud_artifact_repo.py +332 -0
- mlflow/store/artifact/databricks_artifact_repo.py +729 -0
- mlflow/store/artifact/databricks_artifact_repo_resources.py +301 -0
- mlflow/store/artifact/databricks_logged_model_artifact_repo.py +93 -0
- mlflow/store/artifact/databricks_models_artifact_repo.py +216 -0
- mlflow/store/artifact/databricks_sdk_artifact_repo.py +134 -0
- mlflow/store/artifact/databricks_sdk_models_artifact_repo.py +97 -0
- mlflow/store/artifact/dbfs_artifact_repo.py +240 -0
- mlflow/store/artifact/ftp_artifact_repo.py +132 -0
- mlflow/store/artifact/gcs_artifact_repo.py +296 -0
- mlflow/store/artifact/hdfs_artifact_repo.py +209 -0
- mlflow/store/artifact/http_artifact_repo.py +218 -0
- mlflow/store/artifact/local_artifact_repo.py +142 -0
- mlflow/store/artifact/mlflow_artifacts_repo.py +94 -0
- mlflow/store/artifact/models_artifact_repo.py +259 -0
- mlflow/store/artifact/optimized_s3_artifact_repo.py +356 -0
- mlflow/store/artifact/presigned_url_artifact_repo.py +173 -0
- mlflow/store/artifact/r2_artifact_repo.py +70 -0
- mlflow/store/artifact/runs_artifact_repo.py +265 -0
- mlflow/store/artifact/s3_artifact_repo.py +330 -0
- mlflow/store/artifact/sftp_artifact_repo.py +141 -0
- mlflow/store/artifact/uc_volume_artifact_repo.py +76 -0
- mlflow/store/artifact/unity_catalog_models_artifact_repo.py +168 -0
- mlflow/store/artifact/unity_catalog_oss_models_artifact_repo.py +168 -0
- mlflow/store/artifact/utils/__init__.py +0 -0
- mlflow/store/artifact/utils/models.py +148 -0
- mlflow/store/db/__init__.py +0 -0
- mlflow/store/db/base_sql_model.py +3 -0
- mlflow/store/db/db_types.py +10 -0
- mlflow/store/db/utils.py +314 -0
- mlflow/store/db_migrations/__init__.py +0 -0
- mlflow/store/db_migrations/alembic.ini +74 -0
- mlflow/store/db_migrations/env.py +84 -0
- mlflow/store/db_migrations/versions/0584bdc529eb_add_cascading_deletion_to_datasets_from_experiments.py +88 -0
- mlflow/store/db_migrations/versions/0a8213491aaa_drop_duplicate_killed_constraint.py +49 -0
- mlflow/store/db_migrations/versions/0c779009ac13_add_deleted_time_field_to_runs_table.py +24 -0
- mlflow/store/db_migrations/versions/181f10493468_allow_nulls_for_metric_values.py +35 -0
- mlflow/store/db_migrations/versions/27a6a02d2cf1_add_model_version_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/2b4d017a5e9b_add_model_registry_tables_to_db.py +77 -0
- mlflow/store/db_migrations/versions/2d6e25af4d3e_increase_max_param_val_length.py +33 -0
- mlflow/store/db_migrations/versions/3500859a5d39_add_model_aliases_table.py +50 -0
- mlflow/store/db_migrations/versions/39d1c3be5f05_add_is_nan_constraint_for_metrics_tables_if_necessary.py +41 -0
- mlflow/store/db_migrations/versions/400f98739977_add_logged_model_tables.py +123 -0
- mlflow/store/db_migrations/versions/4465047574b1_increase_max_dataset_schema_size.py +38 -0
- mlflow/store/db_migrations/versions/451aebb31d03_add_metric_step.py +35 -0
- mlflow/store/db_migrations/versions/5b0e9adcef9c_add_cascade_deletion_to_trace_tables_fk.py +40 -0
- mlflow/store/db_migrations/versions/6953534de441_add_step_to_inputs_table.py +25 -0
- mlflow/store/db_migrations/versions/728d730b5ebd_add_registered_model_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/7ac759974ad8_update_run_tags_with_larger_limit.py +36 -0
- mlflow/store/db_migrations/versions/7f2a7d5fae7d_add_datasets_inputs_input_tags_tables.py +82 -0
- mlflow/store/db_migrations/versions/84291f40a231_add_run_link_to_model_version.py +26 -0
- mlflow/store/db_migrations/versions/867495a8f9d4_add_trace_tables.py +90 -0
- mlflow/store/db_migrations/versions/89d4b8295536_create_latest_metrics_table.py +169 -0
- mlflow/store/db_migrations/versions/90e64c465722_migrate_user_column_to_tags.py +64 -0
- mlflow/store/db_migrations/versions/97727af70f4d_creation_time_last_update_time_experiments.py +25 -0
- mlflow/store/db_migrations/versions/__init__.py +0 -0
- mlflow/store/db_migrations/versions/a8c4a736bde6_allow_nulls_for_run_id.py +27 -0
- mlflow/store/db_migrations/versions/acf3f17fdcc7_add_storage_location_field_to_model_.py +29 -0
- mlflow/store/db_migrations/versions/bd07f7e963c5_create_index_on_run_uuid.py +26 -0
- mlflow/store/db_migrations/versions/bda7b8c39065_increase_model_version_tag_value_limit.py +38 -0
- mlflow/store/db_migrations/versions/c48cb773bb87_reset_default_value_for_is_nan_in_metrics_table_for_mysql.py +41 -0
- mlflow/store/db_migrations/versions/cbc13b556ace_add_v3_trace_schema_columns.py +31 -0
- mlflow/store/db_migrations/versions/cc1f77228345_change_param_value_length_to_500.py +34 -0
- mlflow/store/db_migrations/versions/cfd24bdc0731_update_run_status_constraint_with_killed.py +78 -0
- mlflow/store/db_migrations/versions/df50e92ffc5e_add_experiment_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/f5a4f2784254_increase_run_tag_value_limit.py +36 -0
- mlflow/store/entities/__init__.py +3 -0
- mlflow/store/entities/paged_list.py +18 -0
- mlflow/store/model_registry/__init__.py +10 -0
- mlflow/store/model_registry/abstract_store.py +1081 -0
- mlflow/store/model_registry/base_rest_store.py +44 -0
- mlflow/store/model_registry/databricks_workspace_model_registry_rest_store.py +37 -0
- mlflow/store/model_registry/dbmodels/__init__.py +0 -0
- mlflow/store/model_registry/dbmodels/models.py +206 -0
- mlflow/store/model_registry/file_store.py +1091 -0
- mlflow/store/model_registry/rest_store.py +481 -0
- mlflow/store/model_registry/sqlalchemy_store.py +1286 -0
- mlflow/store/tracking/__init__.py +23 -0
- mlflow/store/tracking/abstract_store.py +816 -0
- mlflow/store/tracking/dbmodels/__init__.py +0 -0
- mlflow/store/tracking/dbmodels/initial_models.py +243 -0
- mlflow/store/tracking/dbmodels/models.py +1073 -0
- mlflow/store/tracking/file_store.py +2438 -0
- mlflow/store/tracking/postgres_managed_identity.py +146 -0
- mlflow/store/tracking/rest_store.py +1131 -0
- mlflow/store/tracking/sqlalchemy_store.py +2785 -0
- mlflow/system_metrics/__init__.py +61 -0
- mlflow/system_metrics/metrics/__init__.py +0 -0
- mlflow/system_metrics/metrics/base_metrics_monitor.py +32 -0
- mlflow/system_metrics/metrics/cpu_monitor.py +23 -0
- mlflow/system_metrics/metrics/disk_monitor.py +21 -0
- mlflow/system_metrics/metrics/gpu_monitor.py +71 -0
- mlflow/system_metrics/metrics/network_monitor.py +34 -0
- mlflow/system_metrics/metrics/rocm_monitor.py +123 -0
- mlflow/system_metrics/system_metrics_monitor.py +198 -0
- mlflow/tracing/__init__.py +16 -0
- mlflow/tracing/assessment.py +356 -0
- mlflow/tracing/client.py +531 -0
- mlflow/tracing/config.py +125 -0
- mlflow/tracing/constant.py +105 -0
- mlflow/tracing/destination.py +81 -0
- mlflow/tracing/display/__init__.py +40 -0
- mlflow/tracing/display/display_handler.py +196 -0
- mlflow/tracing/export/async_export_queue.py +186 -0
- mlflow/tracing/export/inference_table.py +138 -0
- mlflow/tracing/export/mlflow_v3.py +137 -0
- mlflow/tracing/export/utils.py +70 -0
- mlflow/tracing/fluent.py +1417 -0
- mlflow/tracing/processor/base_mlflow.py +199 -0
- mlflow/tracing/processor/inference_table.py +175 -0
- mlflow/tracing/processor/mlflow_v3.py +47 -0
- mlflow/tracing/processor/otel.py +73 -0
- mlflow/tracing/provider.py +487 -0
- mlflow/tracing/trace_manager.py +200 -0
- mlflow/tracing/utils/__init__.py +616 -0
- mlflow/tracing/utils/artifact_utils.py +28 -0
- mlflow/tracing/utils/copy.py +55 -0
- mlflow/tracing/utils/environment.py +55 -0
- mlflow/tracing/utils/exception.py +21 -0
- mlflow/tracing/utils/once.py +35 -0
- mlflow/tracing/utils/otlp.py +63 -0
- mlflow/tracing/utils/processor.py +54 -0
- mlflow/tracing/utils/search.py +292 -0
- mlflow/tracing/utils/timeout.py +250 -0
- mlflow/tracing/utils/token.py +19 -0
- mlflow/tracing/utils/truncation.py +124 -0
- mlflow/tracing/utils/warning.py +76 -0
- mlflow/tracking/__init__.py +39 -0
- mlflow/tracking/_model_registry/__init__.py +1 -0
- mlflow/tracking/_model_registry/client.py +764 -0
- mlflow/tracking/_model_registry/fluent.py +853 -0
- mlflow/tracking/_model_registry/registry.py +67 -0
- mlflow/tracking/_model_registry/utils.py +251 -0
- mlflow/tracking/_tracking_service/__init__.py +0 -0
- mlflow/tracking/_tracking_service/client.py +883 -0
- mlflow/tracking/_tracking_service/registry.py +56 -0
- mlflow/tracking/_tracking_service/utils.py +275 -0
- mlflow/tracking/artifact_utils.py +179 -0
- mlflow/tracking/client.py +5900 -0
- mlflow/tracking/context/__init__.py +0 -0
- mlflow/tracking/context/abstract_context.py +35 -0
- mlflow/tracking/context/databricks_cluster_context.py +15 -0
- mlflow/tracking/context/databricks_command_context.py +15 -0
- mlflow/tracking/context/databricks_job_context.py +49 -0
- mlflow/tracking/context/databricks_notebook_context.py +41 -0
- mlflow/tracking/context/databricks_repo_context.py +43 -0
- mlflow/tracking/context/default_context.py +51 -0
- mlflow/tracking/context/git_context.py +32 -0
- mlflow/tracking/context/registry.py +98 -0
- mlflow/tracking/context/system_environment_context.py +15 -0
- mlflow/tracking/default_experiment/__init__.py +1 -0
- mlflow/tracking/default_experiment/abstract_context.py +43 -0
- mlflow/tracking/default_experiment/databricks_notebook_experiment_provider.py +44 -0
- mlflow/tracking/default_experiment/registry.py +75 -0
- mlflow/tracking/fluent.py +3595 -0
- mlflow/tracking/metric_value_conversion_utils.py +93 -0
- mlflow/tracking/multimedia.py +206 -0
- mlflow/tracking/registry.py +86 -0
- mlflow/tracking/request_auth/__init__.py +0 -0
- mlflow/tracking/request_auth/abstract_request_auth_provider.py +34 -0
- mlflow/tracking/request_auth/registry.py +60 -0
- mlflow/tracking/request_header/__init__.py +0 -0
- mlflow/tracking/request_header/abstract_request_header_provider.py +36 -0
- mlflow/tracking/request_header/databricks_request_header_provider.py +38 -0
- mlflow/tracking/request_header/default_request_header_provider.py +17 -0
- mlflow/tracking/request_header/registry.py +79 -0
- mlflow/transformers/__init__.py +2982 -0
- mlflow/transformers/flavor_config.py +258 -0
- mlflow/transformers/hub_utils.py +83 -0
- mlflow/transformers/llm_inference_utils.py +468 -0
- mlflow/transformers/model_io.py +301 -0
- mlflow/transformers/peft.py +51 -0
- mlflow/transformers/signature.py +183 -0
- mlflow/transformers/torch_utils.py +55 -0
- mlflow/types/__init__.py +21 -0
- mlflow/types/agent.py +270 -0
- mlflow/types/chat.py +240 -0
- mlflow/types/llm.py +935 -0
- mlflow/types/responses.py +139 -0
- mlflow/types/responses_helpers.py +416 -0
- mlflow/types/schema.py +1505 -0
- mlflow/types/type_hints.py +647 -0
- mlflow/types/utils.py +753 -0
- mlflow/utils/__init__.py +283 -0
- mlflow/utils/_capture_modules.py +256 -0
- mlflow/utils/_capture_transformers_modules.py +75 -0
- mlflow/utils/_spark_utils.py +201 -0
- mlflow/utils/_unity_catalog_oss_utils.py +97 -0
- mlflow/utils/_unity_catalog_utils.py +479 -0
- mlflow/utils/annotations.py +218 -0
- mlflow/utils/arguments_utils.py +16 -0
- mlflow/utils/async_logging/__init__.py +1 -0
- mlflow/utils/async_logging/async_artifacts_logging_queue.py +258 -0
- mlflow/utils/async_logging/async_logging_queue.py +366 -0
- mlflow/utils/async_logging/run_artifact.py +38 -0
- mlflow/utils/async_logging/run_batch.py +58 -0
- mlflow/utils/async_logging/run_operations.py +49 -0
- mlflow/utils/autologging_utils/__init__.py +737 -0
- mlflow/utils/autologging_utils/client.py +432 -0
- mlflow/utils/autologging_utils/config.py +33 -0
- mlflow/utils/autologging_utils/events.py +294 -0
- mlflow/utils/autologging_utils/logging_and_warnings.py +328 -0
- mlflow/utils/autologging_utils/metrics_queue.py +71 -0
- mlflow/utils/autologging_utils/safety.py +1104 -0
- mlflow/utils/autologging_utils/versioning.py +95 -0
- mlflow/utils/checkpoint_utils.py +206 -0
- mlflow/utils/class_utils.py +6 -0
- mlflow/utils/cli_args.py +257 -0
- mlflow/utils/conda.py +354 -0
- mlflow/utils/credentials.py +231 -0
- mlflow/utils/data_utils.py +17 -0
- mlflow/utils/databricks_utils.py +1436 -0
- mlflow/utils/docstring_utils.py +477 -0
- mlflow/utils/doctor.py +133 -0
- mlflow/utils/download_cloud_file_chunk.py +43 -0
- mlflow/utils/env_manager.py +16 -0
- mlflow/utils/env_pack.py +131 -0
- mlflow/utils/environment.py +1009 -0
- mlflow/utils/exception_utils.py +14 -0
- mlflow/utils/file_utils.py +978 -0
- mlflow/utils/git_utils.py +77 -0
- mlflow/utils/gorilla.py +797 -0
- mlflow/utils/import_hooks/__init__.py +363 -0
- mlflow/utils/lazy_load.py +51 -0
- mlflow/utils/logging_utils.py +168 -0
- mlflow/utils/mime_type_utils.py +58 -0
- mlflow/utils/mlflow_tags.py +103 -0
- mlflow/utils/model_utils.py +486 -0
- mlflow/utils/name_utils.py +346 -0
- mlflow/utils/nfs_on_spark.py +62 -0
- mlflow/utils/openai_utils.py +164 -0
- mlflow/utils/os.py +12 -0
- mlflow/utils/oss_registry_utils.py +29 -0
- mlflow/utils/plugins.py +17 -0
- mlflow/utils/process.py +182 -0
- mlflow/utils/promptlab_utils.py +146 -0
- mlflow/utils/proto_json_utils.py +743 -0
- mlflow/utils/pydantic_utils.py +54 -0
- mlflow/utils/request_utils.py +279 -0
- mlflow/utils/requirements_utils.py +704 -0
- mlflow/utils/rest_utils.py +673 -0
- mlflow/utils/search_logged_model_utils.py +127 -0
- mlflow/utils/search_utils.py +2111 -0
- mlflow/utils/secure_loading.py +221 -0
- mlflow/utils/security_validation.py +384 -0
- mlflow/utils/server_cli_utils.py +61 -0
- mlflow/utils/spark_utils.py +15 -0
- mlflow/utils/string_utils.py +138 -0
- mlflow/utils/thread_utils.py +63 -0
- mlflow/utils/time.py +54 -0
- mlflow/utils/timeout.py +42 -0
- mlflow/utils/uri.py +572 -0
- mlflow/utils/validation.py +662 -0
- mlflow/utils/virtualenv.py +458 -0
- mlflow/utils/warnings_utils.py +25 -0
- mlflow/utils/yaml_utils.py +179 -0
- mlflow/version.py +24 -0
mlflow/utils/__init__.py
ADDED
@@ -0,0 +1,283 @@
|
|
1
|
+
import inspect
|
2
|
+
import logging
|
3
|
+
import socket
|
4
|
+
import subprocess
|
5
|
+
import uuid
|
6
|
+
from contextlib import closing
|
7
|
+
from itertools import islice
|
8
|
+
from sys import version_info
|
9
|
+
|
10
|
+
from mlflow.utils.pydantic_utils import IS_PYDANTIC_V2_OR_NEWER # noqa: F401
|
11
|
+
|
12
|
+
PYTHON_VERSION = f"{version_info.major}.{version_info.minor}.{version_info.micro}"
|
13
|
+
|
14
|
+
|
15
|
+
_logger = logging.getLogger(__name__)
|
16
|
+
|
17
|
+
|
18
|
+
def get_major_minor_py_version(py_version):
|
19
|
+
return ".".join(py_version.split(".")[:2])
|
20
|
+
|
21
|
+
|
22
|
+
def reraise(tp, value, tb=None):
|
23
|
+
# Taken from: https://github.com/benjaminp/six/blob/1.15.0/six.py#L694-L700
|
24
|
+
try:
|
25
|
+
if value is None:
|
26
|
+
value = tp()
|
27
|
+
if value.__traceback__ is not tb:
|
28
|
+
raise value.with_traceback(tb)
|
29
|
+
raise value
|
30
|
+
finally:
|
31
|
+
value = None
|
32
|
+
tb = None
|
33
|
+
|
34
|
+
|
35
|
+
def chunk_list(l, chunk_size):
|
36
|
+
for i in range(0, len(l), chunk_size):
|
37
|
+
yield l[i : i + chunk_size]
|
38
|
+
|
39
|
+
|
40
|
+
def _chunk_dict(d, chunk_size):
|
41
|
+
"""
|
42
|
+
Splits a dictionary into chunks of the specified size.
|
43
|
+
Taken from: https://stackoverflow.com/a/22878842
|
44
|
+
"""
|
45
|
+
it = iter(d)
|
46
|
+
for _ in range(0, len(d), chunk_size):
|
47
|
+
yield {k: d[k] for k in islice(it, chunk_size)}
|
48
|
+
|
49
|
+
|
50
|
+
def _truncate_and_ellipsize(value, max_length):
|
51
|
+
"""
|
52
|
+
Truncates the string representation of the specified value to the specified
|
53
|
+
maximum length, if necessary. The end of the string is ellipsized if truncation occurs
|
54
|
+
"""
|
55
|
+
value = str(value)
|
56
|
+
if len(value) > max_length:
|
57
|
+
return value[: (max_length - 3)] + "..."
|
58
|
+
else:
|
59
|
+
return value
|
60
|
+
|
61
|
+
|
62
|
+
def _truncate_dict(d, max_key_length=None, max_value_length=None):
|
63
|
+
"""
|
64
|
+
Truncates keys and/or values in a dictionary to the specified maximum length.
|
65
|
+
Truncated items will be converted to strings and ellipsized.
|
66
|
+
"""
|
67
|
+
key_is_none = max_key_length is None
|
68
|
+
val_is_none = max_value_length is None
|
69
|
+
|
70
|
+
if key_is_none and val_is_none:
|
71
|
+
raise ValueError("Must specify at least either `max_key_length` or `max_value_length`")
|
72
|
+
|
73
|
+
truncated = {}
|
74
|
+
for k, v in d.items():
|
75
|
+
should_truncate_key = (not key_is_none) and (len(str(k)) > max_key_length)
|
76
|
+
should_truncate_val = (not val_is_none) and (len(str(v)) > max_value_length)
|
77
|
+
|
78
|
+
new_k = _truncate_and_ellipsize(k, max_key_length) if should_truncate_key else k
|
79
|
+
if should_truncate_key:
|
80
|
+
# Use the truncated key for warning logs to avoid noisy printing to stdout
|
81
|
+
msg = f"Truncated the key `{new_k}`"
|
82
|
+
_logger.warning(msg)
|
83
|
+
|
84
|
+
new_v = _truncate_and_ellipsize(v, max_value_length) if should_truncate_val else v
|
85
|
+
if should_truncate_val:
|
86
|
+
# Use the truncated key and value for warning logs to avoid noisy printing to stdout
|
87
|
+
msg = f"Truncated the value of the key `{new_k}`. Truncated value: `{new_v}`"
|
88
|
+
_logger.warning(msg)
|
89
|
+
|
90
|
+
truncated[new_k] = new_v
|
91
|
+
|
92
|
+
return truncated
|
93
|
+
|
94
|
+
|
95
|
+
def merge_dicts(dict_a, dict_b, raise_on_duplicates=True):
|
96
|
+
"""This function takes two dictionaries and returns one singular merged dictionary.
|
97
|
+
|
98
|
+
Args:
|
99
|
+
dict_a: The first dictionary.
|
100
|
+
dict_b: The second dictionary.
|
101
|
+
raise_on_duplicates: If True, the function raises ValueError if there are duplicate keys.
|
102
|
+
Otherwise, duplicate keys in `dict_b` will override the ones in `dict_a`.
|
103
|
+
|
104
|
+
Returns:
|
105
|
+
A merged dictionary.
|
106
|
+
|
107
|
+
"""
|
108
|
+
duplicate_keys = dict_a.keys() & dict_b.keys()
|
109
|
+
if raise_on_duplicates and len(duplicate_keys) > 0:
|
110
|
+
raise ValueError(f"The two merging dictionaries contains duplicate keys: {duplicate_keys}.")
|
111
|
+
return {**dict_a, **dict_b}
|
112
|
+
|
113
|
+
|
114
|
+
def _get_fully_qualified_class_name(obj):
|
115
|
+
"""
|
116
|
+
Obtains the fully qualified class name of the given object.
|
117
|
+
"""
|
118
|
+
return obj.__class__.__module__ + "." + obj.__class__.__name__
|
119
|
+
|
120
|
+
|
121
|
+
def _inspect_original_var_name(var, fallback_name):
|
122
|
+
"""
|
123
|
+
Inspect variable name, will search above frames and fetch the same instance variable name
|
124
|
+
in the most outer frame.
|
125
|
+
If inspect failed, return fallback_name
|
126
|
+
"""
|
127
|
+
if var is None:
|
128
|
+
return fallback_name
|
129
|
+
try:
|
130
|
+
original_var_name = fallback_name
|
131
|
+
|
132
|
+
frame = inspect.currentframe().f_back
|
133
|
+
while frame is not None:
|
134
|
+
arg_info = inspect.getargvalues(frame)
|
135
|
+
|
136
|
+
fixed_args = [arg_info.locals[arg_name] for arg_name in arg_info.args]
|
137
|
+
varlen_args = list(arg_info.locals[arg_info.varargs]) if arg_info.varargs else []
|
138
|
+
keyword_args = (
|
139
|
+
list(arg_info.locals[arg_info.keywords].values()) if arg_info.keywords else []
|
140
|
+
)
|
141
|
+
|
142
|
+
all_args = fixed_args + varlen_args + keyword_args
|
143
|
+
|
144
|
+
# check whether `var` is in arg list first. If yes, go to check parent frame.
|
145
|
+
if any(var is arg for arg in all_args):
|
146
|
+
# the var is passed in from caller, check parent frame.
|
147
|
+
frame = frame.f_back
|
148
|
+
continue
|
149
|
+
|
150
|
+
for var_name, var_val in frame.f_locals.items():
|
151
|
+
if var_val is var:
|
152
|
+
original_var_name = var_name
|
153
|
+
break
|
154
|
+
|
155
|
+
break
|
156
|
+
|
157
|
+
return original_var_name
|
158
|
+
|
159
|
+
except Exception:
|
160
|
+
return fallback_name
|
161
|
+
|
162
|
+
|
163
|
+
def find_free_port():
|
164
|
+
"""
|
165
|
+
Find free socket port on local machine.
|
166
|
+
"""
|
167
|
+
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
|
168
|
+
s.bind(("", 0))
|
169
|
+
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
170
|
+
return s.getsockname()[1]
|
171
|
+
|
172
|
+
|
173
|
+
def check_port_connectivity():
|
174
|
+
port = find_free_port()
|
175
|
+
try:
|
176
|
+
with subprocess.Popen(
|
177
|
+
["nc", "-l", "-p", str(port)],
|
178
|
+
stdout=subprocess.DEVNULL,
|
179
|
+
stderr=subprocess.DEVNULL,
|
180
|
+
) as server:
|
181
|
+
with subprocess.Popen(
|
182
|
+
["nc", "-zv", "localhost", str(port)],
|
183
|
+
stdout=subprocess.DEVNULL,
|
184
|
+
stderr=subprocess.DEVNULL,
|
185
|
+
) as client:
|
186
|
+
client.wait()
|
187
|
+
server.terminate()
|
188
|
+
return client.returncode == 0
|
189
|
+
except Exception as e:
|
190
|
+
_logger.warning("Failed to check port connectivity: %s", e)
|
191
|
+
return False
|
192
|
+
|
193
|
+
|
194
|
+
def is_iterator(obj):
|
195
|
+
"""
|
196
|
+
Args:
|
197
|
+
obj: Any object.
|
198
|
+
|
199
|
+
Returns:
|
200
|
+
Boolean representing whether or not 'obj' is an iterator.
|
201
|
+
"""
|
202
|
+
return (hasattr(obj, "__next__") or hasattr(obj, "next")) and hasattr(obj, "__iter__")
|
203
|
+
|
204
|
+
|
205
|
+
def _is_in_ipython_notebook():
|
206
|
+
try:
|
207
|
+
from IPython import get_ipython
|
208
|
+
|
209
|
+
return get_ipython() is not None
|
210
|
+
except Exception:
|
211
|
+
return False
|
212
|
+
|
213
|
+
|
214
|
+
def get_results_from_paginated_fn(paginated_fn, max_results_per_page, max_results=None):
|
215
|
+
"""Gets results by calling the ``paginated_fn`` until either no more results remain or
|
216
|
+
the specified ``max_results`` threshold has been reached.
|
217
|
+
|
218
|
+
Args:
|
219
|
+
paginated_fn: This function is expected to take in the number of results to retrieve
|
220
|
+
per page and a pagination token, and return a PagedList object.
|
221
|
+
max_results_per_page: The maximum number of results to retrieve per page.
|
222
|
+
max_results: The maximum number of results to retrieve overall. If unspecified,
|
223
|
+
all results will be retrieved.
|
224
|
+
|
225
|
+
Returns:
|
226
|
+
Returns a list of entities, as determined by the paginated_fn parameter, with no more
|
227
|
+
entities than specified by max_results.
|
228
|
+
|
229
|
+
"""
|
230
|
+
all_results = []
|
231
|
+
next_page_token = None
|
232
|
+
returns_all = max_results is None
|
233
|
+
while returns_all or len(all_results) < max_results:
|
234
|
+
num_to_get = max_results_per_page if returns_all else max_results - len(all_results)
|
235
|
+
if num_to_get < max_results_per_page:
|
236
|
+
page_results = paginated_fn(num_to_get, next_page_token)
|
237
|
+
else:
|
238
|
+
page_results = paginated_fn(max_results_per_page, next_page_token)
|
239
|
+
all_results.extend(page_results)
|
240
|
+
if hasattr(page_results, "token") and page_results.token:
|
241
|
+
next_page_token = page_results.token
|
242
|
+
else:
|
243
|
+
break
|
244
|
+
return all_results
|
245
|
+
|
246
|
+
|
247
|
+
class AttrDict(dict):
|
248
|
+
"""
|
249
|
+
Dict-like object that exposes its keys as attributes.
|
250
|
+
|
251
|
+
Examples
|
252
|
+
--------
|
253
|
+
>>> d = AttrDict({"a": 1, "b": 2})
|
254
|
+
>>> d.a
|
255
|
+
1
|
256
|
+
>>> d = AttrDict({"a": 1, "b": {"c": 3, "d": 4}})
|
257
|
+
>>> d.b.c
|
258
|
+
3
|
259
|
+
"""
|
260
|
+
|
261
|
+
def __getattr__(self, attr):
|
262
|
+
try:
|
263
|
+
value = self[attr]
|
264
|
+
except KeyError:
|
265
|
+
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{attr}'")
|
266
|
+
if isinstance(value, dict):
|
267
|
+
return AttrDict(value)
|
268
|
+
return value
|
269
|
+
|
270
|
+
|
271
|
+
def get_parent_module(module):
|
272
|
+
return module[0 : module.rindex(".")]
|
273
|
+
|
274
|
+
|
275
|
+
def is_uuid(s: str) -> bool:
|
276
|
+
"""
|
277
|
+
Returns True if the specified string is a UUID, False otherwise.
|
278
|
+
"""
|
279
|
+
try:
|
280
|
+
uuid.UUID(s)
|
281
|
+
return True
|
282
|
+
except ValueError:
|
283
|
+
return False
|
@@ -0,0 +1,256 @@
|
|
1
|
+
"""
|
2
|
+
This script should be executed in a fresh python interpreter process using `subprocess`.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import argparse
|
6
|
+
import builtins
|
7
|
+
import functools
|
8
|
+
import importlib
|
9
|
+
import json
|
10
|
+
import os
|
11
|
+
import sys
|
12
|
+
|
13
|
+
import mlflow
|
14
|
+
from mlflow.models.model import MLMODEL_FILE_NAME, Model
|
15
|
+
from mlflow.pyfunc import MAIN
|
16
|
+
from mlflow.utils._spark_utils import _prepare_subprocess_environ_for_creating_local_spark_session
|
17
|
+
from mlflow.utils.exception_utils import get_stacktrace
|
18
|
+
from mlflow.utils.file_utils import write_to
|
19
|
+
from mlflow.utils.requirements_utils import (
|
20
|
+
DATABRICKS_MODULES_TO_PACKAGES,
|
21
|
+
MLFLOW_MODULES_TO_PACKAGES,
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
def _get_top_level_module(full_module_name):
|
26
|
+
return full_module_name.split(".")[0]
|
27
|
+
|
28
|
+
|
29
|
+
def _get_second_level_module(full_module_name):
|
30
|
+
return ".".join(full_module_name.split(".")[:2])
|
31
|
+
|
32
|
+
|
33
|
+
class _CaptureImportedModules:
|
34
|
+
"""
|
35
|
+
A context manager to capture imported modules by temporarily applying a patch to
|
36
|
+
`builtins.__import__` and `importlib.import_module`.
|
37
|
+
|
38
|
+
If `record_full_module` is set to `False`, it only captures top level modules
|
39
|
+
for inferring python package purpose.
|
40
|
+
If `record_full_module` is set to `True`, it captures full module name for all
|
41
|
+
imported modules and sub-modules. This is used in automatic model code path inference.
|
42
|
+
"""
|
43
|
+
|
44
|
+
def __init__(self, record_full_module=False):
|
45
|
+
self.imported_modules = set()
|
46
|
+
self.original_import = None
|
47
|
+
self.original_import_module = None
|
48
|
+
self.record_full_module = record_full_module
|
49
|
+
|
50
|
+
def _wrap_import(self, original):
|
51
|
+
@functools.wraps(original)
|
52
|
+
def wrapper(name, globals=None, locals=None, fromlist=(), level=0):
|
53
|
+
is_absolute_import = level == 0
|
54
|
+
if not self.record_full_module and is_absolute_import:
|
55
|
+
self._record_imported_module(name)
|
56
|
+
|
57
|
+
result = original(name, globals, locals, fromlist, level)
|
58
|
+
|
59
|
+
if self.record_full_module:
|
60
|
+
if is_absolute_import:
|
61
|
+
parent_modules = name.split(".")
|
62
|
+
else:
|
63
|
+
parent_modules = globals["__name__"].split(".")
|
64
|
+
if level > 1:
|
65
|
+
parent_modules = parent_modules[: -(level - 1)]
|
66
|
+
|
67
|
+
if fromlist:
|
68
|
+
for from_name in fromlist:
|
69
|
+
full_modules = parent_modules + [from_name]
|
70
|
+
full_module_name = ".".join(full_modules)
|
71
|
+
if full_module_name in sys.modules:
|
72
|
+
self._record_imported_module(full_module_name)
|
73
|
+
else:
|
74
|
+
full_module_name = ".".join(parent_modules)
|
75
|
+
self._record_imported_module(full_module_name)
|
76
|
+
|
77
|
+
return result
|
78
|
+
|
79
|
+
return wrapper
|
80
|
+
|
81
|
+
def _wrap_import_module(self, original):
|
82
|
+
@functools.wraps(original)
|
83
|
+
def wrapper(name, *args, **kwargs):
|
84
|
+
self._record_imported_module(name)
|
85
|
+
return original(name, *args, **kwargs)
|
86
|
+
|
87
|
+
return wrapper
|
88
|
+
|
89
|
+
def _record_imported_module(self, full_module_name):
|
90
|
+
if self.record_full_module:
|
91
|
+
self.imported_modules.add(full_module_name)
|
92
|
+
return
|
93
|
+
|
94
|
+
# If the module is an internal module (prefixed by "_") or is the "databricks"
|
95
|
+
# module, which is populated by many different packages, don't record it (specific
|
96
|
+
# module imports within the databricks namespace are still recorded and mapped to
|
97
|
+
# their corresponding packages)
|
98
|
+
if full_module_name.startswith("_") or full_module_name == "databricks":
|
99
|
+
return
|
100
|
+
|
101
|
+
top_level_module = _get_top_level_module(full_module_name)
|
102
|
+
second_level_module = _get_second_level_module(full_module_name)
|
103
|
+
|
104
|
+
if top_level_module == "databricks":
|
105
|
+
# Multiple packages populate the `databricks` module namespace on Databricks;
|
106
|
+
# to avoid bundling extraneous Databricks packages into model dependencies, we
|
107
|
+
# scope each module to its relevant package
|
108
|
+
if second_level_module in DATABRICKS_MODULES_TO_PACKAGES:
|
109
|
+
self.imported_modules.add(second_level_module)
|
110
|
+
return
|
111
|
+
|
112
|
+
for databricks_module in DATABRICKS_MODULES_TO_PACKAGES:
|
113
|
+
if full_module_name.startswith(databricks_module):
|
114
|
+
self.imported_modules.add(databricks_module)
|
115
|
+
return
|
116
|
+
|
117
|
+
# special casing for mlflow extras since they may not be required by default
|
118
|
+
if top_level_module == "mlflow":
|
119
|
+
if second_level_module in MLFLOW_MODULES_TO_PACKAGES:
|
120
|
+
self.imported_modules.add(second_level_module)
|
121
|
+
return
|
122
|
+
|
123
|
+
self.imported_modules.add(top_level_module)
|
124
|
+
|
125
|
+
def __enter__(self):
|
126
|
+
# Patch `builtins.__import__` and `importlib.import_module`
|
127
|
+
self.original_import = builtins.__import__
|
128
|
+
self.original_import_module = importlib.import_module
|
129
|
+
builtins.__import__ = self._wrap_import(self.original_import)
|
130
|
+
importlib.import_module = self._wrap_import_module(self.original_import_module)
|
131
|
+
return self
|
132
|
+
|
133
|
+
def __exit__(self, *_, **__):
|
134
|
+
# Revert the patches
|
135
|
+
builtins.__import__ = self.original_import
|
136
|
+
importlib.import_module = self.original_import_module
|
137
|
+
|
138
|
+
|
139
|
+
def parse_args():
|
140
|
+
parser = argparse.ArgumentParser()
|
141
|
+
parser.add_argument("--model-path", required=True)
|
142
|
+
parser.add_argument("--flavor", required=True)
|
143
|
+
parser.add_argument("--output-file", required=True)
|
144
|
+
parser.add_argument("--sys-path", required=True)
|
145
|
+
parser.add_argument("--module-to-throw", required=False)
|
146
|
+
parser.add_argument("--error-file", required=False)
|
147
|
+
parser.add_argument("--record-full-module", default=False, action="store_true")
|
148
|
+
return parser.parse_args()
|
149
|
+
|
150
|
+
|
151
|
+
def store_imported_modules(
|
152
|
+
cap_cm, model_path, flavor, output_file, error_file=None, record_full_module=False
|
153
|
+
):
|
154
|
+
# If `model_path` refers to an MLflow model directory, load the model using
|
155
|
+
# `mlflow.pyfunc.load_model`
|
156
|
+
if os.path.isdir(model_path) and MLMODEL_FILE_NAME in os.listdir(model_path):
|
157
|
+
mlflow_model = Model.load(model_path)
|
158
|
+
pyfunc_conf = mlflow_model.flavors.get(mlflow.pyfunc.FLAVOR_NAME)
|
159
|
+
input_example = mlflow_model.load_input_example(model_path)
|
160
|
+
params = mlflow_model.load_input_example_params(model_path)
|
161
|
+
|
162
|
+
def load_model_and_predict(original_load_fn, *args, **kwargs):
|
163
|
+
model = original_load_fn(*args, **kwargs)
|
164
|
+
if input_example is not None:
|
165
|
+
try:
|
166
|
+
model.predict(input_example, params=params)
|
167
|
+
except Exception as e:
|
168
|
+
if error_file:
|
169
|
+
stack_trace = get_stacktrace(e)
|
170
|
+
write_to(
|
171
|
+
error_file,
|
172
|
+
"Failed to run predict on input_example, dependencies "
|
173
|
+
"introduced in predict are not captured.\n" + stack_trace,
|
174
|
+
)
|
175
|
+
else:
|
176
|
+
raise e
|
177
|
+
return model
|
178
|
+
|
179
|
+
if record_full_module:
|
180
|
+
# Note: if we want to record all imported modules
|
181
|
+
# (for inferring code_paths purpose),
|
182
|
+
# The `importlib.import_module(pyfunc_conf[MAIN])` invocation
|
183
|
+
# must be wrapped with `cap_cm` context manager,
|
184
|
+
# because `pyfunc_conf[MAIN]` might also be a module loaded from
|
185
|
+
# code_paths.
|
186
|
+
with cap_cm:
|
187
|
+
# `mlflow.pyfunc.load_model` internally invokes
|
188
|
+
# `importlib.import_module(pyfunc_conf[MAIN])`
|
189
|
+
mlflow.pyfunc.load_model(model_path)
|
190
|
+
else:
|
191
|
+
loader_module = importlib.import_module(pyfunc_conf[MAIN])
|
192
|
+
original = loader_module._load_pyfunc
|
193
|
+
|
194
|
+
@functools.wraps(original)
|
195
|
+
def _load_pyfunc_patch(*args, **kwargs):
|
196
|
+
with cap_cm:
|
197
|
+
return load_model_and_predict(original, *args, **kwargs)
|
198
|
+
|
199
|
+
loader_module._load_pyfunc = _load_pyfunc_patch
|
200
|
+
try:
|
201
|
+
mlflow.pyfunc.load_model(model_path)
|
202
|
+
finally:
|
203
|
+
loader_module._load_pyfunc = original
|
204
|
+
# Otherwise, load the model using `mlflow.<flavor>._load_pyfunc`.
|
205
|
+
# For models that don't contain pyfunc flavor (e.g. scikit-learn estimator
|
206
|
+
# that doesn't implement a `predict` method),
|
207
|
+
# we need to directly pass a model data path to this script.
|
208
|
+
else:
|
209
|
+
with cap_cm:
|
210
|
+
importlib.import_module(f"mlflow.{flavor}")._load_pyfunc(model_path)
|
211
|
+
|
212
|
+
# Store the imported modules in `output_file`
|
213
|
+
write_to(output_file, "\n".join(cap_cm.imported_modules))
|
214
|
+
|
215
|
+
|
216
|
+
def main():
|
217
|
+
args = parse_args()
|
218
|
+
model_path = args.model_path
|
219
|
+
flavor = args.flavor
|
220
|
+
output_file = args.output_file
|
221
|
+
error_file = args.error_file
|
222
|
+
# Mirror `sys.path` of the parent process
|
223
|
+
sys.path = json.loads(args.sys_path)
|
224
|
+
|
225
|
+
if flavor == mlflow.spark.FLAVOR_NAME:
|
226
|
+
# Create a local spark environment within the subprocess
|
227
|
+
from mlflow.utils._spark_utils import _create_local_spark_session_for_loading_spark_model
|
228
|
+
|
229
|
+
_prepare_subprocess_environ_for_creating_local_spark_session()
|
230
|
+
_create_local_spark_session_for_loading_spark_model()
|
231
|
+
|
232
|
+
cap_cm = _CaptureImportedModules(record_full_module=args.record_full_module)
|
233
|
+
store_imported_modules(
|
234
|
+
cap_cm,
|
235
|
+
model_path,
|
236
|
+
flavor,
|
237
|
+
output_file,
|
238
|
+
error_file,
|
239
|
+
record_full_module=args.record_full_module,
|
240
|
+
)
|
241
|
+
|
242
|
+
# Clean up a spark session created by `mlflow.spark._load_pyfunc`
|
243
|
+
if flavor == mlflow.spark.FLAVOR_NAME:
|
244
|
+
from mlflow.utils._spark_utils import _get_active_spark_session
|
245
|
+
|
246
|
+
spark = _get_active_spark_session()
|
247
|
+
if spark:
|
248
|
+
try:
|
249
|
+
spark.stop()
|
250
|
+
except Exception:
|
251
|
+
# Swallow unexpected exceptions
|
252
|
+
pass
|
253
|
+
|
254
|
+
|
255
|
+
if __name__ == "__main__":
|
256
|
+
main()
|
@@ -0,0 +1,75 @@
|
|
1
|
+
"""
|
2
|
+
This script should be executed in a fresh python interpreter process using `subprocess`.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import json
|
6
|
+
import os
|
7
|
+
import sys
|
8
|
+
|
9
|
+
import mlflow
|
10
|
+
from mlflow.exceptions import MlflowException
|
11
|
+
from mlflow.protos.databricks_pb2 import INVALID_PARAMETER_VALUE
|
12
|
+
from mlflow.utils._capture_modules import (
|
13
|
+
_CaptureImportedModules,
|
14
|
+
parse_args,
|
15
|
+
store_imported_modules,
|
16
|
+
)
|
17
|
+
|
18
|
+
|
19
|
+
class _CaptureImportedModulesForHF(_CaptureImportedModules):
|
20
|
+
"""
|
21
|
+
A context manager to capture imported modules by temporarily applying a patch to
|
22
|
+
`builtins.__import__` and `importlib.import_module`.
|
23
|
+
Used for 'transformers' flavor only.
|
24
|
+
"""
|
25
|
+
|
26
|
+
def __init__(self, module_to_throw, record_full_module=False):
|
27
|
+
super().__init__(record_full_module=record_full_module)
|
28
|
+
self.module_to_throw = module_to_throw
|
29
|
+
|
30
|
+
def _record_imported_module(self, full_module_name):
|
31
|
+
if full_module_name == self.module_to_throw or full_module_name.startswith(
|
32
|
+
f"{self.module_to_throw}."
|
33
|
+
):
|
34
|
+
raise ImportError(f"Disabled package {full_module_name}")
|
35
|
+
return super()._record_imported_module(full_module_name)
|
36
|
+
|
37
|
+
|
38
|
+
def main():
|
39
|
+
args = parse_args()
|
40
|
+
model_path = args.model_path
|
41
|
+
flavor = args.flavor
|
42
|
+
output_file = args.output_file
|
43
|
+
module_to_throw = args.module_to_throw
|
44
|
+
# Mirror `sys.path` of the parent process
|
45
|
+
sys.path = json.loads(args.sys_path)
|
46
|
+
|
47
|
+
if flavor != mlflow.transformers.FLAVOR_NAME:
|
48
|
+
raise MlflowException(
|
49
|
+
f"This script is only applicable to '{mlflow.transformers.FLAVOR_NAME}' flavor, "
|
50
|
+
"if you're applying other flavors, please use _capture_modules script.",
|
51
|
+
)
|
52
|
+
|
53
|
+
if module_to_throw == "":
|
54
|
+
raise MlflowException("Please specify the module to throw.")
|
55
|
+
elif module_to_throw == "tensorflow":
|
56
|
+
if os.environ.get("USE_TORCH", None) != "TRUE":
|
57
|
+
raise MlflowException(
|
58
|
+
"The environment variable USE_TORCH has to be set to TRUE to disable Tensorflow.",
|
59
|
+
error_code=INVALID_PARAMETER_VALUE,
|
60
|
+
)
|
61
|
+
elif module_to_throw == "torch":
|
62
|
+
if os.environ.get("USE_TF", None) != "TRUE":
|
63
|
+
raise MlflowException(
|
64
|
+
"The environment variable USE_TF has to be set to TRUE to disable Pytorch.",
|
65
|
+
error_code=INVALID_PARAMETER_VALUE,
|
66
|
+
)
|
67
|
+
|
68
|
+
cap_cm = _CaptureImportedModulesForHF(
|
69
|
+
module_to_throw, record_full_module=args.record_full_module
|
70
|
+
)
|
71
|
+
store_imported_modules(cap_cm, model_path, flavor, output_file)
|
72
|
+
|
73
|
+
|
74
|
+
if __name__ == "__main__":
|
75
|
+
main()
|