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,477 @@
|
|
1
|
+
import textwrap
|
2
|
+
import warnings
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
from mlflow.ml_package_versions import _ML_PACKAGE_VERSIONS
|
6
|
+
from mlflow.utils.autologging_utils.versioning import (
|
7
|
+
get_min_max_version_and_pip_release,
|
8
|
+
)
|
9
|
+
|
10
|
+
|
11
|
+
def _create_placeholder(key: str):
|
12
|
+
return "{{ " + key + " }}"
|
13
|
+
|
14
|
+
|
15
|
+
def _replace_keys_with_placeholders(d: dict[str, Any]) -> dict[str, Any]:
|
16
|
+
return {_create_placeholder(k): v for k, v in d.items()}
|
17
|
+
|
18
|
+
|
19
|
+
def _get_indentation_of_key(line: str, placeholder: str) -> str:
|
20
|
+
index = line.find(placeholder)
|
21
|
+
return (index * " ") if index != -1 else ""
|
22
|
+
|
23
|
+
|
24
|
+
def _indent(text: str, indent: str) -> str:
|
25
|
+
"""Indent everything but first line in text."""
|
26
|
+
lines = text.splitlines()
|
27
|
+
if len(lines) <= 1:
|
28
|
+
return text
|
29
|
+
|
30
|
+
else:
|
31
|
+
first_line = lines[0]
|
32
|
+
subsequent_lines = "\n".join(list(lines[1:]))
|
33
|
+
indented_subsequent_lines = textwrap.indent(subsequent_lines, indent)
|
34
|
+
return first_line + "\n" + indented_subsequent_lines
|
35
|
+
|
36
|
+
|
37
|
+
def _replace_all(text: str, replacements: dict[str, str]) -> str:
|
38
|
+
"""
|
39
|
+
Replace all instances of replacements.keys() with their corresponding
|
40
|
+
values in text. The replacements will be inserted on the same line
|
41
|
+
with wrapping to the same level of indentation, for example:
|
42
|
+
|
43
|
+
```
|
44
|
+
Args:
|
45
|
+
param_1: {{ key }}
|
46
|
+
```
|
47
|
+
|
48
|
+
will become...
|
49
|
+
|
50
|
+
```
|
51
|
+
Args:
|
52
|
+
param_1: replaced_value_at same indentation as prior
|
53
|
+
and if there are more lines they will also
|
54
|
+
have the same indentation.
|
55
|
+
```
|
56
|
+
"""
|
57
|
+
for key, value in replacements.items():
|
58
|
+
if key in text:
|
59
|
+
indent = _get_indentation_of_key(text, key)
|
60
|
+
indented_value = _indent(value, indent)
|
61
|
+
text = text.replace(key, indented_value)
|
62
|
+
return text
|
63
|
+
|
64
|
+
|
65
|
+
class ParamDocs(dict):
|
66
|
+
"""
|
67
|
+
Represents a set of parameter documents in the docstring.
|
68
|
+
"""
|
69
|
+
|
70
|
+
def __repr__(self):
|
71
|
+
return f"ParamDocs({super().__repr__()})"
|
72
|
+
|
73
|
+
def format(self, **kwargs):
|
74
|
+
"""
|
75
|
+
Formats values to be substituted in via the format_docstring() method.
|
76
|
+
|
77
|
+
Args:
|
78
|
+
kwargs: A `dict` in the form of `{"< placeholder name >": "< value >"}`.
|
79
|
+
|
80
|
+
Returns:
|
81
|
+
A new `ParamDocs` instance with the formatted param docs.
|
82
|
+
|
83
|
+
.. code-block:: text
|
84
|
+
:caption: Example
|
85
|
+
|
86
|
+
>>> pd = ParamDocs(p1="{{ doc1 }}", p2="{{ doc2 }}")
|
87
|
+
>>> pd.format(doc1="foo", doc2="bar")
|
88
|
+
ParamDocs({'p1': 'foo', 'p2': 'bar'})
|
89
|
+
"""
|
90
|
+
replacements = _replace_keys_with_placeholders(kwargs)
|
91
|
+
return ParamDocs({k: _replace_all(v, replacements) for k, v in self.items()})
|
92
|
+
|
93
|
+
def format_docstring(self, docstring: str) -> str:
|
94
|
+
"""
|
95
|
+
Formats placeholders in `docstring`.
|
96
|
+
|
97
|
+
Args:
|
98
|
+
docstring: A docstring with placeholders to be replaced.
|
99
|
+
If provided with None, will return None.
|
100
|
+
|
101
|
+
.. code-block:: text
|
102
|
+
:caption: Example
|
103
|
+
|
104
|
+
>>> pd = ParamDocs(p1="doc1", p2="doc2
|
105
|
+
doc2 second line")
|
106
|
+
>>> docstring = '''
|
107
|
+
... Args:
|
108
|
+
... p1: {{ p1 }}
|
109
|
+
... p2: {{ p2 }}
|
110
|
+
... '''.strip()
|
111
|
+
>>> print(pd.format_docstring(docstring))
|
112
|
+
"""
|
113
|
+
if docstring is None:
|
114
|
+
return None
|
115
|
+
|
116
|
+
replacements = _replace_keys_with_placeholders(self)
|
117
|
+
lines = docstring.splitlines()
|
118
|
+
for i, line in enumerate(lines):
|
119
|
+
lines[i] = _replace_all(line, replacements)
|
120
|
+
|
121
|
+
return "\n".join(lines)
|
122
|
+
|
123
|
+
|
124
|
+
def format_docstring(param_docs):
|
125
|
+
"""
|
126
|
+
Returns a decorator that replaces param doc placeholders (e.g. '{{ param_name }}') in the
|
127
|
+
docstring of the decorated function.
|
128
|
+
|
129
|
+
Args:
|
130
|
+
param_docs: A `ParamDocs` instance or `dict`.
|
131
|
+
|
132
|
+
Returns:
|
133
|
+
A decorator to apply the formatting.
|
134
|
+
|
135
|
+
.. code-block:: text
|
136
|
+
:caption: Example
|
137
|
+
|
138
|
+
>>> param_docs = {"p1": "doc1", "p2": "doc2
|
139
|
+
doc2 second line"}
|
140
|
+
>>> @format_docstring(param_docs)
|
141
|
+
... def func(p1, p2):
|
142
|
+
... '''
|
143
|
+
... Args:
|
144
|
+
... p1: {{ p1 }}
|
145
|
+
... p2: {{ p2 }}
|
146
|
+
... '''
|
147
|
+
>>> import textwrap
|
148
|
+
>>> print(textwrap.dedent(func.__doc__).strip())
|
149
|
+
|
150
|
+
Args:
|
151
|
+
p1: doc1
|
152
|
+
p2: doc2
|
153
|
+
doc2 second line
|
154
|
+
"""
|
155
|
+
param_docs = ParamDocs(param_docs)
|
156
|
+
|
157
|
+
def decorator(func):
|
158
|
+
func.__doc__ = param_docs.format_docstring(func.__doc__)
|
159
|
+
return func
|
160
|
+
|
161
|
+
return decorator
|
162
|
+
|
163
|
+
|
164
|
+
# `{{ ... }}` represents a placeholder.
|
165
|
+
LOG_MODEL_PARAM_DOCS = ParamDocs(
|
166
|
+
{
|
167
|
+
"name": "Model name.",
|
168
|
+
"conda_env": (
|
169
|
+
"""Either a dictionary representation of a Conda environment or the path to a conda
|
170
|
+
environment yaml file. If provided, this describes the environment this model should be run in.
|
171
|
+
At a minimum, it should specify the dependencies contained in `get_default_conda_env()`.
|
172
|
+
If ``None``, a conda environment with pip requirements inferred by
|
173
|
+
:func:`mlflow.models.infer_pip_requirements` is added
|
174
|
+
to the model. If the requirement inference fails, it falls back to using
|
175
|
+
`get_default_pip_requirements`. pip requirements from ``conda_env`` are written to a pip
|
176
|
+
``requirements.txt`` file and the full conda environment is written to ``conda.yaml``.
|
177
|
+
The following is an *example* dictionary representation of a conda environment::
|
178
|
+
|
179
|
+
{
|
180
|
+
"name": "mlflow-env",
|
181
|
+
"channels": ["conda-forge"],
|
182
|
+
"dependencies": [
|
183
|
+
"python=3.8.15",
|
184
|
+
{
|
185
|
+
"pip": [
|
186
|
+
"{{ package_name }}==x.y.z"
|
187
|
+
],
|
188
|
+
},
|
189
|
+
],
|
190
|
+
}"""
|
191
|
+
),
|
192
|
+
"pip_requirements": (
|
193
|
+
"""Either an iterable of pip requirement strings
|
194
|
+
(e.g. ``["{{ package_name }}", "-r requirements.txt", "-c constraints.txt"]``) or the string path to
|
195
|
+
a pip requirements file on the local filesystem (e.g. ``"requirements.txt"``). If provided, this
|
196
|
+
describes the environment this model should be run in. If ``None``, a default list of requirements
|
197
|
+
is inferred by :func:`mlflow.models.infer_pip_requirements` from the current software environment.
|
198
|
+
If the requirement inference fails, it falls back to using `get_default_pip_requirements`.
|
199
|
+
Both requirements and constraints are automatically parsed and written to ``requirements.txt`` and
|
200
|
+
``constraints.txt`` files, respectively, and stored as part of the model. Requirements are also
|
201
|
+
written to the ``pip`` section of the model's conda environment (``conda.yaml``) file."""
|
202
|
+
),
|
203
|
+
"extra_pip_requirements": (
|
204
|
+
"""Either an iterable of pip
|
205
|
+
requirement strings
|
206
|
+
(e.g. ``["pandas", "-r requirements.txt", "-c constraints.txt"]``) or the string path to
|
207
|
+
a pip requirements file on the local filesystem (e.g. ``"requirements.txt"``). If provided, this
|
208
|
+
describes additional pip requirements that are appended to a default set of pip requirements
|
209
|
+
generated automatically based on the user's current software environment. Both requirements and
|
210
|
+
constraints are automatically parsed and written to ``requirements.txt`` and ``constraints.txt``
|
211
|
+
files, respectively, and stored as part of the model. Requirements are also written to the ``pip``
|
212
|
+
section of the model's conda environment (``conda.yaml``) file.
|
213
|
+
|
214
|
+
.. warning::
|
215
|
+
The following arguments can't be specified at the same time:
|
216
|
+
|
217
|
+
- ``conda_env``
|
218
|
+
- ``pip_requirements``
|
219
|
+
- ``extra_pip_requirements``
|
220
|
+
|
221
|
+
`This example <https://github.com/mlflow/mlflow/blob/master/examples/pip_requirements/pip_requirements.py>`_ demonstrates how to specify pip requirements using
|
222
|
+
``pip_requirements`` and ``extra_pip_requirements``.""" # noqa: E501
|
223
|
+
),
|
224
|
+
"signature": (
|
225
|
+
"""an instance of the :py:class:`ModelSignature <mlflow.models.ModelSignature>`
|
226
|
+
class that describes the model's inputs and outputs. If not specified but an
|
227
|
+
``input_example`` is supplied, a signature will be automatically inferred
|
228
|
+
based on the supplied input example and model. To disable automatic signature
|
229
|
+
inference when providing an input example, set ``signature`` to ``False``.
|
230
|
+
To manually infer a model signature, call
|
231
|
+
:py:func:`infer_signature() <mlflow.models.infer_signature>` on datasets
|
232
|
+
with valid model inputs, such as a training dataset with the target column
|
233
|
+
omitted, and valid model outputs, like model predictions made on the training
|
234
|
+
dataset, for example:
|
235
|
+
|
236
|
+
.. code-block:: python
|
237
|
+
|
238
|
+
from mlflow.models import infer_signature
|
239
|
+
|
240
|
+
train = df.drop_column("target_label")
|
241
|
+
predictions = ... # compute model predictions
|
242
|
+
signature = infer_signature(train, predictions)
|
243
|
+
"""
|
244
|
+
),
|
245
|
+
"metadata": (
|
246
|
+
"Custom metadata dictionary passed to the model and stored in the MLmodel file."
|
247
|
+
),
|
248
|
+
"input_example": (
|
249
|
+
"""one or several instances of valid model input. The input example is used
|
250
|
+
as a hint of what data to feed the model. It will be converted to a Pandas
|
251
|
+
DataFrame and then serialized to json using the Pandas split-oriented
|
252
|
+
format, or a numpy array where the example will be serialized to json
|
253
|
+
by converting it to a list. Bytes are base64-encoded. When the ``signature`` parameter is
|
254
|
+
``None``, the input example is used to infer a model signature.
|
255
|
+
"""
|
256
|
+
),
|
257
|
+
"prompt_template": (
|
258
|
+
"""A string that, if provided, will be used to format the user's input prior
|
259
|
+
to inference. The string should contain a single placeholder, ``{prompt}``, which will be
|
260
|
+
replaced with the user's input. For example: ``"Answer the following question. Q: {prompt} A:"``.
|
261
|
+
|
262
|
+
Currently, only the following pipeline types are supported:
|
263
|
+
|
264
|
+
- `feature-extraction <https://huggingface.co/transformers/main_classes/pipelines.html#transformers.FeatureExtractionPipeline>`_
|
265
|
+
- `fill-mask <https://huggingface.co/transformers/main_classes/pipelines.html#transformers.FillMaskPipeline>`_
|
266
|
+
- `summarization <https://huggingface.co/transformers/main_classes/pipelines.html#transformers.SummarizationPipeline>`_
|
267
|
+
- `text2text-generation <https://huggingface.co/transformers/main_classes/pipelines.html#transformers.Text2TextGenerationPipeline>`_
|
268
|
+
- `text-generation <https://huggingface.co/transformers/main_classes/pipelines.html#transformers.TextGenerationPipeline>`_
|
269
|
+
"""
|
270
|
+
),
|
271
|
+
"code_paths": (
|
272
|
+
"""A list of local filesystem paths to Python file dependencies (or directories
|
273
|
+
containing file dependencies). These files are *prepended* to the system path when the model
|
274
|
+
is loaded. Files declared as dependencies for a given model should have relative
|
275
|
+
imports declared from a common root path if multiple files are defined with import dependencies
|
276
|
+
between them to avoid import errors when loading the model.
|
277
|
+
|
278
|
+
For a detailed explanation of ``code_paths`` functionality, recommended usage patterns and
|
279
|
+
limitations, see the
|
280
|
+
`code_paths usage guide <https://mlflow.org/docs/latest/model/dependencies.html?highlight=code_paths#saving-extra-code-with-an-mlflow-model>`_.
|
281
|
+
"""
|
282
|
+
),
|
283
|
+
# Only pyfunc flavor supports `infer_code_paths`.
|
284
|
+
"code_paths_pyfunc": (
|
285
|
+
"""A list of local filesystem paths to Python file dependencies (or directories
|
286
|
+
containing file dependencies). These files are *prepended* to the system path when the model
|
287
|
+
is loaded. Files declared as dependencies for a given model should have relative
|
288
|
+
imports declared from a common root path if multiple files are defined with import dependencies
|
289
|
+
between them to avoid import errors when loading the model.
|
290
|
+
|
291
|
+
You can leave ``code_paths`` argument unset but set ``infer_code_paths`` to ``True`` to let MLflow
|
292
|
+
infer the model code paths. See ``infer_code_paths`` argument doc for details.
|
293
|
+
|
294
|
+
For a detailed explanation of ``code_paths`` functionality, recommended usage patterns and
|
295
|
+
limitations, see the
|
296
|
+
`code_paths usage guide <https://mlflow.org/docs/latest/model/dependencies.html?highlight=code_paths#saving-extra-code-with-an-mlflow-model>`_.
|
297
|
+
"""
|
298
|
+
),
|
299
|
+
"infer_code_paths": (
|
300
|
+
"""If set to ``True``, MLflow automatically infers model code paths. The inferred
|
301
|
+
code path files only include necessary python module files. Only python code files
|
302
|
+
under current working directory are automatically inferable. Default value is
|
303
|
+
``False``.
|
304
|
+
|
305
|
+
.. warning::
|
306
|
+
Please ensure that the custom python module code does not contain sensitive data such as
|
307
|
+
credential token strings, otherwise they might be included in the automatic inferred code
|
308
|
+
path files and be logged to MLflow artifact repository.
|
309
|
+
|
310
|
+
If your custom python module depends on non-python files (e.g. a JSON file) with a relative
|
311
|
+
path to the module code file path, the non-python files can't be automatically inferred as the
|
312
|
+
code path file. To address this issue, you should put all used non-python files outside
|
313
|
+
your custom code directory.
|
314
|
+
|
315
|
+
If a python code file is loaded as the python ``__main__`` module, then this code file can't be
|
316
|
+
inferred as the code path file. If your model depends on classes / functions defined in
|
317
|
+
``__main__`` module, you should use `cloudpickle` to dump your model instance in order to pickle
|
318
|
+
classes / functions in ``__main__``.
|
319
|
+
|
320
|
+
.. Note:: Experimental: This parameter may change or be removed in a future release without warning.
|
321
|
+
"""
|
322
|
+
),
|
323
|
+
"save_pretrained": (
|
324
|
+
"""If set to ``False``, MLflow will not save the Transformer model weight files,
|
325
|
+
instead only saving the reference to the HuggingFace Hub model repository and its commit hash.
|
326
|
+
This is useful when you load the pretrained model from HuggingFace Hub and want to log or save
|
327
|
+
it to MLflow without modifying the model weights. In such case, specifying this flag to
|
328
|
+
``False`` will save the storage space and reduce time to save the model. Please refer to the
|
329
|
+
`Storage-Efficient Model Logging
|
330
|
+
<../../llms/transformers/large-models.html#transformers-save-pretrained-guide>`_ for more detailed
|
331
|
+
usage.
|
332
|
+
|
333
|
+
|
334
|
+
.. warning::
|
335
|
+
|
336
|
+
If the model is saved with ``save_pretrained`` set to ``False``, the model cannot be
|
337
|
+
registered to the MLflow Model Registry. In order to convert the model to the one that
|
338
|
+
can be registered, you can use :py:func:`mlflow.transformers.persist_pretrained_model()`
|
339
|
+
to download the model weights from the HuggingFace Hub and save it in the existing model
|
340
|
+
artifacts. Please refer to `Transformers flavor documentation
|
341
|
+
<../../llms/transformers/large-models.html#persist-pretrained-guide>`_
|
342
|
+
for more detailed usage.
|
343
|
+
|
344
|
+
.. code-block:: python
|
345
|
+
|
346
|
+
import mlflow.transformers
|
347
|
+
|
348
|
+
model_uri = "YOUR_MODEL_URI_LOGGED_WITH_SAVE_PRETRAINED_FALSE"
|
349
|
+
model = mlflow.transformers.persist_pretrained_model(model_uri)
|
350
|
+
mlflow.register_model(model_uri, "model_name")
|
351
|
+
|
352
|
+
.. important::
|
353
|
+
|
354
|
+
When you save the `PEFT <https://huggingface.co/docs/peft/en/index>`_ model, MLflow will
|
355
|
+
override the `save_pretrained` flag to `False` and only store the PEFT adapter weights. The
|
356
|
+
base model weights are not saved but the reference to the HuggingFace repository and
|
357
|
+
its commit hash are logged instead.
|
358
|
+
"""
|
359
|
+
),
|
360
|
+
"auth_policy": (
|
361
|
+
"""Specifies the authentication policy for the model, which includes two key components.
|
362
|
+
Note that only one of `auth_policy` or `resources` should be defined.
|
363
|
+
|
364
|
+
- **System Auth Policy**: A list of resources required to serve this model.
|
365
|
+
- **User Auth Policy**: A minimal list of scopes that the user should have access to
|
366
|
+
,in order to invoke this model.
|
367
|
+
|
368
|
+
.. Note::
|
369
|
+
Experimental: This parameter may change or be removed in a future release without warning.
|
370
|
+
"""
|
371
|
+
),
|
372
|
+
"params": "A dictionary of parameters to log with the model.",
|
373
|
+
"tags": "A dictionary of tags to log with the model.",
|
374
|
+
"model_type": "The type of the model.",
|
375
|
+
"step": "The step at which to log the model outputs and metrics",
|
376
|
+
"model_id": "The ID of the model.",
|
377
|
+
"prompts": """\
|
378
|
+
A list of prompt URIs registered in the MLflow Prompt Registry, to be associated with the model.
|
379
|
+
Each prompt URI should be in the form ``prompt:/<name>/<version>``. The prompts should be
|
380
|
+
registered in the MLflow Prompt Registry before being associated with the model.
|
381
|
+
|
382
|
+
This will create a mutual link between the model and the prompt. The associated prompts can be
|
383
|
+
seen in the model's metadata stored in the MLmodel file. From the Prompt Registry UI, you can
|
384
|
+
navigate to the model as well.
|
385
|
+
|
386
|
+
.. code-block:: python
|
387
|
+
|
388
|
+
import mlflow
|
389
|
+
|
390
|
+
prompt_template = "Hi, {name}! How are you doing today?"
|
391
|
+
|
392
|
+
# Register a prompt in the MLflow Prompt Registry
|
393
|
+
mlflow.prompts.register_prompt("my_prompt", prompt_template, description="A simple prompt")
|
394
|
+
|
395
|
+
# Log a model with the registered prompt
|
396
|
+
with mlflow.start_run():
|
397
|
+
model_info = mlflow.pyfunc.log_model(
|
398
|
+
name=MyModel(),
|
399
|
+
name="model",
|
400
|
+
prompts=["prompt:/my_prompt/1"]
|
401
|
+
)
|
402
|
+
|
403
|
+
print(model_info.prompts)
|
404
|
+
# Output: ['prompt:/my_prompt/1']
|
405
|
+
|
406
|
+
# Load the prompt
|
407
|
+
prompt = mlflow.genai.load_prompt(model_info.prompts[0])
|
408
|
+
""",
|
409
|
+
}
|
410
|
+
)
|
411
|
+
|
412
|
+
|
413
|
+
def get_module_min_and_max_supported_ranges(flavor_name):
|
414
|
+
"""
|
415
|
+
Extracts the minimum and maximum supported package versions from the provided module name.
|
416
|
+
The version information is provided via the yaml-to-python-script generation script in
|
417
|
+
dev/update_ml_package_versions.py which writes a python file to the importable namespace of
|
418
|
+
mlflow.ml_package_versions
|
419
|
+
|
420
|
+
Args:
|
421
|
+
flavor_name: The flavor name registered in ml_package_versions.py
|
422
|
+
|
423
|
+
Returns:
|
424
|
+
tuple of module name, minimum supported version, maximum supported version as strings.
|
425
|
+
"""
|
426
|
+
if flavor_name == "pyspark.ml":
|
427
|
+
# pyspark.ml is a special case of spark flavor
|
428
|
+
flavor_name = "spark"
|
429
|
+
|
430
|
+
module_name = _ML_PACKAGE_VERSIONS[flavor_name]["package_info"].get("module_name", flavor_name)
|
431
|
+
versions = _ML_PACKAGE_VERSIONS[flavor_name]["models"]
|
432
|
+
min_version = versions["minimum"]
|
433
|
+
max_version = versions["maximum"]
|
434
|
+
return module_name, min_version, max_version
|
435
|
+
|
436
|
+
|
437
|
+
def _do_version_compatibility_warning(msg: str):
|
438
|
+
"""
|
439
|
+
Isolate the warn call to show the warning only once.
|
440
|
+
"""
|
441
|
+
warnings.warn(msg, category=UserWarning, stacklevel=2)
|
442
|
+
|
443
|
+
|
444
|
+
def docstring_version_compatibility_warning(integration_name):
|
445
|
+
"""
|
446
|
+
Generates a docstring that can be applied as a note stating a version compatibility range for
|
447
|
+
a given flavor and optionally raises a warning if the installed version is outside of the
|
448
|
+
supported range.
|
449
|
+
|
450
|
+
Args:
|
451
|
+
integration_name: The name of the module as stored within ml-package-versions.yml
|
452
|
+
|
453
|
+
Returns:
|
454
|
+
The wrapped function with the additional docstring header applied
|
455
|
+
"""
|
456
|
+
|
457
|
+
def annotated_func(func):
|
458
|
+
# NB: if using this decorator, ensure the package name to module name reference is
|
459
|
+
# updated with the flavor's `save` and `load` functions being used within
|
460
|
+
# ml-package-version.yml file.
|
461
|
+
min_ver, max_ver, pip_release = get_min_max_version_and_pip_release(
|
462
|
+
integration_name, "models"
|
463
|
+
)
|
464
|
+
notice = (
|
465
|
+
f"The '{integration_name}' MLflow Models integration is known to be compatible with "
|
466
|
+
f"``{min_ver}`` <= ``{pip_release}`` <= ``{max_ver}``. "
|
467
|
+
f"MLflow Models integrations with {integration_name} may not succeed when used with "
|
468
|
+
"package versions outside of this range."
|
469
|
+
)
|
470
|
+
|
471
|
+
func.__doc__ = (
|
472
|
+
" .. Note:: " + notice + "\n" * 2 + func.__doc__ if func.__doc__ else notice
|
473
|
+
)
|
474
|
+
|
475
|
+
return func
|
476
|
+
|
477
|
+
return annotated_func
|
mlflow/utils/doctor.py
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
import os
|
2
|
+
import platform
|
3
|
+
|
4
|
+
import click
|
5
|
+
import importlib_metadata
|
6
|
+
import yaml
|
7
|
+
from packaging.requirements import Requirement
|
8
|
+
|
9
|
+
import mlflow
|
10
|
+
from mlflow.utils.databricks_utils import get_databricks_runtime_version
|
11
|
+
|
12
|
+
|
13
|
+
def doctor(mask_envs=False):
|
14
|
+
"""Prints out useful information for debugging issues with MLflow.
|
15
|
+
|
16
|
+
Args:
|
17
|
+
mask_envs: If True, mask the MLflow environment variable values
|
18
|
+
(e.g. `"MLFLOW_ENV_VAR": "***"`) in the output to prevent leaking sensitive
|
19
|
+
information.
|
20
|
+
|
21
|
+
.. warning::
|
22
|
+
|
23
|
+
- This API should only be used for debugging purposes.
|
24
|
+
- The output may contain sensitive information such as a database URI containing a password.
|
25
|
+
|
26
|
+
.. code-block:: python
|
27
|
+
:caption: Example
|
28
|
+
|
29
|
+
import mlflow
|
30
|
+
|
31
|
+
with mlflow.start_run():
|
32
|
+
mlflow.doctor()
|
33
|
+
|
34
|
+
.. code-block:: text
|
35
|
+
:caption: Output
|
36
|
+
|
37
|
+
System information: Linux #58~20.04.1-Ubuntu SMP Thu Oct 13 13:09:46 UTC 2022
|
38
|
+
Python version: 3.8.13
|
39
|
+
MLflow version: 2.0.1
|
40
|
+
MLflow module location: /usr/local/lib/python3.8/site-packages/mlflow/__init__.py
|
41
|
+
Tracking URI: sqlite:///mlflow.db
|
42
|
+
Registry URI: sqlite:///mlflow.db
|
43
|
+
MLflow environment variables:
|
44
|
+
MLFLOW_TRACKING_URI: sqlite:///mlflow.db
|
45
|
+
MLflow dependencies:
|
46
|
+
Flask: 2.2.2
|
47
|
+
Jinja2: 3.0.3
|
48
|
+
alembic: 1.8.1
|
49
|
+
click: 8.1.3
|
50
|
+
cloudpickle: 2.2.0
|
51
|
+
databricks-cli: 0.17.4.dev0
|
52
|
+
docker: 6.0.0
|
53
|
+
entrypoints: 0.4
|
54
|
+
gitpython: 3.1.29
|
55
|
+
gunicorn: 20.1.0
|
56
|
+
importlib-metadata: 5.0.0
|
57
|
+
markdown: 3.4.1
|
58
|
+
matplotlib: 3.6.1
|
59
|
+
numpy: 1.23.4
|
60
|
+
packaging: 21.3
|
61
|
+
pandas: 1.5.1
|
62
|
+
protobuf: 3.19.6
|
63
|
+
pyarrow: 9.0.0
|
64
|
+
pytz: 2022.6
|
65
|
+
pyyaml: 6.0
|
66
|
+
querystring-parser: 1.2.4
|
67
|
+
requests: 2.28.1
|
68
|
+
scikit-learn: 1.1.3
|
69
|
+
scipy: 1.9.3
|
70
|
+
shap: 0.41.0
|
71
|
+
sqlalchemy: 1.4.42
|
72
|
+
sqlparse: 0.4.3
|
73
|
+
"""
|
74
|
+
items = [
|
75
|
+
("System information", " ".join((platform.system(), platform.version()))),
|
76
|
+
("Python version", platform.python_version()),
|
77
|
+
("MLflow version", mlflow.__version__),
|
78
|
+
("MLflow module location", mlflow.__file__),
|
79
|
+
("Tracking URI", mlflow.get_tracking_uri()),
|
80
|
+
("Registry URI", mlflow.get_registry_uri()),
|
81
|
+
]
|
82
|
+
|
83
|
+
if (runtime := get_databricks_runtime_version()) is not None:
|
84
|
+
items.append(("Databricks runtime version", runtime))
|
85
|
+
|
86
|
+
active_run = mlflow.active_run()
|
87
|
+
if active_run:
|
88
|
+
items.extend(
|
89
|
+
[
|
90
|
+
("Active experiment ID", active_run.info.experiment_id),
|
91
|
+
("Active run ID", active_run.info.run_id),
|
92
|
+
("Active run artifact URI", active_run.info.artifact_uri),
|
93
|
+
]
|
94
|
+
)
|
95
|
+
|
96
|
+
mlflow_envs = {
|
97
|
+
k: ("***" if mask_envs else v) for k, v in os.environ.items() if k.startswith("MLFLOW_")
|
98
|
+
}
|
99
|
+
if mlflow_envs:
|
100
|
+
items.append(
|
101
|
+
(
|
102
|
+
"MLflow environment variables",
|
103
|
+
yaml.dump({"_": mlflow_envs}, indent=2).replace("'", "").lstrip("_:").rstrip("\n"),
|
104
|
+
)
|
105
|
+
)
|
106
|
+
|
107
|
+
try:
|
108
|
+
requires = importlib_metadata.requires("mlflow")
|
109
|
+
except importlib_metadata.PackageNotFoundError:
|
110
|
+
requires = importlib_metadata.requires("mlflow-skinny")
|
111
|
+
|
112
|
+
mlflow_dependencies = {}
|
113
|
+
for req in requires:
|
114
|
+
req = Requirement(req)
|
115
|
+
try:
|
116
|
+
dist = importlib_metadata.distribution(req.name)
|
117
|
+
except importlib_metadata.PackageNotFoundError:
|
118
|
+
continue
|
119
|
+
else:
|
120
|
+
mlflow_dependencies[req.name] = dist.version
|
121
|
+
|
122
|
+
items.append(
|
123
|
+
(
|
124
|
+
"MLflow dependencies",
|
125
|
+
yaml.dump({"_": mlflow_dependencies}, indent=2)
|
126
|
+
.replace("'", "")
|
127
|
+
.lstrip("_:")
|
128
|
+
.rstrip("\n"),
|
129
|
+
)
|
130
|
+
)
|
131
|
+
for key, val in items:
|
132
|
+
click.secho(key, fg="blue", nl=False)
|
133
|
+
click.echo(f": {val}")
|
@@ -0,0 +1,43 @@
|
|
1
|
+
"""
|
2
|
+
This script should be executed in a fresh python interpreter process using `subprocess`.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import argparse
|
6
|
+
import importlib.util
|
7
|
+
import json
|
8
|
+
import os
|
9
|
+
import sys
|
10
|
+
|
11
|
+
|
12
|
+
def parse_args():
|
13
|
+
parser = argparse.ArgumentParser()
|
14
|
+
parser.add_argument("--range-start", required=True, type=int)
|
15
|
+
parser.add_argument("--range-end", required=True, type=int)
|
16
|
+
parser.add_argument("--headers", required=True, type=str)
|
17
|
+
parser.add_argument("--download-path", required=True, type=str)
|
18
|
+
parser.add_argument("--http-uri", required=True, type=str)
|
19
|
+
return parser.parse_args()
|
20
|
+
|
21
|
+
|
22
|
+
def main():
|
23
|
+
file_path = os.path.join(os.path.dirname(__file__), "request_utils.py")
|
24
|
+
module_name = "mlflow.utils.request_utils"
|
25
|
+
|
26
|
+
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
27
|
+
module = importlib.util.module_from_spec(spec)
|
28
|
+
sys.modules[module_name] = module
|
29
|
+
spec.loader.exec_module(module)
|
30
|
+
download_chunk = module.download_chunk
|
31
|
+
|
32
|
+
args = parse_args()
|
33
|
+
download_chunk(
|
34
|
+
range_start=args.range_start,
|
35
|
+
range_end=args.range_end,
|
36
|
+
headers=json.loads(args.headers),
|
37
|
+
download_path=args.download_path,
|
38
|
+
http_uri=args.http_uri,
|
39
|
+
)
|
40
|
+
|
41
|
+
|
42
|
+
if __name__ == "__main__":
|
43
|
+
main()
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from mlflow.exceptions import MlflowException
|
2
|
+
from mlflow.protos.databricks_pb2 import INVALID_PARAMETER_VALUE
|
3
|
+
|
4
|
+
LOCAL = "local"
|
5
|
+
CONDA = "conda"
|
6
|
+
VIRTUALENV = "virtualenv"
|
7
|
+
UV = "uv"
|
8
|
+
|
9
|
+
|
10
|
+
def validate(env_manager):
|
11
|
+
allowed_values = [LOCAL, CONDA, VIRTUALENV, UV]
|
12
|
+
if env_manager not in allowed_values:
|
13
|
+
raise MlflowException(
|
14
|
+
f"Invalid value for `env_manager`: {env_manager}. Must be one of {allowed_values}",
|
15
|
+
error_code=INVALID_PARAMETER_VALUE,
|
16
|
+
)
|