def save_model(
    name: Tag | str,
    model: cb.CatBoost,
    *,
    signatures: dict[str, ModelSignatureDict] | None = None,
    labels: dict[str, str] | None = None,
    custom_objects: dict[str, t.Any] | None = None,
    external_modules: t.List[ModuleType] | None = None,
    metadata: dict[str, t.Any] | None = None,
) -> bentoml.Model:
    """
    Save an CatBoost model instance to the BentoML model store.

    Args:
        name:
            The name to give to the model in the BentoML store. This must be a valid
            :obj:`~bentoml.Tag` name.
        model:
            The CatBoost model to be saved.
        signatures:
            Signatures of predict methods to be used. If not provided, the signatures default to
            ``{"predict": {"batchable": False}}``. See :obj:`~bentoml.types.ModelSignature` for more
            details.
        labels:
            A default set of management labels to be associated with the model. An example is
            ``{"training-set": "data-1"}``.
        custom_objects:
            Custom objects to be saved with the model. An example is
            ``{"my-normalizer": normalizer}``.

            Custom objects are currently serialized with cloudpickle, but this implementation is
            subject to change.
        external_modules (:code:`List[ModuleType]`, `optional`, default to :code:`None`):
            user-defined additional python modules to be saved alongside the model or custom objects,
            e.g. a tokenizer module, preprocessor module, model configuration module
        metadata:
            Metadata to be associated with the model. An example is ``{"max_depth": 2}``.

            Metadata is intended for display in model management UI and therefore must be a default
            Python type, such as ``str`` or ``int``.

    Returns:
        :obj:`~bentoml.Tag`: A :obj:`tag` with a format `name:version` where `name` is the
        user-defined model's name, and a generated `version` by BentoML.

    Example:

    .. code-block:: python

        import bentoml
        import numpy as np

        from catboost import CatBoostClassifier, Pool

        # initialize data
        train_data = np.random.randint(0, 100, size=(100, 10))

        train_labels = np.random.randint(0, 2, size=(100))

        test_data = catboost_pool = Pool(train_data, train_labels)

        model = CatBoostClassifier(iterations=2,
                                   depth=2,
                                   learning_rate=1,
                                   loss_function='Logloss',
                                   verbose=True)
        # train the model
        model.fit(train_data, train_labels)

        # save the model to the BentoML model store
        bento_model = bentoml.catboost.save_model("my_catboost_model", model)
    """
    if not isinstance(model, cb.CatBoost):
        raise TypeError(f"Given model ({model}) is not a catboost.CatBoost.")

    context: ModelContext = ModelContext(
        framework_name="catboost",
        framework_versions={"catboost": get_pkg_version("catboost")},
    )

    if signatures is None:
        signatures = {
            "predict": {"batchable": False},
        }
        logger.info(
            'Using the default model signature for CatBoost (%s) for model "%s".',
            signatures,
            name,
        )

    options = ModelOptions(
        training_class_name=model.__class__.__name__,
    )

    with bentoml.models._create(  # type: ignore
        name,
        module=MODULE_NAME,
        api_version=API_VERSION,
        signatures=signatures,
        labels=labels,
        custom_objects=custom_objects,
        external_modules=external_modules,
        metadata=metadata,
        context=context,
        options=options,
    ) as bento_model:
        model.save_model(bento_model.path_of(MODEL_FILENAME))  # type: ignore (incomplete CatBoost types)

        return bento_model
Save an CatBoost model instance to the BentoML model store.

Args:
name:
The name to give to the model in the BentoML store. This must be a valid
:obj:`~bentoml.Tag` name.
model:
The CatBoost model to be saved.
signatures:
Signatures of predict methods to be used. If not provided, the signatures default to
``{"predict": {"batchable": False}}``. See :obj:`~bentoml.types.ModelSignature` for more
details.
labels:
A default set of management labels to be associated with the model. An example is
``{"training-set": "data-1"}``.
custom_objects:
Custom objects to be saved with the model. An example is
``{"my-normalizer": normalizer}``.

Custom objects are currently serialized with cloudpickle, but this implementation is
subject to change.
external_modules (:code:`List[ModuleType]`, `optional`, default to :code:`None`):
user-defined additional python modules to be saved alongside the model or custom objects,
e.g. a tokenizer module, preprocessor module, model configuration module
metadata:
Metadata to be associated with the model. An example is ``{"max_depth": 2}``.

Metadata is intended for display in model management UI and therefore must be a default
Python type, such as ``str`` or ``int``.

Returns:
:obj:`~bentoml.Tag`: A :obj:`tag` with a format `name:version` where `name` is the
user-defined model's name, and a generated `version` by BentoML.

Example:

.. code-block:: python

import bentoml
import numpy as np

from catboost import CatBoostClassifier, Pool

# initialize data
train_data = np.random.randint(0, 100, size=(100, 10))

train_labels = np.random.randint(0, 2, size=(100))

test_data = catboost_pool = Pool(train_data, train_labels)

model = CatBoostClassifier(iterations=2,
depth=2,
learning_rate=1,
loss_function='Logloss',
verbose=True)
# train the model
model.fit(train_data, train_labels)

# save the model to the BentoML model store
bento_model = bentoml.catboost.save_model("my_catboost_model", model)
src/_bentoml_impl/frameworks/catboost.py