jaspercoleman
jaspercoleman

Reputation: 126

Google Vertex AI Prediction API Prediction request error

I am trying to pass a Python Dict into aiplatform_v1.PredictRequest and make prediction with aiplatform_v1.PredictionServiceAsyncClient.

I have encountered this error: TypeError: Argument for field google.cloud.aiplatform.v1.PredictRequest.instances is not iterable

I have parsed my Python Dict into google.protobuf value and wrap it as a list, which should be iterable, as shown in this
Official Python Request Sample Link

Below please find my code for reference:

from google.protobuf.struct_pb2 import Value, Struct, ListValue
from google.protobuf import json_format
from google.oauth2 import service_account
from google.api_core import exceptions
from google.cloud import aiplatform_v1

async def model_predict(json_data):

    # Load credentials from a service account key file
    key_path = 'path-to-key-file.json'
    credentials = service_account.Credentials.from_service_account_file(
        key_path,
        scopes=['https://www.googleapis.com/auth/cloud-platform']
    )
   
    # Set up the endpoint configs and pass user input
    project_id = "XXXXXX"
    endpoint_id = "XXXXXXX"
    instance_dict = json_data
    location = "us-central1"
    api_endpoint = "us-central1-aiplatform.googleapis.com"
    
    # Format user input to pass into request
    instance = json_format.ParseDict(instance_dict, Value())
    parameters_dict = {}
    parameters= json_format.ParseDict(parameters_dict, Value())

    # Set up async prediction service client 
    client_options = {"api_endpoint": api_endpoint}

    prediction_client = aiplatform_v1.PredictionServiceAsyncClient(
        credentials=credentials, client_options=client_options
    )

    # Build Prediction request
    endpoint_path = prediction_client.endpoint_path(
        project=project_id, location=location, endpoint=endpoint_id,
    )

    request = aiplatform_v1.PredictRequest(
        endpoint=endpoint_path, instances= [instance], parameters = parameters
    )

    # Call the predict method asynchronously
    try:
        response = await prediction_client.predict(request=request)
        print(response)
        predictions = response.predictions

        return predictions, None

    except exceptions.GoogleAPIError as error:
        error_message = f"Prediction request failed: {error}"
        return None, error_message

I have printed the type and sample of instances passed through under this code. \

<class 'google.protobuf.struct_pb2.Value'> struct_value { fields { key: "Ticket_Subject" value { string_value: "Battery Issue" } } fields { key: "Ticket_Status" value { string_value: "Open" } } fields { key: "Ticket_Priority" value { string_value: "High" } } .... (more fields structured as above) }

Upvotes: 1

Views: 1439

Answers (1)

jaspercoleman
jaspercoleman

Reputation: 126

Self-Answered

#1
Google has updated its protobuf package to rely on Proto Plus for Python
Link to Library

Inside the PDF documentation which is available for download, on P.17
You can see that only ListValue are considered to be Mutable Sequence, which is the requirement for instance object in Google Prediction Request
You can only append values into a ListValue Object, instead of direct assignment.

#2
Regarding the use of PredictionServiceAsyncClient to make PredictRequest:
You can choose not to parse the instance_dict and directly append instead.

from google.cloud import aiplatform_v1

client_options = {"api_endpoint": api_endpoint}

prediction_client = aiplatform_v1.PredictionServiceAsyncClient(
    credentials=credentials, 
    client_options=client_options
)

# Build Prediction request
# Append the input python dictonary as instances
endpoint_path = prediction_client.endpoint_path(
    project=project_id, location=location, endpoint=endpoint_id,
)

# Direct append instance_dict as instances
request = aiplatform_v1.PredictRequest()
request.endpoint = endpoint_path
request.instances.append(instance_dict)

# Call the predict method asynchronously
try:
    response = await prediction_client.predict(request=request)
    predictions = response.predictions
    return predictions, None

except exceptions.GoogleAPIError as error:
    error_message = f"Prediction request failed: {error}"
    return None, error_message

Upvotes: 2

Related Questions