Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
bb05ef8
chore(bigtable): move bigtable samples into per-client directories
daniel-sanche Jul 21, 2026
a4eef19
renamed data_client to data_client_async
daniel-sanche Jul 21, 2026
1b91ad4
updated repo references
daniel-sanche Jul 21, 2026
9cad950
added _legacy suffix to legacy client region tags
daniel-sanche Jul 21, 2026
9e865b0
added sync data client samples
daniel-sanche Jul 21, 2026
2f816f1
updated CONTRIBUTING
daniel-sanche Jul 21, 2026
f07c66b
added samples targeting generated admin client
daniel-sanche Jul 21, 2026
91d87d2
deleted extra READMEs
daniel-sanche Jul 21, 2026
39b1339
updated headers
daniel-sanche Jul 21, 2026
4601622
remove sub readmes
daniel-sanche Jul 23, 2026
e0c3a47
Merge branch 'samples_1_reorganize_samples' into samples_2_add_sync_s…
daniel-sanche Jul 23, 2026
bb848b4
address gemini comments
daniel-sanche Aug 6, 2026
937077c
Merge branch 'main' into samples_2_add_sync_samples
daniel-sanche Aug 12, 2026
033e9f4
moved generated samples back
daniel-sanche Aug 12, 2026
0b43f15
reset librarian file
daniel-sanche Aug 12, 2026
00bc740
Merge branch 'main' into samples_2_add_sync_samples
daniel-sanche Oct 7, 2026
d835f0e
added imports into samples
daniel-sanche Oct 7, 2026
f5e5f99
add comments
daniel-sanche Oct 7, 2026
86811b3
data samples prefer gapic admin client
daniel-sanche Oct 7, 2026
b842e60
fix sample nox sessions
daniel-sanche Oct 7, 2026
6f13a52
fixed merge issue
daniel-sanche Oct 7, 2026
e6d467c
Merge branch 'main' into samples_2_add_sync_samples
daniel-sanche Oct 7, 2026
0193f8c
trigger samples tests from main noxfile
daniel-sanche Oct 7, 2026
0035d73
unpin bigtable version
daniel-sanche Oct 7, 2026
0012b23
fix sample tests
daniel-sanche Oct 7, 2026
0f4df5f
Merge branch 'samples_1_run_tests' into samples_2_add_sync_samples
daniel-sanche Oct 7, 2026
b4accd8
removed unneeded files
daniel-sanche Oct 7, 2026
e0f8849
completed migration of legacy client to data client samples
daniel-sanche Oct 8, 2026
7f0673a
Merge branch 'samples_1_run_tests' into samples_2_add_sync_samples
daniel-sanche Oct 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
#!/usr/bin/env python

# Copyright 2026 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Demonstrates how to run instance admin operations using BigtableInstanceAdminClient.

Prerequisites:
- Create a Cloud Bigtable project.
- Set your Google Application Default Credentials.
"""

import argparse


def run_instance_operations(project_id, instance_id, cluster_id):
# [START bigtable_check_instance_exists]
from google.api_core.exceptions import NotFound

from google.cloud import bigtable_admin

client = bigtable_admin.BigtableInstanceAdminClient()
instance_path = client.instance_path(project_id, instance_id)

try:
instance = client.get_instance(name=instance_path)
print(f"Instance {instance_id} already exists.")
except NotFound:
print(f"Instance {instance_id} does not exist.")
# [END bigtable_check_instance_exists]

# [START bigtable_create_prod_instance]
from google.api_core.exceptions import NotFound

from google.cloud import bigtable_admin

client = bigtable_admin.BigtableInstanceAdminClient()
project_path = client.common_project_path(project_id)
instance_path = client.instance_path(project_id, instance_id)

cluster = bigtable_admin.Cluster(
location=client.common_location_path(project_id, "us-central1-f"),
serve_nodes=1,
default_storage_type=bigtable_admin.StorageType.SSD,
)
instance_obj = bigtable_admin.Instance(
display_name=instance_id,
labels={"prod-label": "prod-label"},
type_=bigtable_admin.Instance.Type.PRODUCTION,
)

try:
client.get_instance(name=instance_path)
except NotFound:
print("\nCreating an instance")
# Create instance with given options
operation = client.create_instance(
parent=project_path,
instance_id=instance_id,
instance=instance_obj,
clusters={cluster_id: cluster},
)
# Ensure the operation completes.
operation.result(timeout=480)
print(f"\nCreated instance: {instance_id}")
# [END bigtable_create_prod_instance]

# [START bigtable_list_instances]
from google.cloud import bigtable_admin

client = bigtable_admin.BigtableInstanceAdminClient()
project_path = client.common_project_path(project_id)

print("\nListing instances:")
instances_response = client.list_instances(parent=project_path)
for instance in instances_response.instances:
print(instance.name.split("/")[-1])
# [END bigtable_list_instances]

# [START bigtable_get_instance]
from google.cloud import bigtable_admin

client = bigtable_admin.BigtableInstanceAdminClient()
instance_path = client.instance_path(project_id, instance_id)

inst = client.get_instance(name=instance_path)
print(f"\nName of instance: {inst.display_name}\nLabels: {dict(inst.labels)}")
# [END bigtable_get_instance]

# [START bigtable_get_clusters]
from google.cloud import bigtable_admin

client = bigtable_admin.BigtableInstanceAdminClient()
instance_path = client.instance_path(project_id, instance_id)

print("\nListing clusters...")
clusters_response = client.list_clusters(parent=instance_path)
for cluster in clusters_response.clusters:
print(cluster.name.split("/")[-1])
# [END bigtable_get_clusters]


def delete_instance(project_id, instance_id):
# [START bigtable_delete_instance]
from google.api_core.exceptions import NotFound

from google.cloud import bigtable_admin

client = bigtable_admin.BigtableInstanceAdminClient()
instance_path = client.instance_path(project_id, instance_id)

print("\nDeleting instance")
try:
client.delete_instance(name=instance_path)
print(f"Deleted instance: {instance_id}")
except NotFound:
print(f"Instance {instance_id} does not exist.")
# [END bigtable_delete_instance]


def add_cluster(project_id, instance_id, cluster_id):
# [START bigtable_create_cluster]
from google.api_core.exceptions import NotFound

from google.cloud import bigtable_admin

client = bigtable_admin.BigtableInstanceAdminClient()
instance_path = client.instance_path(project_id, instance_id)
cluster_path = client.cluster_path(project_id, instance_id, cluster_id)

print("\nListing clusters...")
clusters_response = client.list_clusters(parent=instance_path)
for cluster in clusters_response.clusters:
print(cluster.name.split("/")[-1])

new_cluster = bigtable_admin.Cluster(
location=client.common_location_path(project_id, "us-central1-a"),
serve_nodes=1,
default_storage_type=bigtable_admin.StorageType.SSD,
)
try:
client.get_cluster(name=cluster_path)
print(f"\nCluster not created, as {cluster_id} already exists.")
except NotFound:
operation = client.create_cluster(
parent=instance_path, cluster_id=cluster_id, cluster=new_cluster
)
# Ensure the operation completes.
operation.result(timeout=480)
print(f"\nCluster created: {cluster_id}")
# [END bigtable_create_cluster]


def delete_cluster(project_id, instance_id, cluster_id):
"""Delete the cluster

:type project_id: str
:param project_id: Project id of the client.

:type instance_id: str
:param instance_id: Instance of the client.

:type cluster_id: str
:param cluster_id: Cluster id.
"""
# [START bigtable_delete_cluster]
from google.api_core.exceptions import NotFound

from google.cloud import bigtable_admin

client = bigtable_admin.BigtableInstanceAdminClient()
cluster_path = client.cluster_path(project_id, instance_id, cluster_id)

print("\nDeleting cluster")
try:
client.delete_cluster(name=cluster_path)
print(f"Cluster deleted: {cluster_id}")
except NotFound:
print(f"\nCluster {cluster_id} does not exist.")
# [END bigtable_delete_cluster]


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument(
"command",
help="run, del-instance, add-cluster or del-cluster.",
)
parser.add_argument("project_id", help="Your Cloud Platform project ID.")
parser.add_argument("instance_id", help="ID of the Cloud Bigtable instance.")
parser.add_argument("cluster_id", help="ID of the Cloud Bigtable cluster.")

args = parser.parse_args()

if args.command.lower() == "run":
run_instance_operations(args.project_id, args.instance_id, args.cluster_id)
elif args.command.lower() == "del-instance":
delete_instance(args.project_id, args.instance_id)
elif args.command.lower() == "add-cluster":
add_cluster(args.project_id, args.instance_id, args.cluster_id)
elif args.command.lower() == "del-cluster":
delete_cluster(args.project_id, args.instance_id, args.cluster_id)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
google-cloud-bigtable
backoff==2.2.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2026 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import uuid

import backoff
from google.api_core import exceptions

from .instanceadmin import (
add_cluster,
delete_cluster,
delete_instance,
run_instance_operations,
)

PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"]
INSTANCE_ID = f"instance-admin-{str(uuid.uuid4())[:8]}"
CLUSTER_ID = f"cluster-admin-{str(uuid.uuid4())[:8]}"
NEW_CLUSTER_ID = f"cluster-add-{str(uuid.uuid4())[:8]}"


def test_instance_operations(capsys):
try:
run_instance_operations(PROJECT, INSTANCE_ID, CLUSTER_ID)
out, _ = capsys.readouterr()
assert f"Created instance: {INSTANCE_ID}" in out
assert "Listing instances:" in out
assert "Listing clusters..." in out

backoff_503 = backoff.on_exception(backoff.expo, exceptions.ServiceUnavailable)
backoff_503(add_cluster)(PROJECT, INSTANCE_ID, NEW_CLUSTER_ID)
out, _ = capsys.readouterr()
assert f"Cluster created: {NEW_CLUSTER_ID}" in out

delete_cluster(PROJECT, INSTANCE_ID, NEW_CLUSTER_ID)
out, _ = capsys.readouterr()
assert f"Cluster deleted: {NEW_CLUSTER_ID}" in out

delete_instance(PROJECT, INSTANCE_ID)
out, _ = capsys.readouterr()
assert f"Deleted instance: {INSTANCE_ID}" in out
finally:
delete_instance(PROJECT, INSTANCE_ID)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Loading
Loading