问题
I am having issues with implementing a custom AutoML model in a .NET web app that allows sending images via the REST API to be recognized. I keep getting errors.
The remote server returned an error: (403) Forbidden.
I have an image and converted it into a string of bytes called imageBytesString
and have created the jsonRequest object like this:
string jsonRequest = "{\"payload\":{\"image\":{\"imageBytes\":\"" + imageBytesString + "\"},}}";`
Then I'm doing a POST request like follows:
WebRequest request = WebRequest.Create(@"https://automl.googleapis.com/v1beta1/projects/PROJECT_ID/locations/us-central1/models/MODEL_ID:predict");
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("Authorization", "Bearer GCLOUD_ACCESS_TOKEN");
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(jsonRequest);
}
Then when it hits request.GetResponse();
if gives me the above error with no other information.
For reference, these are the snippets taken from the bottom of the PREDICT page on my custom AutoML model:
request.json:
{
"payload": {
"image": {
"imageBytes": "YOUR_IMAGE_BYTE"
},
}
}
Execute the request:
curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
https://automl.googleapis.com/v1beta1/projects/PROJECT_ID/locations/us-central1/models/MODEL_ID:predict -d @request.json
Thanks
回答1:
The curl
request you reference passes an access token in the header using the gcloud auth application-default print-access-token
command. This produces a new token every time it is ran. The token has an expiration time, typically 3600 seconds. You can check that yourself by running: curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=GCLOUD_ACCESS_TOKEN
. This will return a payload including a "expires_in"
field. So, passing the token as a GCLOUD_ACCESS_TOKEN
environment variable will result in a 403 error after it expires. What you should do instead is create a service account with the correct permissions, download a json with its credentials and set GOOGLE_APPLICATION_CREDENTIALS
to the json's path. Check here under Download credentials for an example in .NET.
回答2:
I was finally able to get it working.
There were 2 issues that needed to be fixed for it to work.
Firstly; for some reason, when I initially created the service account and entered the command gcloud auth activate-service-account --key-file="[/PATH/TO/KEY/FILE.json]
, it told me that it worked and the service account was added to the gcloud auth list
list. But upon checking again, it wasn't there so I ran it again.
Secondly; I was getting the access token with the following command:
gcloud auth application-default print-access-token
Instead, I tried using the access token received with the following command:
gcloud auth print-access-token
(Without application-default
) in there.
After I had done both those things, I am now able to successfully send an image request and receive the prediction response.
But it seems I still have to get a new access token every hour though... But that's another issue I suppose.
回答3:
A better solution is to access the Auto ML endpoint only from within the same project (then you won't need access tokens).
To access the endpoint from outside of the project, use an API gateway such as APIGEE or AppEngine -- those give you much better controls
来源:https://stackoverflow.com/questions/51805268/403-forbidden-when-trying-to-send-an-image-to-my-custom-automl-model-via-the