2

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!!

Gdiribarne
  • 21
  • 3

1 Answers1

1

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

Ricco D
  • 6,873
  • 1
  • 8
  • 18
  • Thanks for your answer! I removed the putenv(); from my code and the error persists. I've already export the credentials by linux command and follow all recomendations from https://stackoverflow.com/questions/48720306/request-had-invalid-authentication-credentials-expected-oauth-2-access-token-er. Also mi service account has automl - owner role. I tried changing to another service account and results are the same. There is something i'am missing here, do you have another recomendation for this case? – Gdiribarne Feb 15 '21 at 17:45
  • Same issue here with any kind of operation about AutoML, no just predict. Deploy, undeploy, update nodes etc. I exported the service account into ubuntu env variable like google recommends, and tried that exactly php code commented here and i have "error_description":"Invalid OAuth scope or ID tok en audience provided." – martin Feb 15 '21 at 21:10
  • The test I shown above is done in CloudShell. Can you try running your code in CloudShell? Also if you are using an IDE to run your PHP code, what IDE is that? – Ricco D Feb 16 '21 at 06:07
  • I'm using PHPSTORM v 2019.3. If i run the curl on console I got a success prediction, but the error persist on both codes with the errors in the question. – Gdiribarne Feb 16 '21 at 14:42
  • Tested on cloudShell and get the same issue. Predicting with curl is working to me too. – martin Feb 16 '21 at 19:52
  • @Gdiribarne Did you try [setting the environment variable GOOGLE_APPLICATION_CREDENTIALS in PHPSTORM?](https://www.jetbrains.com/help/objc/add-environment-variables-and-program-arguments.html#add-environment-variables) – Ricco D Feb 17 '21 at 05:12
  • @martin Just to confirm, when you exported GOOGLE_APPLICATION_CREDENTIALS in cloudshell. Did you use the correct path to the service account intended for AutoML? You can check the steps for that in this [reference.](https://cloud.google.com/vision/automl/docs/before-you-begin#set-up-your-project) – Ricco D Feb 17 '21 at 05:13
  • @RiccoD I tried on CloudShell and got a success prediction. But in my local when I tried to make a prediction using my code the same error persists. When I unset the credential I got a different error "code": 7, "status": "PERMISSION_DENIED" which means the credentials are setting correctly, but for some reason the autentication fails. Also I tried what you suggest setting the enviromental variable in PHPSTORM and still got "error":"invalid_scope". – Gdiribarne Feb 17 '21 at 16:36
  • @Gdiribarne can you try running `gcloud auth application-default login` so your environment will be authenticated using your email which has a role of owner. When doing this you should not be setting the environment variable `GOOGLE_APPLICATION_CREDENTIALS`. – Ricco D Feb 18 '21 at 06:16
  • @RiccoD I've tried login as you say, this is one of the recomendations from the [link](https://stackoverflow.com/questions/48720306/request-had-invalid-authentication-credentials-expected-oauth-2-access-token-er) I put in the first comment. And the error is the same. What I don't understand is why the error says "invalid_scope", I debug the request process and the scope (https://www.googleapis.com/auth/cloud-platform) is correctly defined. I also tried to use other Google's service as Vision to get the image properties with success results using the credentials exported and with putenv(). – Gdiribarne Feb 18 '21 at 14:31