Search code examples
google-cloud-ml-engine

Google Machine Learning API Issue


I'm trying to use the Google Machine Learning API and I'm facing two problems. In the API explorer I put the correct information and I get a response error:

Code 200 "error": "Missing \"instances\" field in request body: {\n \"httpBody\": \n
{\n \"data\": \"\\"instances\\" : \\"teste\\"\",\n
\"contentType\": \"application/json\"\n }\n}"

The request find my model (if I change the value in field name I get another error) but don't understand my json. That's the json:

{"instances" : [{"key":"0", "image_bytes": {"b64": "mybase64"} }]}

When I do the predict on the command line using gcloud, I get no errors and everything seems ok. The Json that I was create for gcloud is a little bit different:

{"key":"0", "image_bytes": {"b64": "mybase64"} }

I already tryied that one in the API explorer and no success.

So, I decided to use the .Net Api to try the predict and I get other situation: The Response is Empty (???).

Here is my code:

   'get the service credential that I created
    Dim credential = Await GetCredential()


    Dim myService As New CloudMachineLearningEngineService(New BaseClientService.Initializer() With {
                                                                    .ApplicationName = "my Project Name (Is That It???)",
                                                                    .ApiKey = "my API Key",
                                                                    .HttpClientInitializer = credential
                                                               })

    Dim myBase64 As String = GetBase64("my image path to convert into a base64 String")
    Dim myJsonRequest As String = "{""instances"" : [{""key"":""0"", ""image_bytes"": {""b64"": """ + myBase64 + """}}]}"

    Dim myRequest = New GoogleCloudMlV1PredictRequest With {
        .HttpBody = New GoogleApiHttpBody With {.Data = myJsonRequest,
                                                .ContentType = "application/json"
                                                }
    }

    'If I change the model name I get error
    Dim myPredictRequest = myService.Projects.Predict(myRequest, "projects/myProject/models/myModel/versions/v1")
    myPredictRequest.AccessToken = credential.Token.AccessToken
    myPredictRequest.OauthToken = credential.Token.AccessToken
    myPredictRequest.Key = "my API Key

    'Execute the request
    Dim myResponse = myPredictRequest.Execute()

    'at this point, myResponse is Empty (myResponse.ContentType Is Nothing, myResponse.Data Is Nothing And myResponse.ETag Is Nothing)

If I change the model name I get a error informing that my model was not found, so my credentials are right.

I don't know what I'm doing wrong. Someboby can help with any of this issues?

Thanks!

UPDATE: --------------------------

I changed this Execute Command: Dim myResponse = myPredictRequest.Execute()
To This One: Dim s = StreamToString(myPredictRequest.ExecuteAsStream())

and Now I can get the same error with .Net API and google developers interface (Missing instances field...). So If someboby just Know what is wrong with my Json request, It will help a lot.


Solution

  • I solved the problem with .Net API. I created two new classes Inherits the Google API's classes. Something like that:

    Imports Google.Apis.CloudMachineLearningEngine.v1.Data
    Imports Newtonsoft.Json
    
    Public Class myGoogleCloudMlV1PredictRequest
        Inherits GoogleCloudMlV1PredictRequest
    
        <JsonProperty("instances")>
        Public Property MyHttpBody As List(Of myGoogleApiHttpBody)
    End Class
    
    
    
    Imports Google.Apis.CloudMachineLearningEngine.v1.Data
    Imports Newtonsoft.Json
    
    Public Class myGoogleApiHttpBody
        Inherits GoogleApiHttpBody
    
        <JsonProperty("image_bytes")>
        Public Property MyData As image_byte
    
        <JsonProperty("key")>
        Public Property key As String
    
    End Class
    

    So, in my original code I change this part:

        Dim myBase64 As String = GetBase64("my_image_path_to_convert_into_a _base64_String")
        Dim myJsonRequest As String = "{""instances"" : [{""key"":""0"", ""image_bytes"": {""b64"": """ + myBase64 + """}}]}"
    
        Dim myRequest = New GoogleCloudMlV1PredictRequest With {
            .HttpBody = New GoogleApiHttpBody With {.Data = myJsonRequest,
                                                   .ContentType = "application/json"
                                                }
        }
    

    For this one:

    Dim myBase64 As String = GetBase64("my_image_path_to_convert_into_a _base64_String")
    Dim myRequest = New myGoogleCloudMlV1PredictRequest With {
                .MyHttpBody = New List(Of myGoogleApiHttpBody)()
            }
    
            Dim item As myGoogleApiHttpBody = New myGoogleApiHttpBody With {
                                                        .key = "0",
                                                        .MyData = New image_byte With {
                                                            .b64 = myBase64
                                                        }
                                                     }
            myRequest.MyHttpBody.Add(item)
    

    And voilá, It's working!

    Thanks for everyone!!