googleapis / proto-plus-python

Beautiful, idiomatic protocol buffers in Python
Apache License 2.0
166 stars 32 forks source link

AttributeError: 'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute 'WhichOneof' #442

Open WaterKnight1998 opened 11 months ago

WaterKnight1998 commented 11 months ago

Environment details

More important libs:

google-auth==2.23.2
google-cloud-aiplatform==1.34.0
protobuf==3.20.3
google-cloud-core-2.3.3
google-api-core-2.12.0

Code example

Client extracted from here: https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/matching_engine/sdk_matching_engine_create_multimodal_embeddings.ipynb

import base64
import time
import typing

from google.cloud import aiplatform
from google.protobuf import struct_pb2

class EmbeddingResponse(typing.NamedTuple):
    text_embedding: typing.Sequence[float]
    image_embedding: typing.Sequence[float]

def load_image_bytes(image_uri: str) -> bytes:
    """Load image bytes from a remote or local URI."""
    image_bytes = None
    if image_uri.startswith("http://") or image_uri.startswith("https://"):
        response = requests.get(image_uri, stream=True)
        if response.status_code == 200:
            image_bytes = response.content
    else:
        image_bytes = open(image_uri, "rb").read()
    return image_bytes

class EmbeddingPredictionClient:
    """Wrapper around Prediction Service Client."""

    def __init__(
        self,
        project: str,
        location: str = "us-central1",
        api_regional_endpoint: str = "us-central1-aiplatform.googleapis.com",
    ):
        client_options = {"api_endpoint": api_regional_endpoint}
        # Initialize client that will be used to create and send requests.
        # This client only needs to be created once, and can be reused for multiple requests.
        self.client = aiplatform.gapic.PredictionServiceClient(
            client_options=client_options
        )
        self.location = location
        self.project = project

    def get_embedding(self, text: str = None, image_file: str = None):
        if not text and not image_file:
            raise ValueError("At least one of text or image_file must be specified.")

        # Load image file
        image_bytes = None
        if image_file:
            image_bytes = load_image_bytes(image_file)

        instance = struct_pb2.Struct()
        if text:
            instance.fields["text"].string_value = text

        if image_bytes:
            encoded_content = base64.b64encode(image_bytes).decode("utf-8")
            image_struct = instance.fields["image"].struct_value
            image_struct.fields["bytesBase64Encoded"].string_value = encoded_content

        instances = [instance]
        endpoint = (
            f"projects/{self.project}/locations/{self.location}"
            "/publishers/google/models/multimodalembedding@001"
        )
        response = self.client.predict(endpoint=endpoint, instances=instances)

        text_embedding = None
        if text:
            text_emb_value = response.predictions[0]["textEmbedding"]
            text_embedding = [v for v in text_emb_value]

        image_embedding = None
        if image_bytes:
            image_emb_value = response.predictions[0]["imageEmbedding"]
            image_embedding = [v for v in image_emb_value]

        return EmbeddingResponse(
            text_embedding=text_embedding, image_embedding=image_embedding
        )

Stack trace

Result: Failure

Exception: AttributeError: 'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute 'WhichOneof'
File "/home/site/wwwroot/.python_packages/lib/site-packages/proto/message.py", line 752, in __getattr__

return marshal.to_python(pb_type, pb_value, absent=key not in self)

File "/home/site/wwwroot/.python_packages/lib/site-packages/proto/marshal/marshal.py", line 193, in to_python

return self.get_rule(proto_type=proto_type).to_python(value, absent=absent)

File "/home/site/wwwroot/.python_packages/lib/site-packages/proto/marshal/rules/struct.py", line 39, in to_python

kind = value.WhichOneof("kind")

Making sure to follow these steps will guarantee the quickest resolution possible.

Thanks!

WaterKnight1998 commented 11 months ago

Fixed with python 3.10

parthea commented 10 months ago

Closing as the issue appears to be addressed based on https://github.com/googleapis/proto-plus-python/issues/442

mukundha commented 7 months ago

I'm running into this exact same issue again,

Environment details OS type and version: Mac M2 Pro, Ventura 13.5.2 Python version: 3.11.6 pip version: 24.0 google-cloud-aiplatform version: 1.42.1 More important libs:

google-auth==2.28.1 google-cloud-aiplatform==1.34.0 protobuf==4.25.3 google-cloud-core==2.4.1 google-api-core==2.17.1

---------------------------------------------------------------------------

Cell In[115], line 66, in EmbeddingPredictionClient.get_embedding(self, text, image_file)
     61 instances = [instance]        
     62 endpoint = (
     63     f"projects/{self.project}/locations/{self.location}"
     64     "/publishers/google/models/multimodalembedding@001"
     65 )
---> 66 response = self.client.predict(endpoint=endpoint, instances=instances)
     68 text_embedding = None
     69 if text:

File /opt/homebrew/lib/python3.11/site-packages/google/cloud/aiplatform_v1/services/prediction_service/client.py:591, in PredictionServiceClient.predict(self, request, endpoint, instances, parameters, retry, timeout, metadata)
    589     request.endpoint = endpoint
    590 if instances is not None:
--> 591     request.instances.extend(instances)
    592 if parameters is not None:
    593     request.parameters = parameters

File /opt/homebrew/lib/python3.11/site-packages/proto/message.py:763, in Message.__getattr__(self, key)
    761 pb_value = getattr(self._pb, key)
    762 marshal = self._meta.marshal
--> 763 return marshal.to_python(pb_type, pb_value, absent=key not in self)

File /opt/homebrew/lib/python3.11/site-packages/proto/marshal/marshal.py:193, in BaseMarshal.to_python(self, proto_type, value, absent)
    191 if value_type in compat.map_composite_types:
    192     return MapComposite(value, marshal=self)
--> 193 return self.get_rule(proto_type=proto_type).to_python(value, absent=absent)

File /opt/homebrew/lib/python3.11/site-packages/google/cloud/aiplatform/utils/enhanced_library/_decorators.py:24, in ConversionValueRule.to_python(self, value, absent)
     23 def to_python(self, value, *, absent: bool = None):
---> 24     return super().to_python(value, absent=absent)

File /opt/homebrew/lib/python3.11/site-packages/proto/marshal/rules/struct.py:39, in ValueRule.to_python(self, value, absent)
     29 def to_python(self, value, *, absent: bool = None):
     30     """Coerce the given value to the appropriate Python type.
     31 
     32     Note that both NullValue and absent fields return None.
   (...)
     37     which is True for NullValue and False for an absent value.
     38     """
---> 39     kind = value.WhichOneof("kind")
     40     if kind == "null_value" or absent:
     41         return None

AttributeError: 'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute 'WhichOneof'
matthiasa4 commented 6 months ago

@mukundha @parthea same here.

Himanshu-28 commented 6 months ago

Hi @mukundha @parthea @WaterKnight1998 facing the same issue, were you guys able to solve it? I am facing this issue while using - FAISS.from_documents(documents=documents, embedding=embedding)

parthea commented 6 months ago

Hi @Himanshu-28, @matthiasa4, @mukundha,

Please could you run the following code to confirm the version of protobuf at runtime, in case it is different from what is shown in pip freeze?

import google.protobuf
google.protobuf.__version__
partheniou@partheniou-vm-3:~$ python3
Python 3.12.0 (main, Oct 19 2023, 15:49:09) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import google.protobuf
>>> google.protobuf.__version__
'4.25.0'
parthea commented 5 months ago

Closing due to no activity

vsvn-DangNH commented 5 months ago

my protobuf version is 4.25.3 @parthea . I have same issue here

oniki-olesh commented 5 months ago

Hi, I have the same issue when trying to run some model from vertex ai

My machine is Apple M1 Max Google Cloud SDK 471.0.0 bq 2.1.3 core 2024.03.29 gcloud-crc32c 1.0.0 gsutil 5.27 Python 3.11.0 protobuf = 5.26.1

My sdk's linters also complain that google.protobuf.struct_pb2 doesn't have class Value

vsvn-DangNH commented 5 months ago

I fixed it by downgrade to python 3.10.9.