Search code examples
pythongrpc-pythonclarifai

gRPC failed to connect to all addresses - Python


I am trying to connect to Clarifai's 'general' image classification model to label images using the following Python script:

#python program to analyze an image and label it
##############################################################################
# Installation
##############################################################################

#pip install clarifai-grpc

##############################################################################
## Initialize client
##     - This initializes the gRPC based client to communicate with the 
##       Clarifai platform. 
##############################################################################
## Import in the Clarifai gRPC based objects needed
from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_pb2, status_code_pb2

## Construct the communications channel and the object stub to call requests on.
# Note: You can also use a secure (encrypted) ClarifaiChannel.get_grpc_channel() however
# it is currently not possible to use it with the latest gRPC version
channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)


################################################################################
## Set up Personal Access Token and Access information
##     - This will be used by every Clarifai API call 
################################################################################
## Specify the Authorization key.  This should be changed to your Personal Access Token.
## Example: metadata = (('authorization', 'Key 123457612345678'),) 
metadata = (('authorization', 'Key <PERSONAL ACCESS TOKEN>'),)

##
## A UserAppIDSet object is needed for most rpc calls.  This object contains
## two pieces of information: the user id and the app id.  Both of these are
## specified as string values.
##
##     'user_id' : This is your user id
##     'app_id'  : This is the app id which contains the model of interest
userDataObject = resources_pb2.UserAppIDSet(user_id='<USERNAME>', app_id='<APP ID>')

# Insert here the initialization code as outlined on this page:
# https://docs.clarifai.com/api-guide/api-overview/api-clients#client-installation-instructions

post_model_outputs_response = stub.PostModelOutputs(
    service_pb2.PostModelOutputsRequest(
        user_app_id=userDataObject,  # The userDataObject is created in the overview and is required when using a PAT
        model_id="aaa03c23b3724a16a56b629203edc62c",
        version_id="aa7f35c01e0642fda5cf400f543e7c40",  # This is optional. Defaults to the latest model version.
        inputs=[
            resources_pb2.Input(
                data=resources_pb2.Data(
                    image=resources_pb2.Image(
                        url="https://samples.clarifai.com/metro-north.jpg"
                    )
                )
            )
        ]
    ),
    metadata=metadata
)
if post_model_outputs_response.status.code != status_code_pb2.SUCCESS:
    print("There was an error with your request!")
    print("\tCode: {}".format(post_model_outputs_response.outputs[0].status.code))
    print("\tDescription: {}".format(post_model_outputs_response.outputs[0].status.description))
    print("\tDetails: {}".format(post_model_outputs_response.outputs[0].status.details))
    raise Exception("Post model outputs failed, status: " + post_model_outputs_response.status.description)

# Since we have one input, one output will exist here.
output = post_model_outputs_response.outputs[0]

print("Predicted concepts:")
for concept in output.data.concepts:
    print("%s %.2f" % (concept.name, concept.value))

However, I am getting the following error:

Traceback (most recent call last):
  File "C:\Users\Eshaan\Desktop\moveForward\Python\Level 4\New try\Vision MFSA.py", line 45, in <module>
    post_model_outputs_response = stub.PostModelOutputs(
  File "C:\Users\Eshaan\AppData\Local\Programs\Python\Python39\lib\site-packages\grpc\_channel.py", line 946, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "C:\Users\Eshaan\AppData\Local\Programs\Python\Python39\lib\site-packages\grpc\_channel.py", line 849, in _end_unary_response_blocking
    raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
    status = StatusCode.UNAVAILABLE
    details = "failed to connect to all addresses"
    debug_error_string = "{"created":"@1634655221.541000000","description":"Failed to pick subchannel","file":"src/core/ext/filters/client_channel/client_channel.cc","file_line":3009,"referenced_errors":[{"created":"@1634655221.541000000","description":"failed to connect to all addresses","file":"src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc","file_line":398,"grpc_status":14}]}"
>

Any idea/suggestion on why this is and how to fix it? I referred to the following documentation : https://docs.clarifai.com/api-guide/predict/images

I haven't added a single line of code from my side, it's all from the documentation plus the required keys. I have looked at all the related answers on the site but still haven't been able to figure it out.


Solution

  • There is currently an issue with gRPC in how it supports certain certificates. You might be able to update to the latest version in order to fix this, or as an alternative you can use a slightly different approach and change:

    channel = ClarifaiChannel.get_grpc_channel()

    to

    channel = ClarifaiChannel.get_json_channel()

    Which will basically side-step the problem by using REST behind the scenes.

    (NOTE: the rest of the program including parsing will continue to work as expected even with this change, it is just changing the communication method.)