Many GCP products are now namespaced regionally, or have started adding regional namespaces. The methods to do this is generalized across products, but each product documents this in their own way and can be hard to discover. Cloud Build, for example, only mentions this in their reference docs.

Seems like a good topic to disambiguate. Let's dig in, fellow Pythonistas!

The first consideration here is which library you are using to interact with the API: google-api-python-client or google-cloud-python. The former is a generic library for interacting with Google APIs, while the latter are specialized libraries for specific GCP products.

There is a subtle difference between these libraries that can be a gotcha, as in it absolutely got me. When overriding the API endpoint, the google-api-python-client MUST provide a fully-qualified URL, otherwise known as an absolute URI. For the google-cloud-python, it MUST provide a non-qualified URL, otherwise known as a relative URI. Keep that in mind if you're moving between libraries, or trying to decipher the existing docs and apply that to the api_endpoint value.

Let's use Cloud Build in our example. Cloud Build can run in these locations. We'll use us-central1 as our region, and using the preferred google-cloud-python library for build.

import google.auth
from google.cloud.devtools import cloudbuild_v1
from google.api_core import client_options


REGION = 'us-central1'

credentials, project_id = google.auth.default()
endpoint = "{}-cloudbuild.googleapis.com"
client_options = client_options.ClientOptions(
    api_endpoint=endpoint.format(REGION)
)
client = cloudbuild_v1.services.cloud_build.CloudBuildClient(
    client_options=client_options
)
# any API call will be targeted to a regional endpoint and can interact with
# resources in that region.

With the google-api-python-client library, it would be structured like this.

import google.auth
from googleapiclient import discovery
from google.api_core import client_options


REGION = 'us-central1'

credentials, project_id = google.auth.default()
endpoint = 'https://{}-cloudbuild.googleapis.com'
client_options = client_options.ClientOptions(
    api_endpoint=endpoint.format(REGION)
)
service =  discovery.build('cloudbuild', 'v1', client_options=client_options)
parent = 'projects/{}/locations/{}'
triggers = service.projects().locations().triggers().list(
    parent=parent.format(project_id, REGION)
).execute()

And there we go! Both libraries making the same API calls, with results, with subtle differences to get there.