gapic-generator-python icon indicating copy to clipboard operation
gapic-generator-python copied to clipboard

Improve autogenerated code samples for `google.cloud.resourcemanager_v3`

Open avinashpancham opened this issue 2 years ago • 6 comments

Hi all,

Im running into issues when trying to create a tag on a regional resource (e.g. a project) with the following code based on the Resource manager docs:

from google.cloud.resourcemanager_v3 import TagBindingsClient
from google.cloud.resourcemanager_v3.types.tag_bindings import TagBinding

client = TagBindingsClient()

tag_binding = TagBinding(
        parent="cloudresourcemanager.googleapis.com/projects/PROJECTID",
        tag_value="tagValues/XXXX"
    )
    
operation = client.create_tag_binding(tag_binding=tag_binding)    

This results in the following error:

  File "/opt/hostedtoolcache/Python/3.10.13/x64/lib/python3.10/site-packages/google/cloud/resourcemanager_v3/services/tag_bindings/client.py", line 639, in create_tag_binding
    response = rpc(
  File "/opt/hostedtoolcache/Python/3.10.13/x64/lib/python3.10/site-packages/google/api_core/gapic_v1/method.py", line 113, in __call__
    return wrapped_func(*args, **kwargs)
  File "/opt/hostedtoolcache/Python/3.10.13/x64/lib/python3.10/site-packages/google/api_core/grpc_helpers.py", line 74, in error_remapped_callable
    raise exceptions.from_grpc_error(exc) from exc
google.api_core.exceptions.InvalidArgument: 400 Request contains an invalid argument. [field_violations {
  field: "binding.resource"
  description: "Must be a valid One Platform resource name of a tag-compatible global resource. Did you forget to specify the correct location?"
}
field_violations {
  field: "binding.resource"
  description: "Resource type not supported in location global"
}
]

I should thus specify the location, but there is no parameter to specify the location.

In the GCP docs I found that regional resources have another endpoint for tags and that's why the Python client is perhaps failing. https://LOCATION-cloudresourcemanager.googleapis.com/v3/tagBindings instead of https://cloudresourcemanager.googleapis.com/v3/tagBindings

avinashpancham avatar Nov 16 '23 17:11 avinashpancham

Hi @avinashpancham,

Since the docs that you linked mention using a regional endpoint, you'll need to set the api_endpoint argument of ClientOptions.

For example

    # Set the regional endpoint
    regional_endpoint = "<LOCATION>-cloudresourcemanager.googleapis.com"
    client_options = ClientOptions(api_endpoint=regional_endpoint)

    # Create a client with the specified regional endpoint
    client = TagBindingsClient(client_options=client_options)

Please let me know if this resolves the error.

If the issue is resolved, we should keep this issue open to track improving the automatically generated code snippets located at https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-resource-manager/samples/generated_samples

parthea avatar Nov 16 '23 17:11 parthea

Thanks @parthea. Providing the regional endpoint seems to solve the error. I now have another issue though, but that is unrelated to this issue.

    raise exceptions.from_grpc_error(exc) from exc
google.api_core.exceptions.InvalidArgument: 400 Request contains an invalid argument. [field_violations {
  field: "binding.resource"
  description: "Must be a valid One Platform resource name of a tag compatible regional resource"
}
field_violations {
  field: "binding.resource"
  description: "Resource type not supported in location europe-west4"
}
]

avinashpancham avatar Nov 16 '23 17:11 avinashpancham

But a wider question: isn't a project a global resource instead of a regional resource?

So I'm puzzled that we need to define a regional endpoint

avinashpancham avatar Nov 16 '23 18:11 avinashpancham

Regarding the need for a regional endpoint, see this comment from the docs If you are attaching the tag to a regional resource, such as a Compute Engine instance, use the tagBindings.create method with the regional endpoint where your resource is located..

Can you try the snippet below?

from google.cloud import resourcemanager_v3
from google.api_core.client_options import ClientOptions

def sample_create_tag_binding():
    # Set the regional endpoint
    regional_endpoint = "<zone>-cloudresourcemanager.googleapis.com"
    client_options = ClientOptions(api_endpoint=regional_endpoint)

    # Create a client with the specified regional endpoint
    client = resourcemanager_v3.TagBindingsClient(client_options=client_options)

    tag_binding = resourcemanager_v3.TagBinding()
    tag_binding.parent = "//compute.googleapis.com/projects/<proj ID>/zones/<zone>/instances/<instance number>"
    tag_binding.tag_value = "tagValues/<tag number>"

    # Initialize request argument(s)
    request = resourcemanager_v3.CreateTagBindingRequest(
        tag_binding=tag_binding
    )

    # Make the request
    operation = client.create_tag_binding(request=request)

    print("Waiting for operation to complete...")

    response = operation.result()

    # Handle the response
    print(response)

sample_create_tag_binding()

(Googlers see b/279143409)

parthea avatar Nov 16 '23 18:11 parthea

@parthea thank you for your response. In your previous message I actually found my error, the parent should start with two leading slashes ('//'). I did not do that.

Thanks for the help!

avinashpancham avatar Nov 16 '23 18:11 avinashpancham

I'm going to transfer this issue to gapic-generator-python, which is the repository that generates the sample code in https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-resource-manager/samples/generated_samples, so that we can improve the documentation.

parthea avatar Nov 16 '23 18:11 parthea