Skip to content

Commit

Permalink
fix: emit deprecation warings for legacy APIs (#5023)
Browse files Browse the repository at this point in the history
  • Loading branch information
frostming authored Oct 15, 2024
1 parent 0a5e3be commit f8874ef
Show file tree
Hide file tree
Showing 14 changed files with 133 additions and 24 deletions.
4 changes: 2 additions & 2 deletions src/_bentoml_impl/frameworks/catboost.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

import attr
import numpy as np
from typing_extensions import deprecated

import bentoml
from bentoml import Tag
from bentoml._internal.models.model import ModelContext
from bentoml._internal.utils import deprecated
from bentoml._internal.utils.pkg import get_pkg_version
from bentoml.exceptions import BentoMLException
from bentoml.exceptions import InvalidArgument
Expand Down Expand Up @@ -199,7 +199,7 @@ def save_model(
return bento_model


@deprecated("`get_runnable` is a legacy API, use `get_service` instead.")
@deprecated(suggestion="Use `get_service` instead.")
def get_runnable(bento_model: bentoml.Model) -> t.Type[bentoml.Runnable]:
"""
Private API: use :obj:`~bentoml.Model.to_runnable` instead.
Expand Down
5 changes: 5 additions & 0 deletions src/_bentoml_impl/frameworks/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from importlib.abc import MetaPathFinder
from typing import TYPE_CHECKING

from bentoml._internal.utils import warn_deprecated

if TYPE_CHECKING:
from importlib.machinery import ModuleSpec
from types import ModuleType
Expand All @@ -21,6 +23,9 @@ def find_spec(
return None
spec = importlib.util.find_spec(f"_bentoml_impl.frameworks.{framework}")
if spec is None:
warn_deprecated(
f"`bentoml.{framework}` is deprecated since BentoML v1.4 and will be removed in a future version.",
)
spec = importlib.util.find_spec(f"bentoml._internal.frameworks.{framework}")
return spec

Expand Down
4 changes: 2 additions & 2 deletions src/_bentoml_impl/frameworks/lightgbm.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
from typing import TYPE_CHECKING

import numpy as np
from typing_extensions import deprecated

import bentoml
from bentoml import Tag
from bentoml._internal.models.model import ModelContext
from bentoml._internal.utils import deprecated
from bentoml._internal.utils.pkg import get_pkg_version
from bentoml.exceptions import InvalidArgument
from bentoml.exceptions import MissingDependencyException
Expand Down Expand Up @@ -203,7 +203,7 @@ def save_model(
return bento_model


@deprecated("`get_runnable` is a legacy API, use `get_service` instead.")
@deprecated(suggestion="Use `get_service` instead.")
def get_runnable(bento_model: bentoml.Model) -> t.Type[bentoml.Runnable]:
"""
Private API: use :obj:`~bentoml.Model.to_runnable` instead.
Expand Down
4 changes: 2 additions & 2 deletions src/_bentoml_impl/frameworks/mlflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
from typing import TYPE_CHECKING

import numpy as np
from typing_extensions import deprecated

import bentoml
from bentoml import Tag
from bentoml._internal.utils import deprecated
from bentoml.exceptions import BentoMLException
from bentoml.exceptions import MissingDependencyException
from bentoml.exceptions import NotFound
Expand Down Expand Up @@ -212,7 +212,7 @@ def import_model(
return bento_model


@deprecated("`get_runnable` is a legacy API, use `get_service` instead.")
@deprecated(suggestion="Use `get_service` instead.")
def get_runnable(bento_model: bentoml.Model) -> t.Type[bentoml.Runnable]:
"""
Private API: use :obj:`~bentoml.Model.to_runnable` instead.
Expand Down
5 changes: 2 additions & 3 deletions src/_bentoml_impl/frameworks/sklearn.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@
from types import ModuleType
from typing import TYPE_CHECKING

from typing_extensions import deprecated

import bentoml
from bentoml import Tag
from bentoml._internal.types import LazyType
from bentoml._internal.utils import deprecated
from bentoml._internal.utils.pkg import get_pkg_version
from bentoml.exceptions import MissingDependencyException
from bentoml.exceptions import NotFound
Expand Down Expand Up @@ -159,7 +158,7 @@ def save_model(
return bento_model


@deprecated("`get_runnable` is a legacy API, use `get_service` instead.")
@deprecated(suggestion="Use `get_service` instead.")
def get_runnable(bento_model: Model):
"""
Private API: use :obj:`~bentoml.Model.to_runnable` instead.
Expand Down
4 changes: 2 additions & 2 deletions src/_bentoml_impl/frameworks/xgboost.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

import attr
import numpy as np
from typing_extensions import deprecated

import bentoml
from bentoml import Tag
from bentoml._internal.models.model import ModelContext
from bentoml._internal.utils import deprecated
from bentoml._internal.utils.pkg import get_pkg_version
from bentoml.exceptions import BentoMLException
from bentoml.exceptions import InvalidArgument
Expand Down Expand Up @@ -216,7 +216,7 @@ def save_model(
return bento_model


@deprecated("`get_runnable` is a legacy API, use `get_service` instead.")
@deprecated(suggestion="Use `get_service` instead.")
def get_runnable(bento_model: bentoml.Model) -> t.Type[bentoml.Runnable]:
"""
Private API: use :obj:`~bentoml.Model.to_runnable` instead.
Expand Down
2 changes: 2 additions & 0 deletions src/_bentoml_sdk/service/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from bentoml._internal.configuration.containers import BentoMLContainer
from bentoml._internal.context import ServiceContext
from bentoml._internal.models import Model as StoredModel
from bentoml._internal.utils import deprecated
from bentoml._internal.utils import dict_filter_none
from bentoml.exceptions import BentoMLConfigException
from bentoml.exceptions import BentoMLException
Expand Down Expand Up @@ -422,6 +423,7 @@ def decorator(inner: type[T]) -> Service[T]:
return decorator(inner) if inner is not None else decorator


@deprecated()
def runner_service(runner: Runner, **kwargs: Unpack[Config]) -> Service[t.Any]:
"""Make a service from a legacy Runner"""
if not isinstance(runner, Runner): # type: ignore
Expand Down
66 changes: 54 additions & 12 deletions src/bentoml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,47 +138,89 @@
)
mlflow = _LazyLoader("bentoml.mlflow", globals(), "_bentoml_impl.frameworks.mlflow")
detectron = _LazyLoader(
"bentoml.detectron", globals(), "bentoml._internal.frameworks.detectron"
"bentoml.detectron",
globals(),
"bentoml._internal.frameworks.detectron",
warning="`bentoml.detectron` is deprecated since v1.4 and will be removed in a future version.",
)
diffusers = _LazyLoader(
"bentoml.diffusers", globals(), "bentoml._internal.frameworks.diffusers"
"bentoml.diffusers",
globals(),
"bentoml._internal.frameworks.diffusers",
warning="`bentoml.diffusers` is deprecated since v1.4 and will be removed in a future version.",
)
diffusers_simple = _LazyLoader(
"bentoml.diffusers_simple", globals(), "bentoml.diffusers_simple"
"bentoml.diffusers_simple",
globals(),
"bentoml.diffusers_simple",
warning="`bentoml.diffusers_simple` is deprecated since v1.4 and will be removed in a future version.",
)
easyocr = _LazyLoader(
"bentoml.easyocr", globals(), "bentoml._internal.frameworks.easyocr"
"bentoml.easyocr",
globals(),
"bentoml._internal.frameworks.easyocr",
warning="`bentoml.easyocr` is deprecated since v1.4 and will be removed in a future version.",
)
flax = _LazyLoader(
"bentoml.flax",
globals(),
"bentoml._internal.frameworks.flax",
warning="`bentoml.flax` is deprecated since v1.4 and will be removed in a future version.",
)
flax = _LazyLoader("bentoml.flax", globals(), "bentoml._internal.frameworks.flax")
fastai = _LazyLoader(
"bentoml.fastai", globals(), "bentoml._internal.frameworks.fastai"
"bentoml.fastai",
globals(),
"bentoml._internal.frameworks.fastai",
warning="`bentoml.fastai` is deprecated since v1.4 and will be removed in a future version.",
)

onnx = _LazyLoader("bentoml.onnx", globals(), "bentoml._internal.frameworks.onnx")
onnx = _LazyLoader(
"bentoml.onnx",
globals(),
"bentoml._internal.frameworks.onnx",
warning="`bentoml.onnx` is deprecated since v1.4 and will be removed in a future version.",
)
keras = _LazyLoader(
"bentoml.keras", globals(), "bentoml._internal.frameworks.keras"
"bentoml.keras",
globals(),
"bentoml._internal.frameworks.keras",
warning="`bentoml.keras` is deprecated since v1.4 and will be removed in a future version.",
)
pytorch = _LazyLoader(
"bentoml.pytorch", globals(), "bentoml._internal.frameworks.pytorch"
"bentoml.pytorch",
globals(),
"bentoml._internal.frameworks.pytorch",
warning="`bentoml.pytorch` is deprecated since v1.4 and will be removed in a future version.",
)
pytorch_lightning = _LazyLoader(
"bentoml.pytorch_lightning",
globals(),
"bentoml._internal.frameworks.pytorch_lightning",
warning="`bentoml.pytorch_lightning` is deprecated since v1.4 and will be removed in a future version.",
)
picklable_model = _LazyLoader(
"bentoml.picklable_model",
globals(),
"bentoml._internal.frameworks.picklable_model",
warning="`bentoml.picklable_model` is deprecated since v1.4 and will be removed in a future version.",
)
tensorflow = _LazyLoader(
"bentoml.tensorflow", globals(), "bentoml._internal.frameworks.tensorflow"
"bentoml.tensorflow",
globals(),
"bentoml._internal.frameworks.tensorflow",
warning="`bentoml.tensorflow` is deprecated since v1.4 and will be removed in a future version.",
)
torchscript = _LazyLoader(
"bentoml.torchscript", globals(), "bentoml._internal.frameworks.torchscript"
"bentoml.torchscript",
globals(),
"bentoml._internal.frameworks.torchscript",
warning="`bentoml.torchscript` is deprecated since v1.4 and will be removed in a future version.",
)
transformers = _LazyLoader(
"bentoml.transformers", globals(), "bentoml._internal.frameworks.transformers"
"bentoml.transformers",
globals(),
"bentoml._internal.frameworks.transformers",
warning="`bentoml.transformers` is deprecated since v1.4 and will be removed in a future version.",
)

# Integrations
Expand Down
2 changes: 2 additions & 0 deletions src/bentoml/_internal/runner/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from ..configuration.containers import BentoMLContainer
from ..models.model import Model
from ..tag import validate_tag_str
from ..utils import deprecated
from ..utils import first_not_none
from .runnable import Runnable
from .runner_handle import DummyRunnerHandle
Expand Down Expand Up @@ -114,6 +115,7 @@ def init_client(
"""


@deprecated(suggestion="Please upgrade to new style services.")
@attr.define(slots=False, frozen=True, eq=False, init=False)
class Runner(AbstractRunner):
if t.TYPE_CHECKING:
Expand Down
2 changes: 2 additions & 0 deletions src/bentoml/_internal/runner/strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@

from ..resource import get_resource
from ..resource import system_resources
from ..utils import deprecated

if t.TYPE_CHECKING:
from .runnable import Runnable

logger = logging.getLogger(__name__)


@deprecated()
class Strategy(abc.ABC):
@classmethod
@abc.abstractmethod
Expand Down
2 changes: 2 additions & 0 deletions src/bentoml/_internal/service/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from ..runner.runner import AbstractRunner
from ..runner.runner import Runner
from ..tag import Tag
from ..utils import deprecated
from ..utils import first_not_none
from .inference_api import InferenceAPI

Expand Down Expand Up @@ -78,6 +79,7 @@ def get_valid_service_name(user_provided_svc_name: str) -> str:
return lower_name


@deprecated("bentoml.Service", suggestion="Please upgrade to @bentoml.service().")
@attr.define(frozen=False, init=False)
class Service:
"""The service definition is the manifestation of the Service Oriented Architecture
Expand Down
44 changes: 44 additions & 0 deletions src/bentoml/_internal/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import re
import socket
import typing as t
import warnings
from datetime import date
from datetime import datetime
from datetime import time
Expand Down Expand Up @@ -588,3 +589,46 @@ def wrapper(app: Starlette) -> T:
return func()

return wrapper


class BentoMLDeprecationWarning(DeprecationWarning):
pass


warnings.simplefilter("default", BentoMLDeprecationWarning)


def warn_deprecated(message: str, stacklevel: int = 2) -> None:
warnings.warn(
message, category=BentoMLDeprecationWarning, stacklevel=stacklevel + 1
)


def deprecated(
name: str = "", deprecated_since: str = "1.4", suggestion: str = ""
) -> t.Callable[[t.Callable[P, T]], t.Callable[P, T]]:
def decorator(func: t.Callable[P, T]) -> t.Callable[P, T]:
obj_name = name or func.__name__

class _DeprecatedMixin:
def __init__(self, *args: P.args, **kwargs: P.kwargs) -> None:
warn_deprecated(
f"`{obj_name}` is deprecated since BentoML v{deprecated_since} and will be removed in a future version."
+ (f" {suggestion}" if suggestion else "")
)
super().__init__(*args, **kwargs)

if inspect.isclass(func):
return type(func.__name__, (_DeprecatedMixin, func), {})

@functools.wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
warn_deprecated(
f"`{obj_name}` is deprecated since BentoML v{deprecated_since} and will be removed in a future version."
+ (f" {suggestion}" if suggestion else "")
)
return func(*args, **kwargs)

return wrapper

return decorator
4 changes: 3 additions & 1 deletion src/bentoml/_internal/utils/lazy_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def __init__(

def _load(self) -> types.ModuleType:
"""Load the module and insert it into the parent's globals."""
from . import warn_deprecated

# Import the target module and insert it into the parent's namespace
try:
module = importlib.import_module(self.__name__)
Expand All @@ -54,7 +56,7 @@ def _load(self) -> types.ModuleType:

# Emit a warning if one was specified
if self._warning:
logger.warning(self._warning)
warn_deprecated(self._warning, stacklevel=3)
# Make sure to only warn once.
self._warning = None

Expand Down
9 changes: 9 additions & 0 deletions src/bentoml/io.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# ruff: noqa: E402

from __future__ import annotations

from bentoml._internal.utils import warn_deprecated

warn_deprecated(
"`bentoml.io` is deprecated since BentoML v1.4 and will be removed in a future version. Please upgrade to new style IO types instead.",
stacklevel=1,
)

from ._internal.io_descriptors import from_spec
from ._internal.io_descriptors.base import IODescriptor
from ._internal.io_descriptors.file import File
Expand Down

0 comments on commit f8874ef

Please sign in to comment.