bentoml / BentoML

The easiest way to serve AI apps and models - Build reliable Inference APIs, LLM apps, Multi-model chains, RAG service, and much more!

Home Page:https://bentoml.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

bug: AttributeError: type object 'GrpcClient' has no attribute '_create_channel'

antoniogomezalvarado opened this issue · comments

Describe the bug

Using latest bentoml==1.2.12 version

I'm following the docs on how to use a GRPC client

from __future__ import annotations

import asyncio
import logging

import numpy as np

import bentoml


async def async_run(client: bentoml.client.Client):
    res = await client.async_classify(np.array([[5.9, 3, 5.1, 1.8]]))
    logger.info("Result from 'client.async_classify':\n%s", res)
    res = await client.async_call("classify", np.array([[5.9, 3, 5.1, 1.8]]))
    logger.info("Result from 'client.async_call':\n%s", res)


def run(client: bentoml.client.Client):
    res = client.classify(np.array([[5.9, 3, 5.1, 1.8]]))
    logger.info("Result from 'client.classify':\n%s", res)
    res = client.call("classify", np.array([[5.9, 3, 5.1, 1.8]]))
    logger.info("Result from 'client.call(bentoml_api_name='classify')':\n%s", res)


if __name__ == "__main__":
    import argparse

    logger = logging.getLogger(__name__)

    ch = logging.StreamHandler()
    formatter = logging.Formatter("%(message)s")
    ch.setFormatter(formatter)
    logger.addHandler(ch)
    logger.setLevel(logging.DEBUG)

    parser = argparse.ArgumentParser()
    parser.add_argument("-s", "--sync", action="store_true", default=False)
    args = parser.parse_args()

    c = bentoml.client.Client.from_url("localhost:3000", kind="grpc")

    if args.sync:
        run(c)
    else:
        asyncio.run(async_run(c))

Trying to execute the above ☝️ and getting the following exception

root@42ca13f78843:/tmp/bentomlclientexample# python client_grpc_example.py
Traceback (most recent call last):
  File "/tmp/bentomlclientexample/client_grpc_example.py", line 46, in <module>
    c = bentoml.client.Client.from_url("0.0.0.0:3000", kind="grpc")
  File "/usr/local/lib/python3.10/site-packages/bentoml/_internal/client/__init__.py", line 109, in from_url
    return SyncClient.from_url(server_url, kind=kind, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/bentoml/_internal/client/__init__.py", line 367, in from_url
    return SyncGrpcClient.from_url(server_url, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/bentoml/_internal/client/grpc.py", line 728, in from_url
    with GrpcClient._create_channel(
AttributeError: type object 'GrpcClient' has no attribute '_create_channel'

Looking at the code

class GrpcClient(Client):
    def __init__(self, svc: Service, server_url: str):
        self._sync_client = SyncGrpcClient(svc=svc, server_url=server_url)
        self._async_client = AsyncGrpcClient(svc=svc, server_url=server_url)
        super().__init__(svc, server_url)

Neither GrpClient or Client (defined here) have _create_channel defined.

Not that crucial but also worth mentioning that kind="grpc" arg is needed which isn't stated by the doc ☝️ (I had to dig into the code to get it right)

To reproduce

No response

Expected behavior

The examples provided in https://docs.bentoml.org/en/v1.1.11/guides/grpc.html should work

Environment

Environment variable

BENTOML_DEBUG=''
BENTOML_QUIET=''
BENTOML_BUNDLE_LOCAL_BUILD=''
BENTOML_DO_NOT_TRACK=''
BENTOML_CONFIG=''
BENTOML_CONFIG_OPTIONS=''
BENTOML_PORT=''
BENTOML_HOST=''
BENTOML_API_WORKERS=''

System information

bentoml: 1.2.12
python: 3.10.9
platform: Linux-5.10.76-linuxkit-aarch64-with-glibc2.31
uid_gid: 0:0

pip_packages
absl-py==1.3.0
aiohttp==3.9.5
aiosignal==1.3.1
annotated-types==0.6.0
anyio==4.3.0
appdirs==1.4.4
asgiref==3.8.1
astunparse==1.6.3
async-timeout==4.0.3
attrs==23.2.0
bentoml==1.2.12
build==1.2.1
cachetools==5.2.0
cattrs==23.1.2
certifi==2022.12.7
charset-normalizer==2.1.1
circus==0.18.0
click==8.1.7
click-option-group==0.5.6
cloudpickle==3.0.0
contextlib2==21.6.0
deepmerge==1.1.1
Deprecated==1.2.14
exceptiongroup==1.2.1
flatbuffers==1.12
frozenlist==1.4.1
fs==2.4.16
gast==0.4.0
google-auth==2.15.0
google-auth-oauthlib==0.4.6
google-pasta==0.2.0
grpcio==1.51.1
h11==0.14.0
h5py==3.7.0
httpcore==1.0.5
httpx==0.27.0
idna==3.4
importlib-metadata==6.11.0
inflection==0.5.1
Jinja2==3.1.3
keras==2.9.0
Keras-Preprocessing==1.1.2
libclang==14.0.6
Markdown==3.4.1
markdown-it-py==3.0.0
MarkupSafe==2.1.1
mdurl==0.1.2
multidict==6.0.5
numpy==1.24.1
nvidia-ml-py==11.525.150
oauthlib==3.2.2
opentelemetry-api==1.20.0
opentelemetry-instrumentation==0.41b0
opentelemetry-instrumentation-aiohttp-client==0.41b0
opentelemetry-instrumentation-asgi==0.41b0
opentelemetry-sdk==1.20.0
opentelemetry-semantic-conventions==0.41b0
opentelemetry-util-http==0.41b0
opt-einsum==3.3.0
packaging==22.0
pathspec==0.12.1
pip-requirements-parser==32.0.1
pip-tools==7.4.1
prometheus_client==0.20.0
protobuf==3.19.6
psutil==5.9.8
pyasn1==0.4.8
pyasn1-modules==0.2.8
pydantic==2.7.0
pydantic_core==2.18.1
Pygments==2.17.2
pyparsing==3.1.2
pyproject_hooks==1.0.0
python-dateutil==2.9.0.post0
python-json-logger==2.0.7
python-multipart==0.0.9
PyYAML==6.0.1
pyzmq==26.0.2
requests==2.28.1
requests-oauthlib==1.3.1
rich==13.7.1
rsa==4.9
schema==0.7.5
simple-di==0.1.5
six==1.16.0
sniffio==1.3.1
starlette==0.37.2
tensorboard==2.9.1
tensorboard-data-server==0.6.1
tensorboard-plugin-wit==1.8.1
tensorflow==2.9.2
tensorflow-estimator==2.9.0
tensorflow-io-gcs-filesystem==0.29.0
termcolor==2.1.1
tomli==2.0.1
tomli_w==1.0.0
tornado==6.4
typing_extensions==4.11.0
urllib3==1.26.13
uvicorn==0.29.0
watchfiles==0.21.0
Werkzeug==2.2.2
wrapt==1.14.1
yarl==1.9.4
zipp==3.18.1