code: def autolog(
      importance_types=None,
      log_input_examples=False,
      log_model_signatures=True,
      log_models=True,
      log_datasets=True,
      disable=False,
      exclusive=False,
      disable_for_unsupported_versions=False,
      silent=False,
      registered_model_name=None,
      model_format="xgb",
      extra_tags=None,
  ):  # pylint: disable=unused-argument
      """
      Enables (or disables) and configures autologging from XGBoost to MLflow. Logs the following:
  
          - parameters specified in `xgboost.train`_.
          - metrics on each iteration (if ``evals`` specified).
          - metrics at the best iteration (if ``early_stopping_rounds`` specified).
          - feature importance as JSON files and plots.
          - trained model, including:
              - an example of valid input.
              - inferred signature of the inputs and outputs of the model.
  
      Note that the `scikit-learn API`_ is now supported.
  
      Args:
          importance_types: Importance types to log. If unspecified, defaults to ``["weight"]``.
          log_input_examples: If ``True``, input examples from training datasets are collected and
              logged along with XGBoost model artifacts during training. If
              ``False``, input examples are not logged. Note: Input examples are MLflow model
              attributes and are only collected if ``log_models`` is also ``True``.
          log_model_signatures: If ``True``,
              :py:class:`ModelSignatures <mlflow.models.ModelSignature>`
              describing model inputs and outputs are collected and logged along
              with XGBoost model artifacts during training. If ``False``,
              signatures are not logged.
              Note: Model signatures are MLflow model attributes
              and are only collected if ``log_models`` is also ``True``.
          log_models: If ``True``, trained models are logged as MLflow model artifacts.
              If ``False``, trained models are not logged.
              Input examples and model signatures, which are attributes of MLflow models,
              are also omitted when ``log_models`` is ``False``.
          log_datasets: If ``True``, train and validation dataset information is logged to MLflow
              Tracking if applicable. If ``False``, dataset information is not logged.
          disable: If ``True``, disables the XGBoost autologging integration. If ``False``,
              enables the XGBoost autologging integration.
          exclusive: If ``True``, autologged content is not logged to user-created fluent runs.
              If ``False``, autologged content is logged to the active fluent run,
              which may be user-created.
          disable_for_unsupported_versions: If ``True``, disable autologging for versions of
              xgboost that have not been tested against this version of the MLflow client
              or are incompatible.
          silent: If ``True``, suppress all event logs and warnings from MLflow during XGBoost
              autologging. If ``False``, show all events and warnings during XGBoost
              autologging.
          registered_model_name: If given, each time a model is trained, it is registered as a
              new model version of the registered model with this name.
              The registered model is created if it does not already exist.
          model_format: File format in which the model is to be saved.
          extra_tags: A dictionary of extra tags to set on each managed run created by autologging.
      """
      import numpy as np
      import xgboost
  
      if importance_types is None:
          importance_types = ["weight"]
  
      # Patching this function so we can get a copy of the data given to DMatrix.__init__
      #   to use as an input example and for inferring the model signature.
      #   (there is no way to get the data back from a DMatrix object)
      # We store it on the DMatrix object so the train function is able to read it.
      def __init__(original, self, *args, **kwargs):
          data = args[0] if len(args) > 0 else kwargs.get("data")
  
          if data is not None:
              try:
                  if isinstance(data, str):
                      raise Exception(
                          "cannot gather example input when dataset is loaded from a file."
                      )
  
                  input_example_info = InputExampleInfo(
                      input_example=deepcopy(
                          data[:INPUT_EXAMPLE_SAMPLE_ROWS]
                      )
                  )
              except Exception as e:
                  input_example_info = InputExampleInfo(
                      error_msg=str(e)
                  )
  
              self.input_example_info = input_example_info
  
          original(self, *args, **kwargs)
  
      def train_impl(
          _log_models, _log_datasets, original, *args, **kwargs
      ):
          def record_eval_results(eval_results, metrics_logger):
              """
              Create a callback function that records evaluation results.
              """
              # TODO: Remove `replace("SNAPSHOT", "dev")` once the following issue is addressed:
              #       https://github.com/dmlc/xgboost/issues/6984
              from mlflow.xgboost._autolog import (
                  IS_TRAINING_CALLBACK_SUPPORTED,
              )
  
              if IS_TRAINING_CALLBACK_SUPPORTED:
                  from mlflow.xgboost._autolog import AutologCallback
  
                  # In xgboost >= 1.3.0, user-defined callbacks should inherit
                  # `xgboost.callback.TrainingCallback`:
                  # https://xgboost.readthedocs.io/en/latest/python/callbacks.html#defining-your-own-callback
                  return AutologCallback(metrics_logger, eval_results)
              else:
                  from mlflow.xgboost._autolog import autolog_callback
  
                  return picklable_exception_safe_function(
                      functools.partial(
                          autolog_callback,
                          metrics_logger=metrics_logger,
                          eval_results=eval_results,
                      )
                  )
  
          def log_feature_importance_plot(
              features, importance, importance_type
          ):
              """
              Log feature importance plot.
              """
              import matplotlib.pyplot as plt
              from cycler import cycler
  
              features = np.array(features)
  
              # Structure the supplied `importance` values as a `num_features`-by-`num_classes` matrix
              importances_per_class_by_feature = np.array(importance)
              if importances_per_class_by_feature.ndim <= 1:
                  # In this case, the supplied `importance` values are not given per class. Rather,
                  # one importance value is given per feature. For consistency with the assumed
                  # `num_features`-by-`num_classes` matrix structure, we coerce the importance
                  # values to a `num_features`-by-1 matrix
                  indices = np.argsort(importance)
                  # Sort features and importance values by magnitude during transformation to a
                  # `num_features`-by-`num_classes` matrix
                  features = features[indices]
                  importances_per_class_by_feature = np.array(
                      [
                          [importance]
                          for importance in importances_per_class_by_feature[
                              indices
                          ]
                      ]
                  )
                  # In this case, do not include class labels on the feature importance plot because
                  # only one importance value has been provided per feature, rather than an
                  # one importance value for each class per feature
                  label_classes_on_plot = False
              else:
                  importance_value_magnitudes = np.abs(
                      importances_per_class_by_feature
                  ).sum(axis=1)
                  indices = np.argsort(importance_value_magnitudes)
                  features = features[indices]
                  importances_per_class_by_feature = (
                      importances_per_class_by_feature[indices]
                  )
                  label_classes_on_plot = True
  
              num_classes = importances_per_class_by_feature.shape[1]
              num_features = len(features)
  
              # If num_features > 10, increase the figure height to prevent the plot
              # from being too dense.
              w, h = [6.4, 4.8]  # matplotlib's default figure size
              h = h + 0.1 * num_features if num_features > 10 else h
              h = h + 0.1 * num_classes if num_classes > 1 else h
              fig, ax = plt.subplots(figsize=(w, h))
              # When importance values are provided for each class per feature, we want to ensure
              # that the same color is used for all bars in the bar chart that have the same class
              colors_to_cycle = plt.rcParams[
                  "axes.prop_cycle"
              ].by_key()["color"][:num_classes]
              color_cycler = cycler(color=colors_to_cycle)
              ax.set_prop_cycle(color_cycler)
  
              # The following logic operates on one feature at a time, adding a bar to the bar chart
              # for each class that reflects the importance of the feature to predictions of that
              # class
              feature_ylocs = np.arange(num_features)
              # Define offsets on the y-axis that are used to evenly space the bars for each class
              # around the y-axis position of each feature
              offsets_per_yloc = (
                  np.linspace(-0.5, 0.5, num_classes) / 2
                  if num_classes > 1
                  else [0]
              )
              for feature_idx, (
                  feature_yloc,
                  importances_per_class,
              ) in enumerate(
                  zip(feature_ylocs, importances_per_class_by_feature)
              ):
                  for class_idx, (
                      offset,
                      class_importance,
                  ) in enumerate(
                      zip(offsets_per_yloc, importances_per_class)
                  ):
                      (bar,) = ax.barh(
                          feature_yloc + offset,
                          class_importance,
                          align="center",
                          # Set the bar height such that importance value bars for a particular
                          # feature are spaced properly relative to each other (no overlap or gaps)
                          # and relative to importance value bars for other features
                          height=(0.5 / max(num_classes - 1, 1)),
                      )
                      if label_classes_on_plot and feature_idx == 0:
                          # Only set a label the first time a bar for a particular class is plotted to
                          # avoid duplicate legend entries. If we were to set a label for every bar,
                          # the legend would contain `num_features` labels for each class.
                          bar.set_label(f"Class {class_idx}")
  
              ax.set_yticks(feature_ylocs)
              ax.set_yticklabels(features)
              ax.set_xlabel("Importance")
              ax.set_title(f"Feature Importance ({importance_type})")
              if label_classes_on_plot:
                  ax.legend()
              fig.tight_layout()
  
              with tempfile.TemporaryDirectory() as tmpdir:
                  try:
                      # pylint: disable=undefined-loop-variable
                      filepath = os.path.join(
                          tmpdir, f"feature_importance_{imp_type}.png"
                      )
                      fig.savefig(filepath)
                      mlflow.log_artifact(filepath)
                  finally:
                      plt.close(fig)
  
          autologging_client = MlflowAutologgingQueueingClient()
          # logging booster params separately to extract key/value pairs and make it easier to
          # compare them across runs.
          booster_params = (
              args[0] if len(args) > 0 else kwargs["params"]
          )
          autologging_client.log_params(
              run_id=mlflow.active_run().info.run_id,
              params=booster_params,
          )
  
          unlogged_params = [
              "params",
              "dtrain",
              "evals",
              "obj",
              "feval",
              "evals_result",
              "xgb_model",
              "callbacks",
              "learning_rates",
          ]
          params_to_log_for_fn = get_mlflow_run_params_for_fn_args(
              original, args, kwargs, unlogged_params
          )
          autologging_client.log_params(
              run_id=mlflow.active_run().info.run_id,
              params=params_to_log_for_fn,
          )
  
          param_logging_operations = autologging_client.flush(
              synchronous=False
          )
  
          all_arg_names = _get_arg_names(original)
          num_pos_args = len(args)
  
          # adding a callback that records evaluation results.
          eval_results = []
          callbacks_index = all_arg_names.index("callbacks")
  
          run_id = mlflow.active_run().info.run_id
  
          dtrain = args[1] if len(args) > 1 else kwargs.get("dtrain")
  
          # Whether to automatically log the training dataset as a dataset artifact.
          if _log_datasets and dtrain is not None:
              try:
                  context_tags = context_registry.resolve_tags()
                  source = CodeDatasetSource(context_tags)
  
                  _log_xgboost_dataset(
                      dtrain, source, "train", autologging_client
                  )
                  evals = kwargs.get("evals")
                  if evals is not None:
                      for d, name in evals:
                          _log_xgboost_dataset(
                              d,
                              source,
                              "eval",
                              autologging_client,
                              name,
                          )
                  dataset_logging_operations = autologging_client.flush(
                      synchronous=False
                  )
                  dataset_logging_operations.await_completion()
              except Exception as e:
                  _logger.warning(
                      "Failed to log dataset information to MLflow Tracking. Reason: %s",
                      e,
                  )
  
          with batch_metrics_logger(run_id) as metrics_logger:
              callback = record_eval_results(
                  eval_results, metrics_logger
              )
              if num_pos_args >= callbacks_index + 1:
                  tmp_list = list(args)
                  tmp_list[callbacks_index] += [callback]
                  args = tuple(tmp_list)
              elif (
                  "callbacks" in kwargs
                  and kwargs["callbacks"] is not None
              ):
                  kwargs["callbacks"] += [callback]
              else:
                  kwargs["callbacks"] = [callback]
  
              # training model
              model = original(*args, **kwargs)
  
              # If early_stopping_rounds is present, logging metrics at the best iteration
              # as extra metrics with the max step + 1.
              early_stopping_index = all_arg_names.index(
                  "early_stopping_rounds"
              )
              early_stopping = (
                  num_pos_args >= early_stopping_index + 1
                  or kwargs.get("early_stopping_rounds")
              )
              if early_stopping:
                  extra_step = len(eval_results)
                  autologging_client.log_metrics(
                      run_id=mlflow.active_run().info.run_id,
                      metrics={
                          "stopped_iteration": extra_step - 1,
                          "best_iteration": model.best_iteration,
                      },
                  )
                  autologging_client.log_metrics(
                      run_id=mlflow.active_run().info.run_id,
                      metrics=eval_results[model.best_iteration],
                      step=extra_step,
                  )
                  early_stopping_logging_operations = (
                      autologging_client.flush(synchronous=False)
                  )
  
          # logging feature importance as artifacts.
          for imp_type in importance_types:
              imp = None
              try:
                  imp = model.get_score(importance_type=imp_type)
                  features, importance = zip(*imp.items())
                  log_feature_importance_plot(
                      features, importance, imp_type
                  )
              except Exception:
                  _logger.exception(
                      "Failed to log feature importance plot. XGBoost autologging "
                      "will ignore the failure and continue. Exception: "
                  )
  
              if imp is not None:
                  with tempfile.TemporaryDirectory() as tmpdir:
                      filepath = os.path.join(
                          tmpdir, f"feature_importance_{imp_type}.json"
                      )
                      with open(filepath, "w") as f:
                          json.dump(imp, f)
                      mlflow.log_artifact(filepath)
  
          # dtrain must exist as the original train function already ran successfully
          # it is possible that the dataset was constructed before the patched
          #   constructor was applied, so we cannot assume the input_example_info exists
          input_example_info = getattr(
              dtrain, "input_example_info", None
          )
  
          def get_input_example():
              if input_example_info is None:
                  raise Exception(ENSURE_AUTOLOGGING_ENABLED_TEXT)
              if input_example_info.error_msg is not None:
                  raise Exception(input_example_info.error_msg)
              return input_example_info.input_example
  
          def infer_model_signature(input_example):
              model_output = model.predict(
                  xgboost.DMatrix(input_example)
              )
              return infer_signature(input_example, model_output)
  
          # Only log the model if the autolog() param log_models is set to True.
          if _log_models:
              # Will only resolve `input_example` and `signature` if `log_models` is `True`.
              (
                  input_example,
                  signature,
              ) = resolve_input_example_and_signature(
                  get_input_example,
                  infer_model_signature,
                  log_input_examples,
                  log_model_signatures,
                  _logger,
              )
  
              registered_model_name = get_autologging_config(
                  FLAVOR_NAME, "registered_model_name", None
              )
              log_model(
                  model,
                  artifact_path="model",
                  signature=signature,
                  input_example=input_example,
                  registered_model_name=registered_model_name,
                  model_format=model_format,
              )
  
          param_logging_operations.await_completion()
          if early_stopping:
              early_stopping_logging_operations.await_completion()
  
          return model
  
      def train(_log_models, _log_datasets, original, *args, **kwargs):
          current_sklearn_session = (
              _SklearnTrainingSession.get_current_session()
          )
          if (
              current_sklearn_session is None
              or current_sklearn_session.should_log()
          ):
              return train_impl(
                  _log_models, _log_datasets, original, *args, **kwargs
              )
          else:
              return original(*args, **kwargs)
  
      safe_patch(
          FLAVOR_NAME,
          xgboost,
          "train",
          functools.partial(train, log_models, log_datasets),
          manage_run=True,
          extra_tags=extra_tags,
      )
      # The `train()` method logs XGBoost models as Booster objects. When using XGBoost
      # scikit-learn models, we want to save / log models as their model classes. So we turn
      # off the log_models functionality in the `train()` method patched to `xgboost.sklearn`.
      # Instead the model logging is handled in `fit_mlflow_sklearn()` in `mlflow.sklearn._autolog()`,
      # where models are logged as XGBoost scikit-learn models after the `fit()` method returns.
      safe_patch(
          FLAVOR_NAME,
          xgboost.sklearn,
          "train",
          functools.partial(train, False, log_datasets),
          manage_run=True,
          extra_tags=extra_tags,
      )
      safe_patch(FLAVOR_NAME, xgboost.DMatrix, "__init__", __init__)
  
      # enable xgboost scikit-learn estimators autologging
      import mlflow.sklearn
  
      mlflow.sklearn._autolog(
          flavor_name=FLAVOR_NAME,
          log_input_examples=log_input_examples,
          log_model_signatures=log_model_signatures,
          log_models=log_models,
          log_datasets=log_datasets,
          disable=disable,
          exclusive=exclusive,
          disable_for_unsupported_versions=disable_for_unsupported_versions,
          silent=silent,
          max_tuning_runs=None,
          log_post_training_metrics=True,
          extra_tags=extra_tags,
      )
  
imports: import functools
  import json
  import logging
  import os
  import tempfile
  from copy import deepcopy
  from typing import Any, Dict, Optional
  import yaml
  from packaging.version import Version
  import mlflow
  from mlflow import pyfunc
  from mlflow.data.code_dataset_source import CodeDatasetSource
  from mlflow.data.numpy_dataset import from_numpy
  from mlflow.data.pandas_dataset import from_pandas
  from mlflow.entities.dataset_input import DatasetInput
  from mlflow.entities.input_tag import InputTag
  from mlflow.models import Model, ModelInputExample, ModelSignature, infer_signature
  from mlflow.models.model import MLMODEL_FILE_NAME
  from mlflow.models.signature import _infer_signature_from_input_example
  from mlflow.models.utils import _save_example
  from mlflow.sklearn import _SklearnTrainingSession
  from mlflow.tracking._model_registry import DEFAULT_AWAIT_MAX_SLEEP_SECONDS
  from mlflow.tracking.artifact_utils import _download_artifact_from_uri
  from mlflow.tracking.context import registry
  from mlflow.utils import _get_fully_qualified_class_name
  from mlflow.utils.arguments_utils import _get_arg_names
  from mlflow.utils.autologging_utils import ENSURE_AUTOLOGGING_ENABLED_TEXT, INPUT_EXAMPLE_SAMPLE_ROWS, InputExampleInfo, MlflowAutologgingQueueingClient, autologging_integration, batch_metrics_logger, get_autologging_config, get_mlflow_run_params_for_fn_args, picklable_exception_safe_function, resolve_input_example_and_signature, safe_patch
  from mlflow.utils.class_utils import _get_class_from_string
  from mlflow.utils.docstring_utils import LOG_MODEL_PARAM_DOCS, format_docstring
  from mlflow.utils.environment import _CONDA_ENV_FILE_NAME, _CONSTRAINTS_FILE_NAME, _PYTHON_ENV_FILE_NAME, _REQUIREMENTS_FILE_NAME, _mlflow_conda_env, _process_conda_env, _process_pip_requirements, _PythonEnv, _validate_env_arguments
  from mlflow.utils.file_utils import get_total_file_size, write_to
  from mlflow.utils.mlflow_tags import MLFLOW_DATASET_CONTEXT
  from mlflow.utils.model_utils import _add_code_from_conf_to_system_path, _get_flavor_configuration, _validate_and_copy_code_paths, _validate_and_prepare_target_save_path
  from mlflow.utils.requirements_utils import _get_pinned_requirement
label_desc: Use image node_id 8 for calling a global function with example usage: autolog(importance_types, log_input_examples, log_model_signatures, log_models, log_datasets, disable, exclusive, disable_for_unsupported_versions, silent, registered_model_name, model_format, extra_tags) and returns: model, input_example_info, infer_signature, train_impl, original, AutologCallback, picklable_exception_safe_function