2
votes

I'm trying to use Google AutoML prediction service with a custom model I trained and it's returning the following error:

Client error: `POST https://oauth2.googleapis.com/token` resulted in a `400 Bad Request` response:
{"error":"invalid_scope","error_description":"Invalid OAuth scope or ID token audience provided."}

I'm using the following code, similar to the documentation:

use Google\Cloud\AutoMl\V1\ExamplePayload;
use Google\Cloud\AutoMl\V1\Image;
use Google\Cloud\AutoMl\V1\PredictionServiceClient;

putenv("GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json");

$service = new PredictionServiceClient();
        try {
            $formattedName = $service->modelName('project-name', 'region', 'model');
            $content = file_get_contents($filePath); //defined in other side as the path to the photo
            $image = (new Image())->setImageBytes($content);
            $payload = (new ExamplePayload())->setImage($image);
            $params = ['score_threshold' => '0.5']; // value between 0.0 and 1.0
            $response = $service->predict($formattedName, $payload, $params);
            $annotations = $response->getPayload();
            foreach ($annotations as $annotation) {
                $spaceName = $annotation->getDisplayName();
            }
        } finally {
            $service->close();
        }

And I tried to use the curl provided by google after deploy the model and the result is the following:

   {
      "error": {
        "code": 401,
        "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
        "status": "UNAUTHENTICATED"
      }
    }

The code used in this case is:

         putenv("GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json");
         $file = file_get_contents('/path/to/photo.jpg');
         $image = base64_encode($file);
         $url = "https://automl.googleapis.com/v1/projects/[project_name]/locations/[region]/models/[model]:predict";

         $curl = curl_init($url);
         curl_setopt($curl, CURLOPT_URL, $url);
         curl_setopt($curl, CURLOPT_POST, true);
         curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

         $headers = [
         "Content-Type: application/json",
         "Authorization: Bearer $(gcloud auth application-default print-access-token)",
         ];
         curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

         $data = '{"payload":{"image":{"imageBytes": "' . $image . '"}}}';
         curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
         //for debug only!
         curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
         curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

         $resp = curl_exec($curl);
         curl_close($curl);

I've followed all documentations about how to get credentials and there are in the key.json file.

Does anyone know what I need to make a success prediction? Thanks in advance!!

1

1 Answers

1
votes

It is possible that putenv("GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json"); is not taking effect since the Oauth error is returned. Instead, you can remove it on your code and set the environment variable prior to running your script. Just make sure that you are using the correct path to your service account.

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/key.json"

I tested this using your code and just add priting of name. I used the dataset in AutoML Vision quick start which detects flowers.

use Google\Cloud\AutoMl\V1\ExamplePayload;
use Google\Cloud\AutoMl\V1\Image;
use Google\Cloud\AutoMl\V1\PredictionServiceClient;

$filePath = '/my_file_path/red-rose.jpg';
$service = new PredictionServiceClient();
        try {
            $formattedName = $service->modelName('my-project', 'us-central1', 'my-model-id');
            $content = file_get_contents($filePath); //defined in other side as the path to the photo
            $image = (new Image())->setImageBytes($content);
            $payload = (new ExamplePayload())->setImage($image);
            $params = ['score_threshold' => '0.5']; // value between 0.0 and 1.0
            $response = $service->predict($formattedName, $payload, $params);
            $annotations = $response->getPayload();
            foreach ($annotations as $annotation) {
                    $spaceName = $annotation->getDisplayName();
                    printf('Predicted class name: %s' . PHP_EOL, $spaceName);
            }
        } finally {
            $service->close();
        }

Testing: enter image description here