3
votes

Using the Python Google API client library from AppEngine flex, I'm making calls to GCP ML Engine API. It works fine when I list the different models, get their default version and all "read-only" actions but when I try to create a new version for a model, it does not work. I get a 403 Forbidden error with "Access to model denied".

I use a service account to make the calls. In IAM, my service account has the "ML Engine administrator" right.

This is how I make the call

from google.oauth2.service_account import Credentials

credentials = Credentials.from_service_account_file(PATH_TO_MY_JSON)
ml_client = discovery.build(u'ml', u'v1', credentials=credentials)

body = {
        u"name": version_name,
        u"description": description,
        u"runtimeVersion": current_default_version.get(u"runtimeVersion"),
        u"framework": current_default_version.get(u"framework"),
        u"pythonVersion": current_default_version.get(u"pythonVersion"),
        u"deploymentUri": deployment_uri
    }
request = ml_client.projects().models().versions().create(parent=get_query_name(model_name), body=body)
request.execute()

The error

 <HttpError 403 when requesting https://ml.googleapis.com/v1/projects/XXX/models/YYY/versions?alt=json returned "Access to model denied.">

it has to do with the service account because when I run this code in Cloud Shell and build my ml_client without credentials (ml_client = discovery.build(u'ml', u'v1')), it works fine.

1
Did you gcloud auth login and gcloud auth application-default login ? - sdcbr
not sure how this impacts the deployed version but anyway, no I did not - Valentin Coudert
It could be that the service account doesn't have permissions to read the bucket. Even when the account is a Cloud ML Admin the storage permissions are required to deploy/create a model since Cloud ML needs to read the training files that are stored in such bucket. Could you confirm if you have set the storage permissions as stated in the doc? - rsantiago

1 Answers

0
votes

My Service Account IAM Roles:

  • ML Engine Developer
  • Storage Object Viewer

For me, it appears that if I created a model resource via the UI, I could not create a model version from the python client library. However, if I created a model resource via the python client, then create a model version it worked.

credentials = Credentials.from_service_account_file('./service_account.json')
ml = discovery.build('ml', 'v1', credentials=credentials)
request_dict = {
   'name': 'model_resource_name',
   'description': 'your_model_description'}

project_id = 'projects/{}'.format('YOUR_PROJECT_ID')
request = ml.projects().models().create(parent=project_id, body=request_dict)
request.execute()

body = {
   u"name": "test_version",
   u"description": "description",
   u"runtimeVersion": "1.13",
   u"framework": "TENSORFLOW",
   u"pythonVersion": "3.5",
   u"deploymentUri": "gs://BUCKET_ID/directory_path_to_your_model/"
        }

request = ml.projects().models().versions().create(
    parent='projects/{}/models/{}'.format(
          'YOUR_PROJECT_ID', 
          'model_resource'), 
    body=body)

response = request.execute()

Still investigating why the model resource creation via the UI doesn't allow the python client to create a model version.