I am trying to hit my Vertex AI endpoint from a Golang web application (the web server/application is running on cloud run+build). The web application has a form that I'm landing into the Details Submission, my question is, how do I take the struct received from the web application and cast it to a type accepted in the Instances field of the aiplatformb.PredictRequest struct?
type Submission struct {
MonthlyIncome int
Age int
Passport int
}
var Details = Submission{}
Ctx := context.Background()
C, err := aiplatform.NewPredictionClient(Ctx)
if err != nil {
log.Fatalf("Error 1: %v", err)
}
defer C.Close()
reqs := &aiplatformpb.PredictRequest{
Endpoint: "{{my endpoint that is formatted correctly}",
Instances: []*structpb.Value{},
I've tried hitting this endpoint externally using postman and the request below confirms the endpoint is up and running. Those values are the values of the Details Submission
{
"instances": [
[
29823,
43.5,
1
]
]
}
After several attempts using the client libraries and consulting documentation, the .Predict()
method [which acts on a pointer to PredictionClient
type] doesn't allow you to specify the schema of the vertex AI model endpoint. So the solution is to send the request via the .RawPredict()
method, so making a serialized JSON (structpb) request works only if the schema implemented by the golang GCP client library matches that of your deployed model.
Here's the GCP documentation for PredictionClient
:
Here are the necessary libraries for forming and using the RawPredict()
method:
import (
"context"
"fmt"
"log"
"reflect"
"strconv"
aiplatform "cloud.google.com/go/aiplatform/apiv1"
"cloud.google.com/go/aiplatform/apiv1/aiplatformpb"
"google.golang.org/api/option"
"google.golang.org/genproto/googleapis/api/httpbody"
)
And here's the code:
// Get the form values from the web application
income, _ := strconv.Atoi(r.FormValue("MonthlyIncome"))
age, _ := strconv.Atoi(r.FormValue("Age"))
passport, _ := strconv.Atoi(r.FormValue("Passport"))
// create our struct from the form values
Details = Submission{
MonthlyIncome: income,
Age: age,
Passport: passport,
}
v := reflect.ValueOf(Details)
body = ""
for i := 0; i < v.NumField(); i++ {
body = body + fmt.Sprintf("%v", v.Field(i).Interface()) + ","
}
if last := len(body) - 1; last >= 0 && body[last] == ',' {
body = body[:last]
}
Requestb = pre + body + post
log.Println("The request string was:", Requestb)
// structure the body of the raw request
Raw := &httpbody.HttpBody{}
Raw.Data = []byte(Requestb)
// identify the post request using the raw body and the endpoint
reqs := &aiplatformpb.RawPredictRequest{
// Note GCP Project ID, Region, and endpoint ID
Endpoint: "projects/<PROJECT-HERE>/locations/<REGDION-HERE>/endpoints/<ENDPOINT-ID-HERE>",
HttpBody: Raw,
}
// CTX gets the credentials of the application service account - NOTE THE REGION
Ctx := context.Background()
C, err := aiplatform.NewPredictionClient(Ctx, option.WithEndpoint("<REGION-HERE>-aiplatform.googleapis.com:443"))
if err != nil {
log.Println("Error 1, connectrion:", err)
}
defer C.Close()
// gets the response using the credentials of the application service account
resp, err := C.RawPredict(Ctx, reqs)
if err != nil {
log.Fatalf("Error 2, response: %v", err)
}
log.Println(resp)
RespString := fmt.Sprintf("%+v", resp)
log.Println("The Response String was:", resp)